UNPKG

444 kBJavaScriptView Raw
1/**
2 * Modules in this bundle
3 * @license
4 *
5 * power-assert:
6 * license: MIT
7 * author: Takuto Wada <takuto.wada@gmail.com>
8 * contributors: azu, vvakame, yosuke-furukawa, teppeis, zoncoen
9 * homepage: http://github.com/power-assert-js/power-assert
10 * version: 1.0.1
11 *
12 * array-filter:
13 * license: MIT
14 * author: Julian Gruber <mail@juliangruber.com>
15 * maintainers: juliangruber <julian@juliangruber.com>
16 * homepage: https://github.com/juliangruber/array-filter
17 * version: 1.0.0
18 *
19 * array-foreach:
20 * license: MIT
21 * author: Takuto Wada <takuto.wada@gmail.com>
22 * homepage: https://github.com/twada/array-foreach
23 * version: 1.0.1
24 *
25 * array-map:
26 * license: MIT
27 * author: James Halliday <mail@substack.net>
28 * maintainers: substack <mail@substack.net>
29 * homepage: https://github.com/substack/array-map
30 * version: 0.0.0
31 *
32 * array-reduce:
33 * license: MIT
34 * author: James Halliday <mail@substack.net>
35 * maintainers: substack <mail@substack.net>
36 * homepage: https://github.com/substack/array-reduce
37 * version: 0.0.0
38 *
39 * array-reduce-right:
40 * license: MIT
41 * author: Takuto Wada <takuto.wada@gmail.com>
42 * homepage: https://github.com/twada/array-reduce-right
43 * version: 1.0.0
44 *
45 * array-some:
46 * license: MIT
47 * author: Takuto Wada <takuto.wada@gmail.com>
48 * homepage: https://github.com/twada/array-some
49 * version: 1.0.0
50 *
51 * assert:
52 * license: MIT
53 * maintainers: coolaj86 <coolaj86@gmail.com>, shtylman <shtylman@gmail.com>
54 * homepage: https://github.com/defunctzombie/commonjs-assert
55 * version: 1.3.0
56 *
57 * deep-equal:
58 * license: MIT
59 * author: James Halliday <mail@substack.net>
60 * maintainers: substack <mail@substack.net>
61 * homepage: https://github.com/substack/node-deep-equal#readme
62 * version: 1.0.1
63 *
64 * eastasianwidth:
65 * license: MIT
66 * author: Masaki Komagata
67 * maintainers: komagata <komagata@gmail.com>
68 * homepage: https://github.com/komagata/eastasianwidth
69 * version: 0.1.0
70 *
71 * empower:
72 * license: MIT
73 * author: Takuto Wada <takuto.wada@gmail.com>
74 * homepage: http://github.com/power-assert-js/empower
75 * version: 1.0.1
76 *
77 * escallmatch:
78 * license: MIT
79 * author: Takuto Wada <takuto.wada@gmail.com>
80 * homepage: https://github.com/twada/escallmatch
81 * version: 1.4.2
82 *
83 * esprima:
84 * license: BSD-2-Clause
85 * author: Ariya Hidayat <ariya.hidayat@gmail.com>
86 * maintainers: ariya <ariya.hidayat@gmail.com>
87 * homepage: http://esprima.org
88 * version: 2.6.0
89 *
90 * espurify:
91 * license: MIT
92 * author: Takuto Wada <takuto.wada@gmail.com>
93 * homepage: https://github.com/estools/espurify
94 * version: 1.3.0
95 *
96 * estraverse:
97 * licenses: BSD
98 * maintainers: constellation <utatane.tea@gmail.com>, michaelficarra <npm@michael.ficarra.me>
99 * homepage: https://github.com/estools/estraverse
100 * version: 4.1.0
101 *
102 * events:
103 * author: Irakli Gozalishvili <rfobic@gmail.com>
104 * maintainers: gozala <rfobic@gmail.com>, shtylman <shtylman@gmail.com>
105 * homepage: https://github.com/Gozala/events
106 * version: 1.0.2
107 *
108 * function-bind:
109 * licenses: MIT
110 * author: Raynos <raynos2@gmail.com>
111 * maintainers: raynos <raynos2@gmail.com>
112 * contributors: Raynos
113 * homepage: https://github.com/Raynos/function-bind
114 * version: 0.1.0
115 *
116 * googlediff:
117 * licenses: Apache
118 * author: Neil Fraser <root@neil.fraser.name>
119 * maintainers: shimondoodkin <helpmepro1@gmail.com>
120 * contributors: Shimon Doodkin <helpmepro1@gmail.com>, Ryan Graham <r.m.graham@gmail.com>
121 * homepage: http://code.google.com/p/google-diff-match-patch/
122 * version: 0.1.0
123 *
124 * has:
125 * licenses: MIT
126 * author: Thiago de Arruda <tpadilha84@gmail.com>
127 * maintainers: tarruda <tpadilha84@gmail.com>
128 * homepage: https://github.com/tarruda/has
129 * version: 0.0.1
130 *
131 * indexof:
132 * maintainers: tjholowaychuk <tj@vision-media.ca>
133 * version: 0.0.1
134 *
135 * inherits:
136 * license: ISC
137 * homepage: https://github.com/isaacs/inherits
138 * version: 2.0.1
139 *
140 * isarray:
141 * license: MIT
142 * author: Julian Gruber <mail@juliangruber.com>
143 * maintainers: juliangruber <julian@juliangruber.com>
144 * homepage: https://github.com/juliangruber/isarray
145 * version: 0.0.1
146 *
147 * object-create:
148 * licenses: MIT
149 * author: Thiago de Arruda <tpadilha84@gmail.com>
150 * maintainers: tarruda <tpadilha84@gmail.com>
151 * homepage: https://github.com/tarruda/object-create
152 * version: 0.1.0
153 *
154 * object-define-property:
155 * licenses: MIT
156 * author: Thiago de Arruda <tpadilha84@gmail.com>
157 * maintainers: tarruda <tpadilha84@gmail.com>
158 * homepage: https://github.com/tarruda/object-define-property
159 * version: 0.1.0
160 *
161 * object-keys:
162 * license: MIT
163 * author: Jordan Harband
164 * maintainers: ljharb <ljharb@gmail.com>
165 * homepage: https://github.com/ljharb/object-keys#readme
166 * version: 1.0.7
167 *
168 * power-assert-formatter:
169 * license: MIT
170 * author: Takuto Wada <takuto.wada@gmail.com>
171 * homepage: http://github.com/power-assert-js/power-assert-formatter
172 * version: 1.1.0
173 *
174 * process:
175 * author: Roman Shtylman <shtylman@gmail.com>
176 * maintainers: coolaj86 <coolaj86@gmail.com>, defunctzombie <shtylman@gmail.com>
177 * homepage: https://github.com/shtylman/node-process#readme
178 * version: 0.11.1
179 *
180 * stringifier:
181 * license: MIT
182 * author: Takuto Wada <takuto.wada@gmail.com>
183 * homepage: https://github.com/twada/stringifier
184 * version: 1.2.0
185 *
186 * traverse:
187 * license: MIT
188 * author: James Halliday <mail@substack.net>
189 * maintainers: substack <mail@substack.net>
190 * homepage: https://github.com/substack/js-traverse
191 * version: 0.6.6
192 *
193 * type-name:
194 * license: MIT
195 * author: Takuto Wada <takuto.wada@gmail.com>
196 * maintainers: twada <takuto.wada@gmail.com>
197 * contributors: azu, Yosuke Furukawa
198 * homepage: https://github.com/twada/type-name
199 * version: 1.0.1
200 *
201 * util:
202 * license: MIT
203 * author: Joyent
204 * maintainers: shtylman <shtylman@gmail.com>
205 * homepage: https://github.com/defunctzombie/node-util
206 * version: 0.10.3
207 *
208 * xtend:
209 * licenses: MIT
210 * author: Raynos <raynos2@gmail.com>
211 * contributors: Jake Verbaten, Matt Esch
212 * homepage: https://github.com/Raynos/xtend
213 * version: 4.0.0
214 *
215 * This header is generated by licensify (https://github.com/twada/licensify)
216 */
217(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.assert = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw (f.code="MODULE_NOT_FOUND", f)}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){
218/**
219 * power-assert.js - Power Assert in JavaScript.
220 *
221 * https://github.com/power-assert-js/power-assert
222 *
223 * Copyright (c) 2013-2015 Takuto Wada
224 * Licensed under the MIT license.
225 * https://github.com/power-assert-js/power-assert/blob/master/MIT-LICENSE.txt
226 */
227'use strict';
228
229var baseAssert = _dereq_('assert');
230var empower = _dereq_('empower');
231var formatter = _dereq_('power-assert-formatter');
232var extend = _dereq_('xtend');
233var empowerOptions = {
234 modifyMessageOnRethrow: true,
235 saveContextOnRethrow: true
236};
237
238function customize (customOptions) {
239 var options = customOptions || {};
240 var poweredAssert = empower(
241 baseAssert,
242 formatter(options.output),
243 extend(empowerOptions, options.assertion)
244 );
245 poweredAssert.customize = customize;
246 return poweredAssert;
247}
248
249module.exports = customize();
250
251},{"assert":2,"empower":12,"power-assert-formatter":39,"xtend":60}],2:[function(_dereq_,module,exports){
252// http://wiki.commonjs.org/wiki/Unit_Testing/1.0
253//
254// THIS IS NOT TESTED NOR LIKELY TO WORK OUTSIDE V8!
255//
256// Originally from narwhal.js (http://narwhaljs.org)
257// Copyright (c) 2009 Thomas Robinson <280north.com>
258//
259// Permission is hereby granted, free of charge, to any person obtaining a copy
260// of this software and associated documentation files (the 'Software'), to
261// deal in the Software without restriction, including without limitation the
262// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
263// sell copies of the Software, and to permit persons to whom the Software is
264// furnished to do so, subject to the following conditions:
265//
266// The above copyright notice and this permission notice shall be included in
267// all copies or substantial portions of the Software.
268//
269// THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
270// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
271// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
272// AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
273// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
274// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
275
276// when used in node, this will actually load the util module we depend on
277// versus loading the builtin util module as happens otherwise
278// this is a bug in node module loading as far as I am concerned
279var util = _dereq_('util/');
280
281var pSlice = Array.prototype.slice;
282var hasOwn = Object.prototype.hasOwnProperty;
283
284// 1. The assert module provides functions that throw
285// AssertionError's when particular conditions are not met. The
286// assert module must conform to the following interface.
287
288var assert = module.exports = ok;
289
290// 2. The AssertionError is defined in assert.
291// new assert.AssertionError({ message: message,
292// actual: actual,
293// expected: expected })
294
295assert.AssertionError = function AssertionError(options) {
296 this.name = 'AssertionError';
297 this.actual = options.actual;
298 this.expected = options.expected;
299 this.operator = options.operator;
300 if (options.message) {
301 this.message = options.message;
302 this.generatedMessage = false;
303 } else {
304 this.message = getMessage(this);
305 this.generatedMessage = true;
306 }
307 var stackStartFunction = options.stackStartFunction || fail;
308
309 if (Error.captureStackTrace) {
310 Error.captureStackTrace(this, stackStartFunction);
311 }
312 else {
313 // non v8 browsers so we can have a stacktrace
314 var err = new Error();
315 if (err.stack) {
316 var out = err.stack;
317
318 // try to strip useless frames
319 var fn_name = stackStartFunction.name;
320 var idx = out.indexOf('\n' + fn_name);
321 if (idx >= 0) {
322 // once we have located the function frame
323 // we need to strip out everything before it (and its line)
324 var next_line = out.indexOf('\n', idx + 1);
325 out = out.substring(next_line + 1);
326 }
327
328 this.stack = out;
329 }
330 }
331};
332
333// assert.AssertionError instanceof Error
334util.inherits(assert.AssertionError, Error);
335
336function replacer(key, value) {
337 if (util.isUndefined(value)) {
338 return '' + value;
339 }
340 if (util.isNumber(value) && !isFinite(value)) {
341 return value.toString();
342 }
343 if (util.isFunction(value) || util.isRegExp(value)) {
344 return value.toString();
345 }
346 return value;
347}
348
349function truncate(s, n) {
350 if (util.isString(s)) {
351 return s.length < n ? s : s.slice(0, n);
352 } else {
353 return s;
354 }
355}
356
357function getMessage(self) {
358 return truncate(JSON.stringify(self.actual, replacer), 128) + ' ' +
359 self.operator + ' ' +
360 truncate(JSON.stringify(self.expected, replacer), 128);
361}
362
363// At present only the three keys mentioned above are used and
364// understood by the spec. Implementations or sub modules can pass
365// other keys to the AssertionError's constructor - they will be
366// ignored.
367
368// 3. All of the following functions must throw an AssertionError
369// when a corresponding condition is not met, with a message that
370// may be undefined if not provided. All assertion methods provide
371// both the actual and expected values to the assertion error for
372// display purposes.
373
374function fail(actual, expected, message, operator, stackStartFunction) {
375 throw new assert.AssertionError({
376 message: message,
377 actual: actual,
378 expected: expected,
379 operator: operator,
380 stackStartFunction: stackStartFunction
381 });
382}
383
384// EXTENSION! allows for well behaved errors defined elsewhere.
385assert.fail = fail;
386
387// 4. Pure assertion tests whether a value is truthy, as determined
388// by !!guard.
389// assert.ok(guard, message_opt);
390// This statement is equivalent to assert.equal(true, !!guard,
391// message_opt);. To test strictly for the value true, use
392// assert.strictEqual(true, guard, message_opt);.
393
394function ok(value, message) {
395 if (!value) fail(value, true, message, '==', assert.ok);
396}
397assert.ok = ok;
398
399// 5. The equality assertion tests shallow, coercive equality with
400// ==.
401// assert.equal(actual, expected, message_opt);
402
403assert.equal = function equal(actual, expected, message) {
404 if (actual != expected) fail(actual, expected, message, '==', assert.equal);
405};
406
407// 6. The non-equality assertion tests for whether two objects are not equal
408// with != assert.notEqual(actual, expected, message_opt);
409
410assert.notEqual = function notEqual(actual, expected, message) {
411 if (actual == expected) {
412 fail(actual, expected, message, '!=', assert.notEqual);
413 }
414};
415
416// 7. The equivalence assertion tests a deep equality relation.
417// assert.deepEqual(actual, expected, message_opt);
418
419assert.deepEqual = function deepEqual(actual, expected, message) {
420 if (!_deepEqual(actual, expected)) {
421 fail(actual, expected, message, 'deepEqual', assert.deepEqual);
422 }
423};
424
425function _deepEqual(actual, expected) {
426 // 7.1. All identical values are equivalent, as determined by ===.
427 if (actual === expected) {
428 return true;
429
430 } else if (util.isBuffer(actual) && util.isBuffer(expected)) {
431 if (actual.length != expected.length) return false;
432
433 for (var i = 0; i < actual.length; i++) {
434 if (actual[i] !== expected[i]) return false;
435 }
436
437 return true;
438
439 // 7.2. If the expected value is a Date object, the actual value is
440 // equivalent if it is also a Date object that refers to the same time.
441 } else if (util.isDate(actual) && util.isDate(expected)) {
442 return actual.getTime() === expected.getTime();
443
444 // 7.3 If the expected value is a RegExp object, the actual value is
445 // equivalent if it is also a RegExp object with the same source and
446 // properties (`global`, `multiline`, `lastIndex`, `ignoreCase`).
447 } else if (util.isRegExp(actual) && util.isRegExp(expected)) {
448 return actual.source === expected.source &&
449 actual.global === expected.global &&
450 actual.multiline === expected.multiline &&
451 actual.lastIndex === expected.lastIndex &&
452 actual.ignoreCase === expected.ignoreCase;
453
454 // 7.4. Other pairs that do not both pass typeof value == 'object',
455 // equivalence is determined by ==.
456 } else if (!util.isObject(actual) && !util.isObject(expected)) {
457 return actual == expected;
458
459 // 7.5 For all other Object pairs, including Array objects, equivalence is
460 // determined by having the same number of owned properties (as verified
461 // with Object.prototype.hasOwnProperty.call), the same set of keys
462 // (although not necessarily the same order), equivalent values for every
463 // corresponding key, and an identical 'prototype' property. Note: this
464 // accounts for both named and indexed properties on Arrays.
465 } else {
466 return objEquiv(actual, expected);
467 }
468}
469
470function isArguments(object) {
471 return Object.prototype.toString.call(object) == '[object Arguments]';
472}
473
474function objEquiv(a, b) {
475 if (util.isNullOrUndefined(a) || util.isNullOrUndefined(b))
476 return false;
477 // an identical 'prototype' property.
478 if (a.prototype !== b.prototype) return false;
479 // if one is a primitive, the other must be same
480 if (util.isPrimitive(a) || util.isPrimitive(b)) {
481 return a === b;
482 }
483 var aIsArgs = isArguments(a),
484 bIsArgs = isArguments(b);
485 if ((aIsArgs && !bIsArgs) || (!aIsArgs && bIsArgs))
486 return false;
487 if (aIsArgs) {
488 a = pSlice.call(a);
489 b = pSlice.call(b);
490 return _deepEqual(a, b);
491 }
492 var ka = objectKeys(a),
493 kb = objectKeys(b),
494 key, i;
495 // having the same number of owned properties (keys incorporates
496 // hasOwnProperty)
497 if (ka.length != kb.length)
498 return false;
499 //the same set of keys (although not necessarily the same order),
500 ka.sort();
501 kb.sort();
502 //~~~cheap key test
503 for (i = ka.length - 1; i >= 0; i--) {
504 if (ka[i] != kb[i])
505 return false;
506 }
507 //equivalent values for every corresponding key, and
508 //~~~possibly expensive deep test
509 for (i = ka.length - 1; i >= 0; i--) {
510 key = ka[i];
511 if (!_deepEqual(a[key], b[key])) return false;
512 }
513 return true;
514}
515
516// 8. The non-equivalence assertion tests for any deep inequality.
517// assert.notDeepEqual(actual, expected, message_opt);
518
519assert.notDeepEqual = function notDeepEqual(actual, expected, message) {
520 if (_deepEqual(actual, expected)) {
521 fail(actual, expected, message, 'notDeepEqual', assert.notDeepEqual);
522 }
523};
524
525// 9. The strict equality assertion tests strict equality, as determined by ===.
526// assert.strictEqual(actual, expected, message_opt);
527
528assert.strictEqual = function strictEqual(actual, expected, message) {
529 if (actual !== expected) {
530 fail(actual, expected, message, '===', assert.strictEqual);
531 }
532};
533
534// 10. The strict non-equality assertion tests for strict inequality, as
535// determined by !==. assert.notStrictEqual(actual, expected, message_opt);
536
537assert.notStrictEqual = function notStrictEqual(actual, expected, message) {
538 if (actual === expected) {
539 fail(actual, expected, message, '!==', assert.notStrictEqual);
540 }
541};
542
543function expectedException(actual, expected) {
544 if (!actual || !expected) {
545 return false;
546 }
547
548 if (Object.prototype.toString.call(expected) == '[object RegExp]') {
549 return expected.test(actual);
550 } else if (actual instanceof expected) {
551 return true;
552 } else if (expected.call({}, actual) === true) {
553 return true;
554 }
555
556 return false;
557}
558
559function _throws(shouldThrow, block, expected, message) {
560 var actual;
561
562 if (util.isString(expected)) {
563 message = expected;
564 expected = null;
565 }
566
567 try {
568 block();
569 } catch (e) {
570 actual = e;
571 }
572
573 message = (expected && expected.name ? ' (' + expected.name + ').' : '.') +
574 (message ? ' ' + message : '.');
575
576 if (shouldThrow && !actual) {
577 fail(actual, expected, 'Missing expected exception' + message);
578 }
579
580 if (!shouldThrow && expectedException(actual, expected)) {
581 fail(actual, expected, 'Got unwanted exception' + message);
582 }
583
584 if ((shouldThrow && actual && expected &&
585 !expectedException(actual, expected)) || (!shouldThrow && actual)) {
586 throw actual;
587 }
588}
589
590// 11. Expected to throw an error:
591// assert.throws(block, Error_opt, message_opt);
592
593assert["throws"] = function(block, /*optional*/error, /*optional*/message) {
594 _throws.apply(this, [true].concat(pSlice.call(arguments)));
595};
596
597// EXTENSION! This is annoying to write outside this module.
598assert.doesNotThrow = function(block, /*optional*/message) {
599 _throws.apply(this, [false].concat(pSlice.call(arguments)));
600};
601
602assert.ifError = function(err) { if (err) {throw err;}};
603
604var objectKeys = Object.keys || function (obj) {
605 var keys = [];
606 for (var key in obj) {
607 if (hasOwn.call(obj, key)) keys.push(key);
608 }
609 return keys;
610};
611
612},{"util/":7}],3:[function(_dereq_,module,exports){
613// Copyright Joyent, Inc. and other Node contributors.
614//
615// Permission is hereby granted, free of charge, to any person obtaining a
616// copy of this software and associated documentation files (the
617// "Software"), to deal in the Software without restriction, including
618// without limitation the rights to use, copy, modify, merge, publish,
619// distribute, sublicense, and/or sell copies of the Software, and to permit
620// persons to whom the Software is furnished to do so, subject to the
621// following conditions:
622//
623// The above copyright notice and this permission notice shall be included
624// in all copies or substantial portions of the Software.
625//
626// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
627// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
628// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
629// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
630// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
631// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
632// USE OR OTHER DEALINGS IN THE SOFTWARE.
633
634function EventEmitter() {
635 this._events = this._events || {};
636 this._maxListeners = this._maxListeners || undefined;
637}
638module.exports = EventEmitter;
639
640// Backwards-compat with node 0.10.x
641EventEmitter.EventEmitter = EventEmitter;
642
643EventEmitter.prototype._events = undefined;
644EventEmitter.prototype._maxListeners = undefined;
645
646// By default EventEmitters will print a warning if more than 10 listeners are
647// added to it. This is a useful default which helps finding memory leaks.
648EventEmitter.defaultMaxListeners = 10;
649
650// Obviously not all Emitters should be limited to 10. This function allows
651// that to be increased. Set to zero for unlimited.
652EventEmitter.prototype.setMaxListeners = function(n) {
653 if (!isNumber(n) || n < 0 || isNaN(n))
654 throw TypeError('n must be a positive number');
655 this._maxListeners = n;
656 return this;
657};
658
659EventEmitter.prototype.emit = function(type) {
660 var er, handler, len, args, i, listeners;
661
662 if (!this._events)
663 this._events = {};
664
665 // If there is no 'error' event listener then throw.
666 if (type === 'error') {
667 if (!this._events.error ||
668 (isObject(this._events.error) && !this._events.error.length)) {
669 er = arguments[1];
670 if (er instanceof Error) {
671 throw er; // Unhandled 'error' event
672 }
673 throw TypeError('Uncaught, unspecified "error" event.');
674 }
675 }
676
677 handler = this._events[type];
678
679 if (isUndefined(handler))
680 return false;
681
682 if (isFunction(handler)) {
683 switch (arguments.length) {
684 // fast cases
685 case 1:
686 handler.call(this);
687 break;
688 case 2:
689 handler.call(this, arguments[1]);
690 break;
691 case 3:
692 handler.call(this, arguments[1], arguments[2]);
693 break;
694 // slower
695 default:
696 len = arguments.length;
697 args = new Array(len - 1);
698 for (i = 1; i < len; i++)
699 args[i - 1] = arguments[i];
700 handler.apply(this, args);
701 }
702 } else if (isObject(handler)) {
703 len = arguments.length;
704 args = new Array(len - 1);
705 for (i = 1; i < len; i++)
706 args[i - 1] = arguments[i];
707
708 listeners = handler.slice();
709 len = listeners.length;
710 for (i = 0; i < len; i++)
711 listeners[i].apply(this, args);
712 }
713
714 return true;
715};
716
717EventEmitter.prototype.addListener = function(type, listener) {
718 var m;
719
720 if (!isFunction(listener))
721 throw TypeError('listener must be a function');
722
723 if (!this._events)
724 this._events = {};
725
726 // To avoid recursion in the case that type === "newListener"! Before
727 // adding it to the listeners, first emit "newListener".
728 if (this._events.newListener)
729 this.emit('newListener', type,
730 isFunction(listener.listener) ?
731 listener.listener : listener);
732
733 if (!this._events[type])
734 // Optimize the case of one listener. Don't need the extra array object.
735 this._events[type] = listener;
736 else if (isObject(this._events[type]))
737 // If we've already got an array, just append.
738 this._events[type].push(listener);
739 else
740 // Adding the second element, need to change to array.
741 this._events[type] = [this._events[type], listener];
742
743 // Check for listener leak
744 if (isObject(this._events[type]) && !this._events[type].warned) {
745 var m;
746 if (!isUndefined(this._maxListeners)) {
747 m = this._maxListeners;
748 } else {
749 m = EventEmitter.defaultMaxListeners;
750 }
751
752 if (m && m > 0 && this._events[type].length > m) {
753 this._events[type].warned = true;
754 console.error('(node) warning: possible EventEmitter memory ' +
755 'leak detected. %d listeners added. ' +
756 'Use emitter.setMaxListeners() to increase limit.',
757 this._events[type].length);
758 if (typeof console.trace === 'function') {
759 // not supported in IE 10
760 console.trace();
761 }
762 }
763 }
764
765 return this;
766};
767
768EventEmitter.prototype.on = EventEmitter.prototype.addListener;
769
770EventEmitter.prototype.once = function(type, listener) {
771 if (!isFunction(listener))
772 throw TypeError('listener must be a function');
773
774 var fired = false;
775
776 function g() {
777 this.removeListener(type, g);
778
779 if (!fired) {
780 fired = true;
781 listener.apply(this, arguments);
782 }
783 }
784
785 g.listener = listener;
786 this.on(type, g);
787
788 return this;
789};
790
791// emits a 'removeListener' event iff the listener was removed
792EventEmitter.prototype.removeListener = function(type, listener) {
793 var list, position, length, i;
794
795 if (!isFunction(listener))
796 throw TypeError('listener must be a function');
797
798 if (!this._events || !this._events[type])
799 return this;
800
801 list = this._events[type];
802 length = list.length;
803 position = -1;
804
805 if (list === listener ||
806 (isFunction(list.listener) && list.listener === listener)) {
807 delete this._events[type];
808 if (this._events.removeListener)
809 this.emit('removeListener', type, listener);
810
811 } else if (isObject(list)) {
812 for (i = length; i-- > 0;) {
813 if (list[i] === listener ||
814 (list[i].listener && list[i].listener === listener)) {
815 position = i;
816 break;
817 }
818 }
819
820 if (position < 0)
821 return this;
822
823 if (list.length === 1) {
824 list.length = 0;
825 delete this._events[type];
826 } else {
827 list.splice(position, 1);
828 }
829
830 if (this._events.removeListener)
831 this.emit('removeListener', type, listener);
832 }
833
834 return this;
835};
836
837EventEmitter.prototype.removeAllListeners = function(type) {
838 var key, listeners;
839
840 if (!this._events)
841 return this;
842
843 // not listening for removeListener, no need to emit
844 if (!this._events.removeListener) {
845 if (arguments.length === 0)
846 this._events = {};
847 else if (this._events[type])
848 delete this._events[type];
849 return this;
850 }
851
852 // emit removeListener for all listeners on all events
853 if (arguments.length === 0) {
854 for (key in this._events) {
855 if (key === 'removeListener') continue;
856 this.removeAllListeners(key);
857 }
858 this.removeAllListeners('removeListener');
859 this._events = {};
860 return this;
861 }
862
863 listeners = this._events[type];
864
865 if (isFunction(listeners)) {
866 this.removeListener(type, listeners);
867 } else {
868 // LIFO order
869 while (listeners.length)
870 this.removeListener(type, listeners[listeners.length - 1]);
871 }
872 delete this._events[type];
873
874 return this;
875};
876
877EventEmitter.prototype.listeners = function(type) {
878 var ret;
879 if (!this._events || !this._events[type])
880 ret = [];
881 else if (isFunction(this._events[type]))
882 ret = [this._events[type]];
883 else
884 ret = this._events[type].slice();
885 return ret;
886};
887
888EventEmitter.listenerCount = function(emitter, type) {
889 var ret;
890 if (!emitter._events || !emitter._events[type])
891 ret = 0;
892 else if (isFunction(emitter._events[type]))
893 ret = 1;
894 else
895 ret = emitter._events[type].length;
896 return ret;
897};
898
899function isFunction(arg) {
900 return typeof arg === 'function';
901}
902
903function isNumber(arg) {
904 return typeof arg === 'number';
905}
906
907function isObject(arg) {
908 return typeof arg === 'object' && arg !== null;
909}
910
911function isUndefined(arg) {
912 return arg === void 0;
913}
914
915},{}],4:[function(_dereq_,module,exports){
916if (typeof Object.create === 'function') {
917 // implementation from standard node.js 'util' module
918 module.exports = function inherits(ctor, superCtor) {
919 ctor.super_ = superCtor
920 ctor.prototype = Object.create(superCtor.prototype, {
921 constructor: {
922 value: ctor,
923 enumerable: false,
924 writable: true,
925 configurable: true
926 }
927 });
928 };
929} else {
930 // old school shim for old browsers
931 module.exports = function inherits(ctor, superCtor) {
932 ctor.super_ = superCtor
933 var TempCtor = function () {}
934 TempCtor.prototype = superCtor.prototype
935 ctor.prototype = new TempCtor()
936 ctor.prototype.constructor = ctor
937 }
938}
939
940},{}],5:[function(_dereq_,module,exports){
941// shim for using process in browser
942
943var process = module.exports = {};
944var queue = [];
945var draining = false;
946var currentQueue;
947var queueIndex = -1;
948
949function cleanUpNextTick() {
950 draining = false;
951 if (currentQueue.length) {
952 queue = currentQueue.concat(queue);
953 } else {
954 queueIndex = -1;
955 }
956 if (queue.length) {
957 drainQueue();
958 }
959}
960
961function drainQueue() {
962 if (draining) {
963 return;
964 }
965 var timeout = setTimeout(cleanUpNextTick);
966 draining = true;
967
968 var len = queue.length;
969 while(len) {
970 currentQueue = queue;
971 queue = [];
972 while (++queueIndex < len) {
973 currentQueue[queueIndex].run();
974 }
975 queueIndex = -1;
976 len = queue.length;
977 }
978 currentQueue = null;
979 draining = false;
980 clearTimeout(timeout);
981}
982
983process.nextTick = function (fun) {
984 var args = new Array(arguments.length - 1);
985 if (arguments.length > 1) {
986 for (var i = 1; i < arguments.length; i++) {
987 args[i - 1] = arguments[i];
988 }
989 }
990 queue.push(new Item(fun, args));
991 if (queue.length === 1 && !draining) {
992 setTimeout(drainQueue, 0);
993 }
994};
995
996// v8 likes predictible objects
997function Item(fun, array) {
998 this.fun = fun;
999 this.array = array;
1000}
1001Item.prototype.run = function () {
1002 this.fun.apply(null, this.array);
1003};
1004process.title = 'browser';
1005process.browser = true;
1006process.env = {};
1007process.argv = [];
1008process.version = ''; // empty string to avoid regexp issues
1009process.versions = {};
1010
1011function noop() {}
1012
1013process.on = noop;
1014process.addListener = noop;
1015process.once = noop;
1016process.off = noop;
1017process.removeListener = noop;
1018process.removeAllListeners = noop;
1019process.emit = noop;
1020
1021process.binding = function (name) {
1022 throw new Error('process.binding is not supported');
1023};
1024
1025// TODO(shtylman)
1026process.cwd = function () { return '/' };
1027process.chdir = function (dir) {
1028 throw new Error('process.chdir is not supported');
1029};
1030process.umask = function() { return 0; };
1031
1032},{}],6:[function(_dereq_,module,exports){
1033module.exports = function isBuffer(arg) {
1034 return arg && typeof arg === 'object'
1035 && typeof arg.copy === 'function'
1036 && typeof arg.fill === 'function'
1037 && typeof arg.readUInt8 === 'function';
1038}
1039},{}],7:[function(_dereq_,module,exports){
1040(function (process,global){
1041// Copyright Joyent, Inc. and other Node contributors.
1042//
1043// Permission is hereby granted, free of charge, to any person obtaining a
1044// copy of this software and associated documentation files (the
1045// "Software"), to deal in the Software without restriction, including
1046// without limitation the rights to use, copy, modify, merge, publish,
1047// distribute, sublicense, and/or sell copies of the Software, and to permit
1048// persons to whom the Software is furnished to do so, subject to the
1049// following conditions:
1050//
1051// The above copyright notice and this permission notice shall be included
1052// in all copies or substantial portions of the Software.
1053//
1054// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
1055// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
1056// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
1057// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
1058// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
1059// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
1060// USE OR OTHER DEALINGS IN THE SOFTWARE.
1061
1062var formatRegExp = /%[sdj%]/g;
1063exports.format = function(f) {
1064 if (!isString(f)) {
1065 var objects = [];
1066 for (var i = 0; i < arguments.length; i++) {
1067 objects.push(inspect(arguments[i]));
1068 }
1069 return objects.join(' ');
1070 }
1071
1072 var i = 1;
1073 var args = arguments;
1074 var len = args.length;
1075 var str = String(f).replace(formatRegExp, function(x) {
1076 if (x === '%') return '%';
1077 if (i >= len) return x;
1078 switch (x) {
1079 case '%s': return String(args[i++]);
1080 case '%d': return Number(args[i++]);
1081 case '%j':
1082 try {
1083 return JSON.stringify(args[i++]);
1084 } catch (_) {
1085 return '[Circular]';
1086 }
1087 default:
1088 return x;
1089 }
1090 });
1091 for (var x = args[i]; i < len; x = args[++i]) {
1092 if (isNull(x) || !isObject(x)) {
1093 str += ' ' + x;
1094 } else {
1095 str += ' ' + inspect(x);
1096 }
1097 }
1098 return str;
1099};
1100
1101
1102// Mark that a method should not be used.
1103// Returns a modified function which warns once by default.
1104// If --no-deprecation is set, then it is a no-op.
1105exports.deprecate = function(fn, msg) {
1106 // Allow for deprecating things in the process of starting up.
1107 if (isUndefined(global.process)) {
1108 return function() {
1109 return exports.deprecate(fn, msg).apply(this, arguments);
1110 };
1111 }
1112
1113 if (process.noDeprecation === true) {
1114 return fn;
1115 }
1116
1117 var warned = false;
1118 function deprecated() {
1119 if (!warned) {
1120 if (process.throwDeprecation) {
1121 throw new Error(msg);
1122 } else if (process.traceDeprecation) {
1123 console.trace(msg);
1124 } else {
1125 console.error(msg);
1126 }
1127 warned = true;
1128 }
1129 return fn.apply(this, arguments);
1130 }
1131
1132 return deprecated;
1133};
1134
1135
1136var debugs = {};
1137var debugEnviron;
1138exports.debuglog = function(set) {
1139 if (isUndefined(debugEnviron))
1140 debugEnviron = process.env.NODE_DEBUG || '';
1141 set = set.toUpperCase();
1142 if (!debugs[set]) {
1143 if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) {
1144 var pid = process.pid;
1145 debugs[set] = function() {
1146 var msg = exports.format.apply(exports, arguments);
1147 console.error('%s %d: %s', set, pid, msg);
1148 };
1149 } else {
1150 debugs[set] = function() {};
1151 }
1152 }
1153 return debugs[set];
1154};
1155
1156
1157/**
1158 * Echos the value of a value. Trys to print the value out
1159 * in the best way possible given the different types.
1160 *
1161 * @param {Object} obj The object to print out.
1162 * @param {Object} opts Optional options object that alters the output.
1163 */
1164/* legacy: obj, showHidden, depth, colors*/
1165function inspect(obj, opts) {
1166 // default options
1167 var ctx = {
1168 seen: [],
1169 stylize: stylizeNoColor
1170 };
1171 // legacy...
1172 if (arguments.length >= 3) ctx.depth = arguments[2];
1173 if (arguments.length >= 4) ctx.colors = arguments[3];
1174 if (isBoolean(opts)) {
1175 // legacy...
1176 ctx.showHidden = opts;
1177 } else if (opts) {
1178 // got an "options" object
1179 exports._extend(ctx, opts);
1180 }
1181 // set default options
1182 if (isUndefined(ctx.showHidden)) ctx.showHidden = false;
1183 if (isUndefined(ctx.depth)) ctx.depth = 2;
1184 if (isUndefined(ctx.colors)) ctx.colors = false;
1185 if (isUndefined(ctx.customInspect)) ctx.customInspect = true;
1186 if (ctx.colors) ctx.stylize = stylizeWithColor;
1187 return formatValue(ctx, obj, ctx.depth);
1188}
1189exports.inspect = inspect;
1190
1191
1192// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics
1193inspect.colors = {
1194 'bold' : [1, 22],
1195 'italic' : [3, 23],
1196 'underline' : [4, 24],
1197 'inverse' : [7, 27],
1198 'white' : [37, 39],
1199 'grey' : [90, 39],
1200 'black' : [30, 39],
1201 'blue' : [34, 39],
1202 'cyan' : [36, 39],
1203 'green' : [32, 39],
1204 'magenta' : [35, 39],
1205 'red' : [31, 39],
1206 'yellow' : [33, 39]
1207};
1208
1209// Don't use 'blue' not visible on cmd.exe
1210inspect.styles = {
1211 'special': 'cyan',
1212 'number': 'yellow',
1213 'boolean': 'yellow',
1214 'undefined': 'grey',
1215 'null': 'bold',
1216 'string': 'green',
1217 'date': 'magenta',
1218 // "name": intentionally not styling
1219 'regexp': 'red'
1220};
1221
1222
1223function stylizeWithColor(str, styleType) {
1224 var style = inspect.styles[styleType];
1225
1226 if (style) {
1227 return '\u001b[' + inspect.colors[style][0] + 'm' + str +
1228 '\u001b[' + inspect.colors[style][1] + 'm';
1229 } else {
1230 return str;
1231 }
1232}
1233
1234
1235function stylizeNoColor(str, styleType) {
1236 return str;
1237}
1238
1239
1240function arrayToHash(array) {
1241 var hash = {};
1242
1243 array.forEach(function(val, idx) {
1244 hash[val] = true;
1245 });
1246
1247 return hash;
1248}
1249
1250
1251function formatValue(ctx, value, recurseTimes) {
1252 // Provide a hook for user-specified inspect functions.
1253 // Check that value is an object with an inspect function on it
1254 if (ctx.customInspect &&
1255 value &&
1256 isFunction(value.inspect) &&
1257 // Filter out the util module, it's inspect function is special
1258 value.inspect !== exports.inspect &&
1259 // Also filter out any prototype objects using the circular check.
1260 !(value.constructor && value.constructor.prototype === value)) {
1261 var ret = value.inspect(recurseTimes, ctx);
1262 if (!isString(ret)) {
1263 ret = formatValue(ctx, ret, recurseTimes);
1264 }
1265 return ret;
1266 }
1267
1268 // Primitive types cannot have properties
1269 var primitive = formatPrimitive(ctx, value);
1270 if (primitive) {
1271 return primitive;
1272 }
1273
1274 // Look up the keys of the object.
1275 var keys = Object.keys(value);
1276 var visibleKeys = arrayToHash(keys);
1277
1278 if (ctx.showHidden) {
1279 keys = Object.getOwnPropertyNames(value);
1280 }
1281
1282 // IE doesn't make error fields non-enumerable
1283 // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx
1284 if (isError(value)
1285 && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) {
1286 return formatError(value);
1287 }
1288
1289 // Some type of object without properties can be shortcutted.
1290 if (keys.length === 0) {
1291 if (isFunction(value)) {
1292 var name = value.name ? ': ' + value.name : '';
1293 return ctx.stylize('[Function' + name + ']', 'special');
1294 }
1295 if (isRegExp(value)) {
1296 return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
1297 }
1298 if (isDate(value)) {
1299 return ctx.stylize(Date.prototype.toString.call(value), 'date');
1300 }
1301 if (isError(value)) {
1302 return formatError(value);
1303 }
1304 }
1305
1306 var base = '', array = false, braces = ['{', '}'];
1307
1308 // Make Array say that they are Array
1309 if (isArray(value)) {
1310 array = true;
1311 braces = ['[', ']'];
1312 }
1313
1314 // Make functions say that they are functions
1315 if (isFunction(value)) {
1316 var n = value.name ? ': ' + value.name : '';
1317 base = ' [Function' + n + ']';
1318 }
1319
1320 // Make RegExps say that they are RegExps
1321 if (isRegExp(value)) {
1322 base = ' ' + RegExp.prototype.toString.call(value);
1323 }
1324
1325 // Make dates with properties first say the date
1326 if (isDate(value)) {
1327 base = ' ' + Date.prototype.toUTCString.call(value);
1328 }
1329
1330 // Make error with message first say the error
1331 if (isError(value)) {
1332 base = ' ' + formatError(value);
1333 }
1334
1335 if (keys.length === 0 && (!array || value.length == 0)) {
1336 return braces[0] + base + braces[1];
1337 }
1338
1339 if (recurseTimes < 0) {
1340 if (isRegExp(value)) {
1341 return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
1342 } else {
1343 return ctx.stylize('[Object]', 'special');
1344 }
1345 }
1346
1347 ctx.seen.push(value);
1348
1349 var output;
1350 if (array) {
1351 output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);
1352 } else {
1353 output = keys.map(function(key) {
1354 return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);
1355 });
1356 }
1357
1358 ctx.seen.pop();
1359
1360 return reduceToSingleString(output, base, braces);
1361}
1362
1363
1364function formatPrimitive(ctx, value) {
1365 if (isUndefined(value))
1366 return ctx.stylize('undefined', 'undefined');
1367 if (isString(value)) {
1368 var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '')
1369 .replace(/'/g, "\\'")
1370 .replace(/\\"/g, '"') + '\'';
1371 return ctx.stylize(simple, 'string');
1372 }
1373 if (isNumber(value))
1374 return ctx.stylize('' + value, 'number');
1375 if (isBoolean(value))
1376 return ctx.stylize('' + value, 'boolean');
1377 // For some reason typeof null is "object", so special case here.
1378 if (isNull(value))
1379 return ctx.stylize('null', 'null');
1380}
1381
1382
1383function formatError(value) {
1384 return '[' + Error.prototype.toString.call(value) + ']';
1385}
1386
1387
1388function formatArray(ctx, value, recurseTimes, visibleKeys, keys) {
1389 var output = [];
1390 for (var i = 0, l = value.length; i < l; ++i) {
1391 if (hasOwnProperty(value, String(i))) {
1392 output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
1393 String(i), true));
1394 } else {
1395 output.push('');
1396 }
1397 }
1398 keys.forEach(function(key) {
1399 if (!key.match(/^\d+$/)) {
1400 output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
1401 key, true));
1402 }
1403 });
1404 return output;
1405}
1406
1407
1408function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {
1409 var name, str, desc;
1410 desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] };
1411 if (desc.get) {
1412 if (desc.set) {
1413 str = ctx.stylize('[Getter/Setter]', 'special');
1414 } else {
1415 str = ctx.stylize('[Getter]', 'special');
1416 }
1417 } else {
1418 if (desc.set) {
1419 str = ctx.stylize('[Setter]', 'special');
1420 }
1421 }
1422 if (!hasOwnProperty(visibleKeys, key)) {
1423 name = '[' + key + ']';
1424 }
1425 if (!str) {
1426 if (ctx.seen.indexOf(desc.value) < 0) {
1427 if (isNull(recurseTimes)) {
1428 str = formatValue(ctx, desc.value, null);
1429 } else {
1430 str = formatValue(ctx, desc.value, recurseTimes - 1);
1431 }
1432 if (str.indexOf('\n') > -1) {
1433 if (array) {
1434 str = str.split('\n').map(function(line) {
1435 return ' ' + line;
1436 }).join('\n').substr(2);
1437 } else {
1438 str = '\n' + str.split('\n').map(function(line) {
1439 return ' ' + line;
1440 }).join('\n');
1441 }
1442 }
1443 } else {
1444 str = ctx.stylize('[Circular]', 'special');
1445 }
1446 }
1447 if (isUndefined(name)) {
1448 if (array && key.match(/^\d+$/)) {
1449 return str;
1450 }
1451 name = JSON.stringify('' + key);
1452 if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) {
1453 name = name.substr(1, name.length - 2);
1454 name = ctx.stylize(name, 'name');
1455 } else {
1456 name = name.replace(/'/g, "\\'")
1457 .replace(/\\"/g, '"')
1458 .replace(/(^"|"$)/g, "'");
1459 name = ctx.stylize(name, 'string');
1460 }
1461 }
1462
1463 return name + ': ' + str;
1464}
1465
1466
1467function reduceToSingleString(output, base, braces) {
1468 var numLinesEst = 0;
1469 var length = output.reduce(function(prev, cur) {
1470 numLinesEst++;
1471 if (cur.indexOf('\n') >= 0) numLinesEst++;
1472 return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1;
1473 }, 0);
1474
1475 if (length > 60) {
1476 return braces[0] +
1477 (base === '' ? '' : base + '\n ') +
1478 ' ' +
1479 output.join(',\n ') +
1480 ' ' +
1481 braces[1];
1482 }
1483
1484 return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];
1485}
1486
1487
1488// NOTE: These type checking functions intentionally don't use `instanceof`
1489// because it is fragile and can be easily faked with `Object.create()`.
1490function isArray(ar) {
1491 return Array.isArray(ar);
1492}
1493exports.isArray = isArray;
1494
1495function isBoolean(arg) {
1496 return typeof arg === 'boolean';
1497}
1498exports.isBoolean = isBoolean;
1499
1500function isNull(arg) {
1501 return arg === null;
1502}
1503exports.isNull = isNull;
1504
1505function isNullOrUndefined(arg) {
1506 return arg == null;
1507}
1508exports.isNullOrUndefined = isNullOrUndefined;
1509
1510function isNumber(arg) {
1511 return typeof arg === 'number';
1512}
1513exports.isNumber = isNumber;
1514
1515function isString(arg) {
1516 return typeof arg === 'string';
1517}
1518exports.isString = isString;
1519
1520function isSymbol(arg) {
1521 return typeof arg === 'symbol';
1522}
1523exports.isSymbol = isSymbol;
1524
1525function isUndefined(arg) {
1526 return arg === void 0;
1527}
1528exports.isUndefined = isUndefined;
1529
1530function isRegExp(re) {
1531 return isObject(re) && objectToString(re) === '[object RegExp]';
1532}
1533exports.isRegExp = isRegExp;
1534
1535function isObject(arg) {
1536 return typeof arg === 'object' && arg !== null;
1537}
1538exports.isObject = isObject;
1539
1540function isDate(d) {
1541 return isObject(d) && objectToString(d) === '[object Date]';
1542}
1543exports.isDate = isDate;
1544
1545function isError(e) {
1546 return isObject(e) &&
1547 (objectToString(e) === '[object Error]' || e instanceof Error);
1548}
1549exports.isError = isError;
1550
1551function isFunction(arg) {
1552 return typeof arg === 'function';
1553}
1554exports.isFunction = isFunction;
1555
1556function isPrimitive(arg) {
1557 return arg === null ||
1558 typeof arg === 'boolean' ||
1559 typeof arg === 'number' ||
1560 typeof arg === 'string' ||
1561 typeof arg === 'symbol' || // ES6 symbol
1562 typeof arg === 'undefined';
1563}
1564exports.isPrimitive = isPrimitive;
1565
1566exports.isBuffer = _dereq_('./support/isBuffer');
1567
1568function objectToString(o) {
1569 return Object.prototype.toString.call(o);
1570}
1571
1572
1573function pad(n) {
1574 return n < 10 ? '0' + n.toString(10) : n.toString(10);
1575}
1576
1577
1578var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep',
1579 'Oct', 'Nov', 'Dec'];
1580
1581// 26 Feb 16:19:34
1582function timestamp() {
1583 var d = new Date();
1584 var time = [pad(d.getHours()),
1585 pad(d.getMinutes()),
1586 pad(d.getSeconds())].join(':');
1587 return [d.getDate(), months[d.getMonth()], time].join(' ');
1588}
1589
1590
1591// log is just a thin wrapper to console.log that prepends a timestamp
1592exports.log = function() {
1593 console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments));
1594};
1595
1596
1597/**
1598 * Inherit the prototype methods from one constructor into another.
1599 *
1600 * The Function.prototype.inherits from lang.js rewritten as a standalone
1601 * function (not on Function.prototype). NOTE: If this file is to be loaded
1602 * during bootstrapping this function needs to be rewritten using some native
1603 * functions as prototype setup using normal JavaScript does not work as
1604 * expected during bootstrapping (see mirror.js in r114903).
1605 *
1606 * @param {function} ctor Constructor function which needs to inherit the
1607 * prototype.
1608 * @param {function} superCtor Constructor function to inherit prototype from.
1609 */
1610exports.inherits = _dereq_('inherits');
1611
1612exports._extend = function(origin, add) {
1613 // Don't do anything if add isn't an object
1614 if (!add || !isObject(add)) return origin;
1615
1616 var keys = Object.keys(add);
1617 var i = keys.length;
1618 while (i--) {
1619 origin[keys[i]] = add[keys[i]];
1620 }
1621 return origin;
1622};
1623
1624function hasOwnProperty(obj, prop) {
1625 return Object.prototype.hasOwnProperty.call(obj, prop);
1626}
1627
1628}).call(this,_dereq_('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
1629},{"./support/isBuffer":6,"_process":5,"inherits":4}],8:[function(_dereq_,module,exports){
1630
1631/**
1632 * Array#filter.
1633 *
1634 * @param {Array} arr
1635 * @param {Function} fn
1636 * @param {Object=} self
1637 * @return {Array}
1638 * @throw TypeError
1639 */
1640
1641module.exports = function (arr, fn, self) {
1642 if (arr.filter) return arr.filter(fn, self);
1643 if (void 0 === arr || null === arr) throw new TypeError;
1644 if ('function' != typeof fn) throw new TypeError;
1645 var ret = [];
1646 for (var i = 0; i < arr.length; i++) {
1647 if (!hasOwn.call(arr, i)) continue;
1648 var val = arr[i];
1649 if (fn.call(self, val, i, arr)) ret.push(val);
1650 }
1651 return ret;
1652};
1653
1654var hasOwn = Object.prototype.hasOwnProperty;
1655
1656},{}],9:[function(_dereq_,module,exports){
1657/**
1658 * array-foreach
1659 * Array#forEach ponyfill for older browsers
1660 * (Ponyfill: A polyfill that doesn't overwrite the native method)
1661 *
1662 * https://github.com/twada/array-foreach
1663 *
1664 * Copyright (c) 2015 Takuto Wada
1665 * Licensed under the MIT license.
1666 * http://twada.mit-license.org/
1667 */
1668'use strict';
1669
1670module.exports = function forEach (ary, callback, thisArg) {
1671 if (ary.forEach) {
1672 ary.forEach(callback, thisArg);
1673 return;
1674 }
1675 for (var i = 0; i < ary.length; i+=1) {
1676 callback.call(thisArg, ary[i], i, ary);
1677 }
1678};
1679
1680},{}],10:[function(_dereq_,module,exports){
1681module.exports = function (xs, f) {
1682 if (xs.map) return xs.map(f);
1683 var res = [];
1684 for (var i = 0; i < xs.length; i++) {
1685 var x = xs[i];
1686 if (hasOwn.call(xs, i)) res.push(f(x, i, xs));
1687 }
1688 return res;
1689};
1690
1691var hasOwn = Object.prototype.hasOwnProperty;
1692
1693},{}],11:[function(_dereq_,module,exports){
1694var hasOwn = Object.prototype.hasOwnProperty;
1695
1696module.exports = function (xs, f, acc) {
1697 var hasAcc = arguments.length >= 3;
1698 if (hasAcc && xs.reduce) return xs.reduce(f, acc);
1699 if (xs.reduce) return xs.reduce(f);
1700
1701 for (var i = 0; i < xs.length; i++) {
1702 if (!hasOwn.call(xs, i)) continue;
1703 if (!hasAcc) {
1704 acc = xs[i];
1705 hasAcc = true;
1706 continue;
1707 }
1708 acc = f(acc, xs[i], i);
1709 }
1710 return acc;
1711};
1712
1713},{}],12:[function(_dereq_,module,exports){
1714/**
1715 * empower - Power Assert feature enhancer for assert function/object.
1716 *
1717 * https://github.com/power-assert-js/empower
1718 *
1719 * Copyright (c) 2013-2015 Takuto Wada
1720 * Licensed under the MIT license.
1721 * https://github.com/power-assert-js/empower/blob/master/MIT-LICENSE.txt
1722 */
1723var defaultOptions = _dereq_('./lib/default-options');
1724var Decorator = _dereq_('./lib/decorator');
1725var create = _dereq_('object-create');
1726var slice = Array.prototype.slice;
1727var extend = _dereq_('xtend/mutable');
1728
1729/**
1730 * Enhance Power Assert feature to assert function/object.
1731 * @param assert target assert function or object to enhance
1732 * @param formatter power assert format function
1733 * @param options enhancement options
1734 * @return enhanced assert function/object
1735 */
1736function empower (assert, formatter, options) {
1737 var typeOfAssert = (typeof assert);
1738 var config;
1739 if ((typeOfAssert !== 'object' && typeOfAssert !== 'function') || assert === null) {
1740 throw new TypeError('empower argument should be a function or object.');
1741 }
1742 if (isEmpowered(assert)) {
1743 return assert;
1744 }
1745 config = extend(defaultOptions(), options);
1746 switch (typeOfAssert) {
1747 case 'function':
1748 return empowerAssertFunction(assert, formatter, config);
1749 case 'object':
1750 return empowerAssertObject(assert, formatter, config);
1751 default:
1752 throw new Error('Cannot be here');
1753 }
1754}
1755
1756function empowerAssertObject (assertObject, formatter, config) {
1757 var target = config.destructive ? assertObject : create(assertObject);
1758 var decorator = new Decorator(target, formatter, config);
1759 return extend(target, decorator.enhancement());
1760}
1761
1762function empowerAssertFunction (assertFunction, formatter, config) {
1763 if (config.destructive) {
1764 throw new Error('cannot use destructive:true to function.');
1765 }
1766 var decorator = new Decorator(assertFunction, formatter, config);
1767 var enhancement = decorator.enhancement();
1768 var powerAssert;
1769 if (typeof enhancement === 'function') {
1770 powerAssert = function powerAssert () {
1771 return enhancement.apply(null, slice.apply(arguments));
1772 };
1773 } else {
1774 powerAssert = function powerAssert () {
1775 return assertFunction.apply(null, slice.apply(arguments));
1776 };
1777 }
1778 extend(powerAssert, assertFunction);
1779 return extend(powerAssert, enhancement);
1780}
1781
1782function isEmpowered (assertObjectOrFunction) {
1783 return (typeof assertObjectOrFunction._capt === 'function') && (typeof assertObjectOrFunction._expr === 'function');
1784}
1785
1786empower.defaultOptions = defaultOptions;
1787module.exports = empower;
1788
1789},{"./lib/decorator":15,"./lib/default-options":16,"object-create":28,"xtend/mutable":61}],13:[function(_dereq_,module,exports){
1790'use strict';
1791
1792module.exports = function capturable () {
1793 var events = [];
1794
1795 function _capt (value, espath) {
1796 events.push({value: value, espath: espath});
1797 return value;
1798 }
1799
1800 function _expr (value, args) {
1801 var captured = events;
1802 events = [];
1803 return {
1804 powerAssertContext: {
1805 value: value,
1806 events: captured
1807 },
1808 source: {
1809 content: args.content,
1810 filepath: args.filepath,
1811 line: args.line
1812 }
1813 };
1814 }
1815
1816 return {
1817 _capt: _capt,
1818 _expr: _expr
1819 };
1820};
1821
1822},{}],14:[function(_dereq_,module,exports){
1823'use strict';
1824
1825var slice = Array.prototype.slice;
1826var map = _dereq_('array-map');
1827var some = _dereq_('array-some');
1828
1829function decorate (callSpec, decorator) {
1830 var func = callSpec.func;
1831 var thisObj = callSpec.thisObj;
1832 var numArgsToCapture = callSpec.numArgsToCapture;
1833
1834 return function decoratedAssert () {
1835 var context, message, args = slice.apply(arguments);
1836 if (some(args, isCaptured)) {
1837 var values = map(args.slice(0, numArgsToCapture), function (arg) {
1838 if (isNotCaptured(arg)) {
1839 return arg;
1840 }
1841 if (!context) {
1842 context = {
1843 source: arg.source,
1844 args: []
1845 };
1846 }
1847 context.args.push({
1848 value: arg.powerAssertContext.value,
1849 events: arg.powerAssertContext.events
1850 });
1851 return arg.powerAssertContext.value;
1852 });
1853
1854 if (numArgsToCapture === (args.length - 1)) {
1855 message = args[args.length - 1];
1856 }
1857
1858 var invocation = {
1859 thisObj: thisObj,
1860 func: func,
1861 values: values,
1862 message: message
1863 };
1864 return decorator.concreteAssert(invocation, context);
1865 } else {
1866 return func.apply(thisObj, args);
1867 }
1868 };
1869}
1870
1871function isNotCaptured (value) {
1872 return !isCaptured(value);
1873}
1874
1875function isCaptured (value) {
1876 return (typeof value === 'object') &&
1877 (value !== null) &&
1878 (typeof value.powerAssertContext !== 'undefined');
1879}
1880
1881module.exports = decorate;
1882
1883},{"array-map":10,"array-some":17}],15:[function(_dereq_,module,exports){
1884'use strict';
1885
1886var escallmatch = _dereq_('escallmatch');
1887var extend = _dereq_('xtend/mutable');
1888var forEach = _dereq_('array-foreach');
1889var map = _dereq_('array-map');
1890var filter = _dereq_('array-filter');
1891var capturable = _dereq_('./capturable');
1892var decorate = _dereq_('./decorate');
1893
1894
1895function Decorator (receiver, formatter, config) {
1896 this.receiver = receiver;
1897 this.formatter = formatter;
1898 this.config = config;
1899 this.matchers = map(config.patterns, escallmatch);
1900 this.eagerEvaluation = !(config.modifyMessageOnRethrow || config.saveContextOnRethrow);
1901}
1902
1903Decorator.prototype.enhancement = function () {
1904 var that = this;
1905 var container = this.container();
1906 forEach(filter(this.matchers, methodCall), function (matcher) {
1907 var methodName = detectMethodName(matcher.calleeAst());
1908 if (typeof that.receiver[methodName] === 'function') {
1909 var callSpec = {
1910 thisObj: that.receiver,
1911 func: that.receiver[methodName],
1912 numArgsToCapture: numberOfArgumentsToCapture(matcher)
1913 };
1914 container[methodName] = decorate(callSpec, that);
1915 }
1916 });
1917 extend(container, capturable());
1918 return container;
1919};
1920
1921Decorator.prototype.container = function () {
1922 var basement = {};
1923 if (typeof this.receiver === 'function') {
1924 var candidates = filter(this.matchers, functionCall);
1925 if (candidates.length === 1) {
1926 var callSpec = {
1927 thisObj: null,
1928 func: this.receiver,
1929 numArgsToCapture: numberOfArgumentsToCapture(candidates[0])
1930 };
1931 basement = decorate(callSpec, this);
1932 }
1933 }
1934 return basement;
1935};
1936
1937Decorator.prototype.concreteAssert = function (invocation, context) {
1938 var func = invocation.func;
1939 var thisObj = invocation.thisObj;
1940 var args = invocation.values;
1941 var message = invocation.message;
1942 if (this.eagerEvaluation) {
1943 var poweredMessage = this.buildPowerAssertText(message, context);
1944 return func.apply(thisObj, args.concat(poweredMessage));
1945 }
1946 try {
1947 return func.apply(thisObj, args.concat(message));
1948 } catch (e) {
1949 throw this.errorToRethrow(e, message, context);
1950 }
1951};
1952
1953Decorator.prototype.errorToRethrow = function (e, originalMessage, context) {
1954 if (e.name !== 'AssertionError') {
1955 return e;
1956 }
1957 if (typeof this.receiver.AssertionError !== 'function') {
1958 return e;
1959 }
1960 var f = new this.receiver.AssertionError({
1961 actual: e.actual,
1962 expected: e.expected,
1963 operator: e.operator,
1964 message: this.config.modifyMessageOnRethrow ? this.buildPowerAssertText(originalMessage, context) : e.message,
1965 stackStartFunction: Decorator.prototype.concreteAssert
1966 });
1967 if (this.config.saveContextOnRethrow) {
1968 f.powerAssertContext = context;
1969 }
1970 return f;
1971};
1972
1973Decorator.prototype.buildPowerAssertText = function (message, context) {
1974 var powerAssertText = this.formatter(context);
1975 return message ? message + ' ' + powerAssertText : powerAssertText;
1976};
1977
1978
1979function numberOfArgumentsToCapture (matcher) {
1980 var argSpecs = matcher.argumentSignatures();
1981 var len = argSpecs.length;
1982 var lastArg;
1983 if (0 < len) {
1984 lastArg = argSpecs[len - 1];
1985 if (lastArg.name === 'message' && lastArg.kind === 'optional') {
1986 len -= 1;
1987 }
1988 }
1989 return len;
1990}
1991
1992
1993function detectMethodName (node) {
1994 if (node.type === 'MemberExpression') {
1995 return node.property.name;
1996 }
1997 return null;
1998}
1999
2000
2001function functionCall (matcher) {
2002 return matcher.calleeAst().type === 'Identifier';
2003}
2004
2005
2006function methodCall (matcher) {
2007 return matcher.calleeAst().type === 'MemberExpression';
2008}
2009
2010
2011module.exports = Decorator;
2012
2013},{"./capturable":13,"./decorate":14,"array-filter":8,"array-foreach":9,"array-map":10,"escallmatch":18,"xtend/mutable":61}],16:[function(_dereq_,module,exports){
2014'use strict';
2015
2016module.exports = function defaultOptions () {
2017 return {
2018 destructive: false,
2019 modifyMessageOnRethrow: false,
2020 saveContextOnRethrow: false,
2021 patterns: [
2022 'assert(value, [message])',
2023 'assert.ok(value, [message])',
2024 'assert.equal(actual, expected, [message])',
2025 'assert.notEqual(actual, expected, [message])',
2026 'assert.strictEqual(actual, expected, [message])',
2027 'assert.notStrictEqual(actual, expected, [message])',
2028 'assert.deepEqual(actual, expected, [message])',
2029 'assert.notDeepEqual(actual, expected, [message])',
2030 'assert.deepStrictEqual(actual, expected, [message])',
2031 'assert.notDeepStrictEqual(actual, expected, [message])'
2032 ]
2033 };
2034};
2035
2036},{}],17:[function(_dereq_,module,exports){
2037/**
2038 * array-some
2039 * Array#some ponyfill for older browsers
2040 * (Ponyfill: A polyfill that doesn't overwrite the native method)
2041 *
2042 * https://github.com/twada/array-some
2043 *
2044 * Copyright (c) 2015 Takuto Wada
2045 * Licensed under the MIT license.
2046 * http://twada.mit-license.org/
2047 */
2048'use strict';
2049
2050module.exports = function some (ary, callback, thisArg) {
2051 if (ary.some) {
2052 return ary.some(callback, thisArg);
2053 }
2054 for (var i = 0; i < ary.length; i+=1) {
2055 if (callback.call(thisArg, ary[i], i, ary)) {
2056 return true;
2057 }
2058 }
2059 return false;
2060};
2061
2062},{}],18:[function(_dereq_,module,exports){
2063/**
2064 * escallmatch:
2065 * ECMAScript CallExpression matcher made from function/method signature
2066 *
2067 * https://github.com/twada/escallmatch
2068 *
2069 * Copyright (c) 2014-2015 Takuto Wada
2070 * Licensed under the MIT license.
2071 * http://twada.mit-license.org/
2072 */
2073'use strict';
2074/* jshint -W024 */
2075
2076var esprima = _dereq_('esprima');
2077var estraverse = _dereq_('estraverse');
2078var espurify = _dereq_('espurify');
2079var syntax = estraverse.Syntax;
2080var hasOwn = Object.prototype.hasOwnProperty;
2081var forEach = _dereq_('array-foreach');
2082var map = _dereq_('array-map');
2083var filter = _dereq_('array-filter');
2084var reduce = _dereq_('array-reduce');
2085var indexOf = _dereq_('indexof');
2086var deepEqual = _dereq_('deep-equal');
2087var notCallExprMessage = 'Argument should be in the form of CallExpression';
2088var duplicatedArgMessage = 'Duplicate argument name: ';
2089var invalidFormMessage = 'Argument should be in the form of `name` or `[name]`';
2090
2091function createMatcher (signatureStr, options) {
2092 var ast = extractExpressionFrom(esprima.parse(signatureStr));
2093 return new Matcher(ast, options || {});
2094}
2095
2096function Matcher (signatureAst, options) {
2097 this.visitorKeys = options.visitorKeys || estraverse.VisitorKeys;
2098 this.signatureAst = signatureAst;
2099 this.signatureCalleeDepth = astDepth(signatureAst.callee, this.visitorKeys);
2100 this.numMaxArgs = this.signatureAst.arguments.length;
2101 this.numMinArgs = filter(this.signatureAst.arguments, identifiers).length;
2102}
2103
2104Matcher.prototype.test = function (currentNode) {
2105 var calleeMatched = this.isCalleeMatched(currentNode);
2106 var numArgs;
2107 if (calleeMatched) {
2108 numArgs = currentNode.arguments.length;
2109 return this.numMinArgs <= numArgs && numArgs <= this.numMaxArgs;
2110 }
2111 return false;
2112};
2113
2114Matcher.prototype.matchArgument = function (currentNode, parentNode) {
2115 if (isCalleeOfParent(currentNode, parentNode)) {
2116 return null;
2117 }
2118 if (this.test(parentNode)) {
2119 var indexOfCurrentArg = indexOf(parentNode.arguments, currentNode);
2120 var numOptional = parentNode.arguments.length - this.numMinArgs;
2121 var matchedSignatures = reduce(this.argumentSignatures(), function (accum, argSig) {
2122 if (argSig.kind === 'mandatory') {
2123 accum.push(argSig);
2124 }
2125 if (argSig.kind === 'optional' && 0 < numOptional) {
2126 numOptional -= 1;
2127 accum.push(argSig);
2128 }
2129 return accum;
2130 }, []);
2131 return matchedSignatures[indexOfCurrentArg];
2132 }
2133 return null;
2134};
2135
2136Matcher.prototype.calleeAst = function () {
2137 return espurify(this.signatureAst.callee);
2138};
2139
2140Matcher.prototype.argumentSignatures = function () {
2141 return map(this.signatureAst.arguments, toArgumentSignature);
2142};
2143
2144Matcher.prototype.isCalleeMatched = function (node) {
2145 if (!isCallExpression(node)) {
2146 return false;
2147 }
2148 if (!this.isSameDepthAsSignatureCallee(node.callee)) {
2149 return false;
2150 }
2151 return deepEqual(espurify(this.signatureAst.callee), espurify(node.callee));
2152};
2153
2154Matcher.prototype.isSameDepthAsSignatureCallee = function (ast) {
2155 var depth = this.signatureCalleeDepth;
2156 var currentDepth = 0;
2157 estraverse.traverse(ast, {
2158 keys: this.visitorKeys,
2159 enter: function (currentNode, parentNode) {
2160 var path = this.path();
2161 var pathDepth = path ? path.length : 0;
2162 if (currentDepth < pathDepth) {
2163 currentDepth = pathDepth;
2164 }
2165 if (depth < currentDepth) {
2166 this['break']();
2167 }
2168 }
2169 });
2170 return (depth === currentDepth);
2171};
2172
2173function toArgumentSignature (argSignatureNode) {
2174 switch(argSignatureNode.type) {
2175 case syntax.Identifier:
2176 return {
2177 name: argSignatureNode.name,
2178 kind: 'mandatory'
2179 };
2180 case syntax.ArrayExpression:
2181 return {
2182 name: argSignatureNode.elements[0].name,
2183 kind: 'optional'
2184 };
2185 default:
2186 return null;
2187 }
2188}
2189
2190function astDepth (ast, visitorKeys) {
2191 var maxDepth = 0;
2192 estraverse.traverse(ast, {
2193 keys: visitorKeys,
2194 enter: function (currentNode, parentNode) {
2195 var path = this.path();
2196 var pathDepth = path ? path.length : 0;
2197 if (maxDepth < pathDepth) {
2198 maxDepth = pathDepth;
2199 }
2200 }
2201 });
2202 return maxDepth;
2203}
2204
2205function isCallExpression (node) {
2206 return node && node.type === syntax.CallExpression;
2207}
2208
2209function isCalleeOfParent(currentNode, parentNode) {
2210 return parentNode && currentNode &&
2211 parentNode.type === syntax.CallExpression &&
2212 parentNode.callee === currentNode;
2213}
2214
2215function identifiers (node) {
2216 return node.type === syntax.Identifier;
2217}
2218
2219function validateApiExpression (callExpression) {
2220 if (callExpression.type !== syntax.CallExpression) {
2221 throw new Error(notCallExprMessage);
2222 }
2223 var names = {};
2224 forEach(callExpression.arguments, function (arg) {
2225 var name = validateArg(arg);
2226 if (hasOwn.call(names, name)) {
2227 throw new Error(duplicatedArgMessage + name);
2228 } else {
2229 names[name] = name;
2230 }
2231 });
2232}
2233
2234function validateArg (arg) {
2235 var inner;
2236 switch(arg.type) {
2237 case syntax.Identifier:
2238 return arg.name;
2239 case syntax.ArrayExpression:
2240 if (arg.elements.length !== 1) {
2241 throw new Error(invalidFormMessage);
2242 }
2243 inner = arg.elements[0];
2244 if (inner.type !== syntax.Identifier) {
2245 throw new Error(invalidFormMessage);
2246 }
2247 return inner.name;
2248 default:
2249 throw new Error(invalidFormMessage);
2250 }
2251}
2252
2253function extractExpressionFrom (tree) {
2254 var statement, expression;
2255 statement = tree.body[0];
2256 if (statement.type !== syntax.ExpressionStatement) {
2257 throw new Error(notCallExprMessage);
2258 }
2259 expression = statement.expression;
2260 validateApiExpression(expression);
2261 return expression;
2262}
2263
2264module.exports = createMatcher;
2265
2266},{"array-filter":8,"array-foreach":9,"array-map":10,"array-reduce":11,"deep-equal":19,"esprima":33,"espurify":22,"estraverse":34,"indexof":36}],19:[function(_dereq_,module,exports){
2267var pSlice = Array.prototype.slice;
2268var objectKeys = _dereq_('./lib/keys.js');
2269var isArguments = _dereq_('./lib/is_arguments.js');
2270
2271var deepEqual = module.exports = function (actual, expected, opts) {
2272 if (!opts) opts = {};
2273 // 7.1. All identical values are equivalent, as determined by ===.
2274 if (actual === expected) {
2275 return true;
2276
2277 } else if (actual instanceof Date && expected instanceof Date) {
2278 return actual.getTime() === expected.getTime();
2279
2280 // 7.3. Other pairs that do not both pass typeof value == 'object',
2281 // equivalence is determined by ==.
2282 } else if (!actual || !expected || typeof actual != 'object' && typeof expected != 'object') {
2283 return opts.strict ? actual === expected : actual == expected;
2284
2285 // 7.4. For all other Object pairs, including Array objects, equivalence is
2286 // determined by having the same number of owned properties (as verified
2287 // with Object.prototype.hasOwnProperty.call), the same set of keys
2288 // (although not necessarily the same order), equivalent values for every
2289 // corresponding key, and an identical 'prototype' property. Note: this
2290 // accounts for both named and indexed properties on Arrays.
2291 } else {
2292 return objEquiv(actual, expected, opts);
2293 }
2294}
2295
2296function isUndefinedOrNull(value) {
2297 return value === null || value === undefined;
2298}
2299
2300function isBuffer (x) {
2301 if (!x || typeof x !== 'object' || typeof x.length !== 'number') return false;
2302 if (typeof x.copy !== 'function' || typeof x.slice !== 'function') {
2303 return false;
2304 }
2305 if (x.length > 0 && typeof x[0] !== 'number') return false;
2306 return true;
2307}
2308
2309function objEquiv(a, b, opts) {
2310 var i, key;
2311 if (isUndefinedOrNull(a) || isUndefinedOrNull(b))
2312 return false;
2313 // an identical 'prototype' property.
2314 if (a.prototype !== b.prototype) return false;
2315 //~~~I've managed to break Object.keys through screwy arguments passing.
2316 // Converting to array solves the problem.
2317 if (isArguments(a)) {
2318 if (!isArguments(b)) {
2319 return false;
2320 }
2321 a = pSlice.call(a);
2322 b = pSlice.call(b);
2323 return deepEqual(a, b, opts);
2324 }
2325 if (isBuffer(a)) {
2326 if (!isBuffer(b)) {
2327 return false;
2328 }
2329 if (a.length !== b.length) return false;
2330 for (i = 0; i < a.length; i++) {
2331 if (a[i] !== b[i]) return false;
2332 }
2333 return true;
2334 }
2335 try {
2336 var ka = objectKeys(a),
2337 kb = objectKeys(b);
2338 } catch (e) {//happens when one is a string literal and the other isn't
2339 return false;
2340 }
2341 // having the same number of owned properties (keys incorporates
2342 // hasOwnProperty)
2343 if (ka.length != kb.length)
2344 return false;
2345 //the same set of keys (although not necessarily the same order),
2346 ka.sort();
2347 kb.sort();
2348 //~~~cheap key test
2349 for (i = ka.length - 1; i >= 0; i--) {
2350 if (ka[i] != kb[i])
2351 return false;
2352 }
2353 //equivalent values for every corresponding key, and
2354 //~~~possibly expensive deep test
2355 for (i = ka.length - 1; i >= 0; i--) {
2356 key = ka[i];
2357 if (!deepEqual(a[key], b[key], opts)) return false;
2358 }
2359 return typeof a === typeof b;
2360}
2361
2362},{"./lib/is_arguments.js":20,"./lib/keys.js":21}],20:[function(_dereq_,module,exports){
2363var supportsArgumentsClass = (function(){
2364 return Object.prototype.toString.call(arguments)
2365})() == '[object Arguments]';
2366
2367exports = module.exports = supportsArgumentsClass ? supported : unsupported;
2368
2369exports.supported = supported;
2370function supported(object) {
2371 return Object.prototype.toString.call(object) == '[object Arguments]';
2372};
2373
2374exports.unsupported = unsupported;
2375function unsupported(object){
2376 return object &&
2377 typeof object == 'object' &&
2378 typeof object.length == 'number' &&
2379 Object.prototype.hasOwnProperty.call(object, 'callee') &&
2380 !Object.prototype.propertyIsEnumerable.call(object, 'callee') ||
2381 false;
2382};
2383
2384},{}],21:[function(_dereq_,module,exports){
2385exports = module.exports = typeof Object.keys === 'function'
2386 ? Object.keys : shim;
2387
2388exports.shim = shim;
2389function shim (obj) {
2390 var keys = [];
2391 for (var key in obj) keys.push(key);
2392 return keys;
2393}
2394
2395},{}],22:[function(_dereq_,module,exports){
2396/**
2397 * espurify - Clone new AST without extra properties
2398 *
2399 * https://github.com/estools/espurify
2400 *
2401 * Copyright (c) 2014-2015 Takuto Wada
2402 * Licensed under the MIT license.
2403 * https://github.com/estools/espurify/blob/master/MIT-LICENSE.txt
2404 */
2405'use strict';
2406
2407var createWhitelist = _dereq_('./lib/create-whitelist');
2408var cloneWithWhitelist = _dereq_('./lib/clone-ast');
2409
2410function createCloneFunction (options) {
2411 return cloneWithWhitelist(createWhitelist(options));
2412}
2413
2414var espurify = createCloneFunction();
2415espurify.customize = createCloneFunction;
2416module.exports = espurify;
2417
2418},{"./lib/clone-ast":24,"./lib/create-whitelist":25}],23:[function(_dereq_,module,exports){
2419module.exports = {
2420 ArrayExpression: ['type', 'elements'],
2421 ArrayPattern: ['type', 'elements'],
2422 ArrowFunctionExpression: ['type', 'id', 'params', 'body', 'generator', 'expression'],
2423 AssignmentExpression: ['type', 'operator', 'left', 'right'],
2424 AssignmentPattern: ['type', 'left', 'right'],
2425 BinaryExpression: ['type', 'operator', 'left', 'right'],
2426 BlockStatement: ['type', 'body'],
2427 BreakStatement: ['type', 'label'],
2428 CallExpression: ['type', 'callee', 'arguments'],
2429 CatchClause: ['type', 'param', 'guard', 'body'],
2430 ClassBody: ['type', 'body'],
2431 ClassDeclaration: ['type', 'id', 'superClass', 'body'],
2432 ClassExpression: ['type', 'id', 'superClass', 'body'],
2433 ConditionalExpression: ['type', 'test', 'alternate', 'consequent'],
2434 ContinueStatement: ['type', 'label'],
2435 DebuggerStatement: ['type'],
2436 DoWhileStatement: ['type', 'body', 'test'],
2437 EmptyStatement: ['type'],
2438 ExportAllDeclaration: ['type', 'source'],
2439 ExportDefaultDeclaration: ['type', 'declaration'],
2440 ExportNamedDeclaration: ['type', 'declaration', 'specifiers', 'source'],
2441 ExportSpecifier: ['type', 'exported', 'local'],
2442 ExpressionStatement: ['type', 'expression'],
2443 ForInStatement: ['type', 'left', 'right', 'body'],
2444 ForOfStatement: ['type', 'left', 'right', 'body'],
2445 ForStatement: ['type', 'init', 'test', 'update', 'body'],
2446 FunctionDeclaration: ['type', 'id', 'params', 'body', 'generator'],
2447 FunctionExpression: ['type', 'id', 'params', 'body', 'generator'],
2448 Identifier: ['type', 'name'],
2449 IfStatement: ['type', 'test', 'consequent', 'alternate'],
2450 ImportDeclaration: ['type', 'specifiers', 'source'],
2451 ImportDefaultSpecifier: ['type', 'local'],
2452 ImportNamespaceSpecifier: ['type', 'local'],
2453 ImportSpecifier: ['type', 'imported', 'local'],
2454 LabeledStatement: ['type', 'label', 'body'],
2455 Literal: ['type', 'value', 'regex'],
2456 LogicalExpression: ['type', 'operator', 'left', 'right'],
2457 MemberExpression: ['type', 'object', 'property', 'computed'],
2458 MetaProperty: ['type', 'meta', 'property'],
2459 MethodDefinition: ['type', 'key', 'value', 'kind', 'computed', 'static'],
2460 NewExpression: ['type', 'callee', 'arguments'],
2461 ObjectExpression: ['type', 'properties'],
2462 ObjectPattern: ['type', 'properties'],
2463 Program: ['type', 'body', 'sourceType'],
2464 Property: ['type', 'key', 'value', 'kind', 'method', 'shorthand', 'computed'],
2465 RestElement: ['type', 'argument'],
2466 ReturnStatement: ['type', 'argument'],
2467 SequenceExpression: ['type', 'expressions'],
2468 SpreadElement: ['type', 'argument'],
2469 Super: ['type'],
2470 SwitchCase: ['type', 'test', 'consequent'],
2471 SwitchStatement: ['type', 'discriminant', 'cases', 'lexical'],
2472 TaggedTemplateExpression: ['type', 'tag', 'quasi'],
2473 TemplateElement: ['type', 'tail', 'value'],
2474 TemplateLiteral: ['type', 'quasis', 'expressions'],
2475 ThisExpression: ['type'],
2476 ThrowStatement: ['type', 'argument'],
2477 TryStatement: ['type', 'block', 'handler', 'finalizer'],
2478 UnaryExpression: ['type', 'operator', 'prefix', 'argument'],
2479 UpdateExpression: ['type', 'operator', 'argument', 'prefix'],
2480 VariableDeclaration: ['type', 'declarations', 'kind'],
2481 VariableDeclarator: ['type', 'id', 'init'],
2482 WhileStatement: ['type', 'test', 'body'],
2483 WithStatement: ['type', 'object', 'body'],
2484 YieldExpression: ['type', 'argument', 'delegate']
2485};
2486
2487},{}],24:[function(_dereq_,module,exports){
2488'use strict';
2489
2490var isArray = _dereq_('isarray');
2491
2492module.exports = function cloneWithWhitelist (whitelist) {
2493
2494 function cloneRoot (ast) {
2495 return cloneContainer({}, ast);
2496 }
2497
2498 function cloneContainer (collector, obj) {
2499 if (isArray(obj)) {
2500 return cloneArray(collector, obj);
2501 } else if (obj.type && whitelist[obj.type]) {
2502 return cloneNode(collector, obj);
2503 } else {
2504 return cloneObj(collector, obj);
2505 }
2506 }
2507
2508 function cloneArray (collector, ary) {
2509 var i, len;
2510 for (i = 0, len = ary.length; i < len; i += 1) {
2511 collector.push(cloneOf(ary[i]));
2512 }
2513 return collector;
2514 }
2515
2516 function cloneNode (collector, obj) {
2517 var i, len, props = whitelist[obj.type];
2518 for (i = 0, len = props.length; i < len; i += 1) {
2519 cloneProperty(collector, obj, props[i]);
2520 }
2521 return collector;
2522 }
2523
2524 function cloneObj (collector, obj) {
2525 var key;
2526 for (key in obj) {
2527 cloneProperty(collector, obj, key);
2528 }
2529 return collector;
2530 }
2531
2532 function cloneProperty (collector, obj, key) {
2533 if (obj.hasOwnProperty(key)) {
2534 collector[key] = cloneOf(obj[key]);
2535 }
2536 }
2537
2538 function cloneOf (val) {
2539 if (typeof val === 'object' && val !== null) {
2540 if (val instanceof RegExp) {
2541 return new RegExp(val);
2542 } else {
2543 return cloneContainer(isArray(val) ? [] : {}, val);
2544 }
2545 } else {
2546 return val;
2547 }
2548 }
2549
2550 return cloneRoot;
2551};
2552
2553},{"isarray":26}],25:[function(_dereq_,module,exports){
2554'use strict';
2555
2556var defaultProps = _dereq_('./ast-properties');
2557var objectKeys = _dereq_('object-keys');
2558var extend = _dereq_('xtend');
2559
2560module.exports = function createWhitelist (options) {
2561 var opts = extend({}, options);
2562 var typeName, i, len;
2563 var keys = objectKeys(defaultProps);
2564 var result = {};
2565 for (i = 0, len = keys.length; i < len; i += 1) {
2566 typeName = keys[i];
2567 result[typeName] = [].concat(defaultProps[typeName]).concat(opts.extra);
2568 }
2569 return result;
2570};
2571
2572},{"./ast-properties":23,"object-keys":37,"xtend":60}],26:[function(_dereq_,module,exports){
2573module.exports = Array.isArray || function (arr) {
2574 return Object.prototype.toString.call(arr) == '[object Array]';
2575};
2576
2577},{}],27:[function(_dereq_,module,exports){
2578var objectCreate = Object.create;
2579
2580
2581module.exports = function create(prototype, properties) {
2582 return objectCreate.call(Object, prototype, properties);
2583};
2584
2585},{}],28:[function(_dereq_,module,exports){
2586/* jshint proto: true, scripturl: true */
2587
2588var objectCreate = Object.create;
2589var defineProperties = _dereq_('object-define-property').defineProperties;
2590
2591// Contributed by Brandon Benvie, October, 2012
2592var createEmpty;
2593var supportsProto = Object.prototype.__proto__ === null;
2594if (supportsProto || typeof document === 'undefined') {
2595 createEmpty = function () {
2596 return { "__proto__": null };
2597 };
2598} else {
2599 // In old IE __proto__ can't be used to manually set `null`, nor does
2600 // any other method exist to make an object that inherits from nothing,
2601 // aside from Object.prototype itself. Instead, create a new global
2602 // object and *steal* its Object.prototype and strip it bare. This is
2603 // used as the prototype to create nullary objects.
2604 createEmpty = function () {
2605 var iframe = document.createElement('iframe');
2606 var parent = document.body || document.documentElement;
2607 iframe.style.display = 'none';
2608 parent.appendChild(iframe);
2609 iframe.src = 'javascript:';
2610 var empty = iframe.contentWindow.Object.prototype;
2611 parent.removeChild(iframe);
2612 iframe = null;
2613 delete empty.constructor;
2614 delete empty.hasOwnProperty;
2615 delete empty.propertyIsEnumerable;
2616 delete empty.isPrototypeOf;
2617 delete empty.toLocaleString;
2618 delete empty.toString;
2619 delete empty.valueOf;
2620 empty.__proto__ = null;
2621
2622 function Empty() {}
2623 Empty.prototype = empty;
2624 // short-circuit future calls
2625 createEmpty = function () {
2626 return new Empty();
2627 };
2628 return new Empty();
2629 };
2630}
2631
2632function create(prototype, properties) {
2633 var object;
2634 function Type() {} // An empty constructor.
2635
2636 if (prototype === null) {
2637 object = createEmpty();
2638 } else {
2639 if (typeof prototype !== "object" && typeof prototype !== "function") {
2640 // In the native implementation `parent` can be `null` OR *any*
2641 // `instanceof Object` (Object|Function|Array|RegExp|etc) Use `typeof`
2642 // tho, b/c in old IE, DOM elements are not `instanceof Object` like
2643 // they are in modern browsers. Using `Object.create` on DOM elements
2644 // is...err...probably inappropriate, but the native version allows for
2645 // it.
2646 // same msg as Chrome
2647 throw new TypeError("Object prototype may only be an Object or null");
2648 }
2649 Type.prototype = prototype;
2650 object = new Type();
2651 // IE has no built-in implementation of `Object.getPrototypeOf`
2652 // neither `__proto__`, but this manually setting `__proto__` will
2653 // guarantee that `Object.getPrototypeOf` will work as expected with
2654 // objects created using `Object.create`
2655 object.__proto__ = prototype;
2656 }
2657
2658 if (properties !== void 0) {
2659 defineProperties(object, properties);
2660 }
2661
2662 return object;
2663}
2664
2665
2666if (!objectCreate) {
2667 module.exports = create;
2668} else {
2669 module.exports = _dereq_('./index');
2670}
2671
2672},{"./index":27,"object-define-property":30}],29:[function(_dereq_,module,exports){
2673var defProp = Object.defineProperty, defProps = Object.defineProperties;
2674
2675
2676module.exports = {
2677 defineProperty: function defineProperty(object, property, descriptor) {
2678 defProp.call(Object, object, property, descriptor);
2679 },
2680 defineProperties: function defineProperties(object, properties) {
2681 defProps.call(Object, object, properties);
2682 }
2683};
2684
2685},{}],30:[function(_dereq_,module,exports){
2686/* jshint proto:true */
2687// ES5 15.2.3.6
2688// http://es5.github.com/#x15.2.3.6
2689
2690// Patch for WebKit and IE8 standard mode
2691// Designed by hax <hax.github.com>
2692// related issue: https://github.com/es-shims/es5-shim/issues#issue/5
2693// IE8 Reference:
2694// http://msdn.microsoft.com/en-us/library/dd282900.aspx
2695// http://msdn.microsoft.com/en-us/library/dd229916.aspx
2696// WebKit Bugs:
2697// https://bugs.webkit.org/show_bug.cgi?id=36423
2698
2699var has = _dereq_('has');
2700var bind = _dereq_('function-bind');
2701
2702var ERR_NON_OBJECT_DESCRIPTOR = "Property description must be an object: ";
2703var ERR_NON_OBJECT_TARGET = "Object.defineProperty called on non-object: ";
2704var ERR_ACCESSORS_NOT_SUPPORTED = "getters & setters can not be defined " +
2705 "on this javascript engine";
2706
2707var defProp = Object.defineProperty, defProps = Object.defineProperties;
2708var call = Function.prototype.call;
2709var prototypeOfObject = Object.prototype;
2710
2711
2712// If JS engine supports accessors creating shortcuts.
2713var defineGetter;
2714var defineSetter;
2715var lookupGetter;
2716var lookupSetter;
2717var supportsAccessors;
2718if ((supportsAccessors = has(prototypeOfObject, "__defineGetter__"))) {
2719 defineGetter = bind.call(call, prototypeOfObject.__defineGetter__);
2720 defineSetter = bind.call(call, prototypeOfObject.__defineSetter__);
2721 lookupGetter = bind.call(call, prototypeOfObject.__lookupGetter__);
2722 lookupSetter = bind.call(call, prototypeOfObject.__lookupSetter__);
2723}
2724
2725function doesDefinePropertyWork(object) {
2726 try {
2727 defProp.call(Object, object, "sentinel", {});
2728 return "sentinel" in object;
2729 } catch (exception) {
2730 // returns falsy
2731 }
2732}
2733
2734// check whether defineProperty works if it's given. Otherwise,
2735// shim partially.
2736if (defProp) {
2737 var definePropertyWorksOnObject = doesDefinePropertyWork({});
2738 var definePropertyWorksOnDom = typeof document === "undefined" ||
2739 doesDefinePropertyWork(document.createElement("div"));
2740 if (!definePropertyWorksOnObject || !definePropertyWorksOnDom) {
2741 var definePropertyFallback = defProp, definePropertiesFallback = defProps;
2742 }
2743}
2744
2745
2746function defineProperty(object, property, descriptor) {
2747 if ((typeof object !== "object" && typeof object !== "function") || object === null) {
2748 throw new TypeError(ERR_NON_OBJECT_TARGET + object);
2749 }
2750 if ((typeof descriptor !== "object" && typeof descriptor !== "function") || descriptor === null) {
2751 throw new TypeError(ERR_NON_OBJECT_DESCRIPTOR + descriptor);
2752 }
2753 // make a valiant attempt to use the real defineProperty
2754 // for I8's DOM elements.
2755 if (definePropertyFallback) {
2756 try {
2757 return definePropertyFallback.call(Object, object, property, descriptor);
2758 } catch (exception) {
2759 // try the shim if the real one doesn't work
2760 }
2761 }
2762
2763 // If it's a data property.
2764 if (has(descriptor, "value")) {
2765 // fail silently if "writable", "enumerable", or "configurable"
2766 // are requested but not supported
2767 if (supportsAccessors && (lookupGetter(object, property) ||
2768 lookupSetter(object, property)))
2769 {
2770 // As accessors are supported only on engines implementing
2771 // `__proto__` we can safely override `__proto__` while defining
2772 // a property to make sure that we don't hit an inherited
2773 // accessor.
2774 var prototype = object.__proto__;
2775 object.__proto__ = prototypeOfObject;
2776 // Deleting a property anyway since getter / setter may be
2777 // defined on object itself.
2778 delete object[property];
2779 object[property] = descriptor.value;
2780 // Setting original `__proto__` back now.
2781 object.__proto__ = prototype;
2782 } else {
2783 object[property] = descriptor.value;
2784 }
2785 } else {
2786 if (!supportsAccessors) {
2787 throw new TypeError(ERR_ACCESSORS_NOT_SUPPORTED);
2788 }
2789 // If we got that far then getters and setters can be defined !!
2790 if (has(descriptor, "get")) {
2791 defineGetter(object, property, descriptor.get);
2792 }
2793 if (has(descriptor, "set")) {
2794 defineSetter(object, property, descriptor.set);
2795 }
2796 }
2797 return object;
2798}
2799
2800
2801function defineProperties(object, properties) {
2802 // make a valiant attempt to use the real defineProperties
2803 if (definePropertiesFallback) {
2804 try {
2805 return definePropertiesFallback.call(Object, object, properties);
2806 } catch (exception) {
2807 // try the shim if the real one doesn't work
2808 }
2809 }
2810 for (var property in properties) {
2811 if (has(properties, property) && property !== "__proto__") {
2812 defineProperty(object, property, properties[property]);
2813 }
2814 }
2815 return object;
2816}
2817
2818
2819if (!defProp || definePropertyFallback) {
2820 module.exports = {
2821 defineProperty: defineProperty,
2822 defineProperties: defineProperties
2823 };
2824} else {
2825 module.exports = _dereq_('./index');
2826}
2827
2828},{"./index":29,"function-bind":31,"has":32}],31:[function(_dereq_,module,exports){
2829var ERROR_MESSAGE = "Function.prototype.bind called on incompatible "
2830var slice = Array.prototype.slice
2831
2832module.exports = bind
2833
2834function bind(that) {
2835 var target = this
2836 if (typeof target !== "function") {
2837 throw new TypeError(ERROR_MESSAGE + target)
2838 }
2839 var args = slice.call(arguments, 1)
2840
2841 return function bound() {
2842 if (this instanceof bound) {
2843 var F = function () {}
2844 F.prototype = target.prototype
2845 var self = new F()
2846
2847 var result = target.apply(
2848 self,
2849 args.concat(slice.call(arguments))
2850 )
2851 if (Object(result) === result) {
2852 return result
2853 }
2854 return self
2855 } else {
2856 return target.apply(
2857 that,
2858 args.concat(slice.call(arguments))
2859 )
2860 }
2861 }
2862}
2863
2864},{}],32:[function(_dereq_,module,exports){
2865var hasOwn = Object.prototype.hasOwnProperty;
2866
2867
2868module.exports = function has(obj, property) {
2869 return hasOwn.call(obj, property);
2870};
2871
2872},{}],33:[function(_dereq_,module,exports){
2873/*
2874 Copyright (c) jQuery Foundation, Inc. and Contributors, All Rights Reserved.
2875
2876 Redistribution and use in source and binary forms, with or without
2877 modification, are permitted provided that the following conditions are met:
2878
2879 * Redistributions of source code must retain the above copyright
2880 notice, this list of conditions and the following disclaimer.
2881 * Redistributions in binary form must reproduce the above copyright
2882 notice, this list of conditions and the following disclaimer in the
2883 documentation and/or other materials provided with the distribution.
2884
2885 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
2886 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2887 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2888 ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
2889 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
2890 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
2891 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
2892 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2893 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2894 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2895*/
2896
2897(function (root, factory) {
2898 'use strict';
2899
2900 // Universal Module Definition (UMD) to support AMD, CommonJS/Node.js,
2901 // Rhino, and plain browser loading.
2902
2903 /* istanbul ignore next */
2904 if (typeof define === 'function' && define.amd) {
2905 define(['exports'], factory);
2906 } else if (typeof exports !== 'undefined') {
2907 factory(exports);
2908 } else {
2909 factory((root.esprima = {}));
2910 }
2911}(this, function (exports) {
2912 'use strict';
2913
2914 var Token,
2915 TokenName,
2916 FnExprTokens,
2917 Syntax,
2918 PlaceHolders,
2919 Messages,
2920 Regex,
2921 source,
2922 strict,
2923 index,
2924 lineNumber,
2925 lineStart,
2926 hasLineTerminator,
2927 lastIndex,
2928 lastLineNumber,
2929 lastLineStart,
2930 startIndex,
2931 startLineNumber,
2932 startLineStart,
2933 scanning,
2934 length,
2935 lookahead,
2936 state,
2937 extra,
2938 isBindingElement,
2939 isAssignmentTarget,
2940 firstCoverInitializedNameError;
2941
2942 Token = {
2943 BooleanLiteral: 1,
2944 EOF: 2,
2945 Identifier: 3,
2946 Keyword: 4,
2947 NullLiteral: 5,
2948 NumericLiteral: 6,
2949 Punctuator: 7,
2950 StringLiteral: 8,
2951 RegularExpression: 9,
2952 Template: 10
2953 };
2954
2955 TokenName = {};
2956 TokenName[Token.BooleanLiteral] = 'Boolean';
2957 TokenName[Token.EOF] = '<end>';
2958 TokenName[Token.Identifier] = 'Identifier';
2959 TokenName[Token.Keyword] = 'Keyword';
2960 TokenName[Token.NullLiteral] = 'Null';
2961 TokenName[Token.NumericLiteral] = 'Numeric';
2962 TokenName[Token.Punctuator] = 'Punctuator';
2963 TokenName[Token.StringLiteral] = 'String';
2964 TokenName[Token.RegularExpression] = 'RegularExpression';
2965 TokenName[Token.Template] = 'Template';
2966
2967 // A function following one of those tokens is an expression.
2968 FnExprTokens = ['(', '{', '[', 'in', 'typeof', 'instanceof', 'new',
2969 'return', 'case', 'delete', 'throw', 'void',
2970 // assignment operators
2971 '=', '+=', '-=', '*=', '/=', '%=', '<<=', '>>=', '>>>=',
2972 '&=', '|=', '^=', ',',
2973 // binary/unary operators
2974 '+', '-', '*', '/', '%', '++', '--', '<<', '>>', '>>>', '&',
2975 '|', '^', '!', '~', '&&', '||', '?', ':', '===', '==', '>=',
2976 '<=', '<', '>', '!=', '!=='];
2977
2978 Syntax = {
2979 AssignmentExpression: 'AssignmentExpression',
2980 AssignmentPattern: 'AssignmentPattern',
2981 ArrayExpression: 'ArrayExpression',
2982 ArrayPattern: 'ArrayPattern',
2983 ArrowFunctionExpression: 'ArrowFunctionExpression',
2984 BlockStatement: 'BlockStatement',
2985 BinaryExpression: 'BinaryExpression',
2986 BreakStatement: 'BreakStatement',
2987 CallExpression: 'CallExpression',
2988 CatchClause: 'CatchClause',
2989 ClassBody: 'ClassBody',
2990 ClassDeclaration: 'ClassDeclaration',
2991 ClassExpression: 'ClassExpression',
2992 ConditionalExpression: 'ConditionalExpression',
2993 ContinueStatement: 'ContinueStatement',
2994 DoWhileStatement: 'DoWhileStatement',
2995 DebuggerStatement: 'DebuggerStatement',
2996 EmptyStatement: 'EmptyStatement',
2997 ExportAllDeclaration: 'ExportAllDeclaration',
2998 ExportDefaultDeclaration: 'ExportDefaultDeclaration',
2999 ExportNamedDeclaration: 'ExportNamedDeclaration',
3000 ExportSpecifier: 'ExportSpecifier',
3001 ExpressionStatement: 'ExpressionStatement',
3002 ForStatement: 'ForStatement',
3003 ForOfStatement: 'ForOfStatement',
3004 ForInStatement: 'ForInStatement',
3005 FunctionDeclaration: 'FunctionDeclaration',
3006 FunctionExpression: 'FunctionExpression',
3007 Identifier: 'Identifier',
3008 IfStatement: 'IfStatement',
3009 ImportDeclaration: 'ImportDeclaration',
3010 ImportDefaultSpecifier: 'ImportDefaultSpecifier',
3011 ImportNamespaceSpecifier: 'ImportNamespaceSpecifier',
3012 ImportSpecifier: 'ImportSpecifier',
3013 Literal: 'Literal',
3014 LabeledStatement: 'LabeledStatement',
3015 LogicalExpression: 'LogicalExpression',
3016 MemberExpression: 'MemberExpression',
3017 MetaProperty: 'MetaProperty',
3018 MethodDefinition: 'MethodDefinition',
3019 NewExpression: 'NewExpression',
3020 ObjectExpression: 'ObjectExpression',
3021 ObjectPattern: 'ObjectPattern',
3022 Program: 'Program',
3023 Property: 'Property',
3024 RestElement: 'RestElement',
3025 ReturnStatement: 'ReturnStatement',
3026 SequenceExpression: 'SequenceExpression',
3027 SpreadElement: 'SpreadElement',
3028 Super: 'Super',
3029 SwitchCase: 'SwitchCase',
3030 SwitchStatement: 'SwitchStatement',
3031 TaggedTemplateExpression: 'TaggedTemplateExpression',
3032 TemplateElement: 'TemplateElement',
3033 TemplateLiteral: 'TemplateLiteral',
3034 ThisExpression: 'ThisExpression',
3035 ThrowStatement: 'ThrowStatement',
3036 TryStatement: 'TryStatement',
3037 UnaryExpression: 'UnaryExpression',
3038 UpdateExpression: 'UpdateExpression',
3039 VariableDeclaration: 'VariableDeclaration',
3040 VariableDeclarator: 'VariableDeclarator',
3041 WhileStatement: 'WhileStatement',
3042 WithStatement: 'WithStatement',
3043 YieldExpression: 'YieldExpression'
3044 };
3045
3046 PlaceHolders = {
3047 ArrowParameterPlaceHolder: 'ArrowParameterPlaceHolder'
3048 };
3049
3050 // Error messages should be identical to V8.
3051 Messages = {
3052 UnexpectedToken: 'Unexpected token %0',
3053 UnexpectedNumber: 'Unexpected number',
3054 UnexpectedString: 'Unexpected string',
3055 UnexpectedIdentifier: 'Unexpected identifier',
3056 UnexpectedReserved: 'Unexpected reserved word',
3057 UnexpectedTemplate: 'Unexpected quasi %0',
3058 UnexpectedEOS: 'Unexpected end of input',
3059 NewlineAfterThrow: 'Illegal newline after throw',
3060 InvalidRegExp: 'Invalid regular expression',
3061 UnterminatedRegExp: 'Invalid regular expression: missing /',
3062 InvalidLHSInAssignment: 'Invalid left-hand side in assignment',
3063 InvalidLHSInForIn: 'Invalid left-hand side in for-in',
3064 InvalidLHSInForLoop: 'Invalid left-hand side in for-loop',
3065 MultipleDefaultsInSwitch: 'More than one default clause in switch statement',
3066 NoCatchOrFinally: 'Missing catch or finally after try',
3067 UnknownLabel: 'Undefined label \'%0\'',
3068 Redeclaration: '%0 \'%1\' has already been declared',
3069 IllegalContinue: 'Illegal continue statement',
3070 IllegalBreak: 'Illegal break statement',
3071 IllegalReturn: 'Illegal return statement',
3072 StrictModeWith: 'Strict mode code may not include a with statement',
3073 StrictCatchVariable: 'Catch variable may not be eval or arguments in strict mode',
3074 StrictVarName: 'Variable name may not be eval or arguments in strict mode',
3075 StrictParamName: 'Parameter name eval or arguments is not allowed in strict mode',
3076 StrictParamDupe: 'Strict mode function may not have duplicate parameter names',
3077 StrictFunctionName: 'Function name may not be eval or arguments in strict mode',
3078 StrictOctalLiteral: 'Octal literals are not allowed in strict mode.',
3079 StrictDelete: 'Delete of an unqualified identifier in strict mode.',
3080 StrictLHSAssignment: 'Assignment to eval or arguments is not allowed in strict mode',
3081 StrictLHSPostfix: 'Postfix increment/decrement may not have eval or arguments operand in strict mode',
3082 StrictLHSPrefix: 'Prefix increment/decrement may not have eval or arguments operand in strict mode',
3083 StrictReservedWord: 'Use of future reserved word in strict mode',
3084 TemplateOctalLiteral: 'Octal literals are not allowed in template strings.',
3085 ParameterAfterRestParameter: 'Rest parameter must be last formal parameter',
3086 DefaultRestParameter: 'Unexpected token =',
3087 ObjectPatternAsRestParameter: 'Unexpected token {',
3088 DuplicateProtoProperty: 'Duplicate __proto__ fields are not allowed in object literals',
3089 ConstructorSpecialMethod: 'Class constructor may not be an accessor',
3090 DuplicateConstructor: 'A class may only have one constructor',
3091 StaticPrototype: 'Classes may not have static property named prototype',
3092 MissingFromClause: 'Unexpected token',
3093 NoAsAfterImportNamespace: 'Unexpected token',
3094 InvalidModuleSpecifier: 'Unexpected token',
3095 IllegalImportDeclaration: 'Unexpected token',
3096 IllegalExportDeclaration: 'Unexpected token',
3097 DuplicateBinding: 'Duplicate binding %0'
3098 };
3099
3100 // See also tools/generate-unicode-regex.js.
3101 Regex = {
3102 // ECMAScript 6/Unicode v7.0.0 NonAsciiIdentifierStart:
3103 NonAsciiIdentifierStart: /[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0-\u08B2\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2118-\u211D\u2124\u2126\u2128\u212A-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309B-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA7AD\uA7B0\uA7B1\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB5F\uAB64\uAB65\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1F\uDF30-\uDF4A\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE4\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48]|\uD804[\uDC03-\uDC37\uDC83-\uDCAF\uDCD0-\uDCE8\uDD03-\uDD26\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDDA\uDE00-\uDE11\uDE13-\uDE2B\uDEB0-\uDEDE\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF5D-\uDF61]|\uD805[\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDD80-\uDDAE\uDE00-\uDE2F\uDE44\uDE80-\uDEAA]|\uD806[\uDCA0-\uDCDF\uDCFF\uDEC0-\uDEF8]|\uD808[\uDC00-\uDF98]|\uD809[\uDC00-\uDC6E]|[\uD80C\uD840-\uD868\uD86A-\uD86C][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50\uDF93-\uDF9F]|\uD82C[\uDC00\uDC01]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB]|\uD83A[\uDC00-\uDCC4]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D]|\uD87E[\uDC00-\uDE1D]/,
3104
3105 // ECMAScript 6/Unicode v7.0.0 NonAsciiIdentifierPart:
3106 NonAsciiIdentifierPart: /[\xAA\xB5\xB7\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u05D0-\u05EA\u05F0-\u05F2\u0610-\u061A\u0620-\u0669\u066E-\u06D3\u06D5-\u06DC\u06DF-\u06E8\u06EA-\u06FC\u06FF\u0710-\u074A\u074D-\u07B1\u07C0-\u07F5\u07FA\u0800-\u082D\u0840-\u085B\u08A0-\u08B2\u08E4-\u0963\u0966-\u096F\u0971-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BC-\u09C4\u09C7\u09C8\u09CB-\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09E6-\u09F1\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A59-\u0A5C\u0A5E\u0A66-\u0A75\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABC-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AD0\u0AE0-\u0AE3\u0AE6-\u0AEF\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3C-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B66-\u0B6F\u0B71\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD0\u0BD7\u0BE6-\u0BEF\u0C00-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58\u0C59\u0C60-\u0C63\u0C66-\u0C6F\u0C81-\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBC-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CDE\u0CE0-\u0CE3\u0CE6-\u0CEF\u0CF1\u0CF2\u0D01-\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D-\u0D44\u0D46-\u0D48\u0D4A-\u0D4E\u0D57\u0D60-\u0D63\u0D66-\u0D6F\u0D7A-\u0D7F\u0D82\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DE6-\u0DEF\u0DF2\u0DF3\u0E01-\u0E3A\u0E40-\u0E4E\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB9\u0EBB-\u0EBD\u0EC0-\u0EC4\u0EC6\u0EC8-\u0ECD\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E-\u0F47\u0F49-\u0F6C\u0F71-\u0F84\u0F86-\u0F97\u0F99-\u0FBC\u0FC6\u1000-\u1049\u1050-\u109D\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u135D-\u135F\u1369-\u1371\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176C\u176E-\u1770\u1772\u1773\u1780-\u17D3\u17D7\u17DC\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u1820-\u1877\u1880-\u18AA\u18B0-\u18F5\u1900-\u191E\u1920-\u192B\u1930-\u193B\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19DA\u1A00-\u1A1B\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA7\u1AB0-\u1ABD\u1B00-\u1B4B\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1BF3\u1C00-\u1C37\u1C40-\u1C49\u1C4D-\u1C7D\u1CD0-\u1CD2\u1CD4-\u1CF6\u1CF8\u1CF9\u1D00-\u1DF5\u1DFC-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u200C\u200D\u203F\u2040\u2054\u2071\u207F\u2090-\u209C\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2102\u2107\u210A-\u2113\u2115\u2118-\u211D\u2124\u2126\u2128\u212A-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D7F-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2DE0-\u2DFF\u3005-\u3007\u3021-\u302F\u3031-\u3035\u3038-\u303C\u3041-\u3096\u3099-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66F\uA674-\uA67D\uA67F-\uA69D\uA69F-\uA6F1\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA7AD\uA7B0\uA7B1\uA7F7-\uA827\uA840-\uA873\uA880-\uA8C4\uA8D0-\uA8D9\uA8E0-\uA8F7\uA8FB\uA900-\uA92D\uA930-\uA953\uA960-\uA97C\uA980-\uA9C0\uA9CF-\uA9D9\uA9E0-\uA9FE\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA60-\uAA76\uAA7A-\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF6\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB5F\uAB64\uAB65\uABC0-\uABEA\uABEC\uABED\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE00-\uFE0F\uFE20-\uFE2D\uFE33\uFE34\uFE4D-\uFE4F\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF3F\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDDFD\uDE80-\uDE9C\uDEA0-\uDED0\uDEE0\uDF00-\uDF1F\uDF30-\uDF4A\uDF50-\uDF7A\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCA0-\uDCA9\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00-\uDE03\uDE05\uDE06\uDE0C-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE38-\uDE3A\uDE3F\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE6\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48]|\uD804[\uDC00-\uDC46\uDC66-\uDC6F\uDC7F-\uDCBA\uDCD0-\uDCE8\uDCF0-\uDCF9\uDD00-\uDD34\uDD36-\uDD3F\uDD50-\uDD73\uDD76\uDD80-\uDDC4\uDDD0-\uDDDA\uDE00-\uDE11\uDE13-\uDE37\uDEB0-\uDEEA\uDEF0-\uDEF9\uDF01-\uDF03\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3C-\uDF44\uDF47\uDF48\uDF4B-\uDF4D\uDF57\uDF5D-\uDF63\uDF66-\uDF6C\uDF70-\uDF74]|\uD805[\uDC80-\uDCC5\uDCC7\uDCD0-\uDCD9\uDD80-\uDDB5\uDDB8-\uDDC0\uDE00-\uDE40\uDE44\uDE50-\uDE59\uDE80-\uDEB7\uDEC0-\uDEC9]|\uD806[\uDCA0-\uDCE9\uDCFF\uDEC0-\uDEF8]|\uD808[\uDC00-\uDF98]|\uD809[\uDC00-\uDC6E]|[\uD80C\uD840-\uD868\uD86A-\uD86C][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE60-\uDE69\uDED0-\uDEED\uDEF0-\uDEF4\uDF00-\uDF36\uDF40-\uDF43\uDF50-\uDF59\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50-\uDF7E\uDF8F-\uDF9F]|\uD82C[\uDC00\uDC01]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99\uDC9D\uDC9E]|\uD834[\uDD65-\uDD69\uDD6D-\uDD72\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB\uDFCE-\uDFFF]|\uD83A[\uDC00-\uDCC4\uDCD0-\uDCD6]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D]|\uD87E[\uDC00-\uDE1D]|\uDB40[\uDD00-\uDDEF]/
3107 };
3108
3109 // Ensure the condition is true, otherwise throw an error.
3110 // This is only to have a better contract semantic, i.e. another safety net
3111 // to catch a logic error. The condition shall be fulfilled in normal case.
3112 // Do NOT use this to enforce a certain condition on any user input.
3113
3114 function assert(condition, message) {
3115 /* istanbul ignore if */
3116 if (!condition) {
3117 throw new Error('ASSERT: ' + message);
3118 }
3119 }
3120
3121 function isDecimalDigit(ch) {
3122 return (ch >= 0x30 && ch <= 0x39); // 0..9
3123 }
3124
3125 function isHexDigit(ch) {
3126 return '0123456789abcdefABCDEF'.indexOf(ch) >= 0;
3127 }
3128
3129 function isOctalDigit(ch) {
3130 return '01234567'.indexOf(ch) >= 0;
3131 }
3132
3133 function octalToDecimal(ch) {
3134 // \0 is not octal escape sequence
3135 var octal = (ch !== '0'), code = '01234567'.indexOf(ch);
3136
3137 if (index < length && isOctalDigit(source[index])) {
3138 octal = true;
3139 code = code * 8 + '01234567'.indexOf(source[index++]);
3140
3141 // 3 digits are only allowed when string starts
3142 // with 0, 1, 2, 3
3143 if ('0123'.indexOf(ch) >= 0 &&
3144 index < length &&
3145 isOctalDigit(source[index])) {
3146 code = code * 8 + '01234567'.indexOf(source[index++]);
3147 }
3148 }
3149
3150 return {
3151 code: code,
3152 octal: octal
3153 };
3154 }
3155
3156 // ECMA-262 11.2 White Space
3157
3158 function isWhiteSpace(ch) {
3159 return (ch === 0x20) || (ch === 0x09) || (ch === 0x0B) || (ch === 0x0C) || (ch === 0xA0) ||
3160 (ch >= 0x1680 && [0x1680, 0x180E, 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006, 0x2007, 0x2008, 0x2009, 0x200A, 0x202F, 0x205F, 0x3000, 0xFEFF].indexOf(ch) >= 0);
3161 }
3162
3163 // ECMA-262 11.3 Line Terminators
3164
3165 function isLineTerminator(ch) {
3166 return (ch === 0x0A) || (ch === 0x0D) || (ch === 0x2028) || (ch === 0x2029);
3167 }
3168
3169 // ECMA-262 11.6 Identifier Names and Identifiers
3170
3171 function fromCodePoint(cp) {
3172 return (cp < 0x10000) ? String.fromCharCode(cp) :
3173 String.fromCharCode(0xD800 + ((cp - 0x10000) >> 10)) +
3174 String.fromCharCode(0xDC00 + ((cp - 0x10000) & 1023));
3175 }
3176
3177 function isIdentifierStart(ch) {
3178 return (ch === 0x24) || (ch === 0x5F) || // $ (dollar) and _ (underscore)
3179 (ch >= 0x41 && ch <= 0x5A) || // A..Z
3180 (ch >= 0x61 && ch <= 0x7A) || // a..z
3181 (ch === 0x5C) || // \ (backslash)
3182 ((ch >= 0x80) && Regex.NonAsciiIdentifierStart.test(fromCodePoint(ch)));
3183 }
3184
3185 function isIdentifierPart(ch) {
3186 return (ch === 0x24) || (ch === 0x5F) || // $ (dollar) and _ (underscore)
3187 (ch >= 0x41 && ch <= 0x5A) || // A..Z
3188 (ch >= 0x61 && ch <= 0x7A) || // a..z
3189 (ch >= 0x30 && ch <= 0x39) || // 0..9
3190 (ch === 0x5C) || // \ (backslash)
3191 ((ch >= 0x80) && Regex.NonAsciiIdentifierPart.test(fromCodePoint(ch)));
3192 }
3193
3194 // ECMA-262 11.6.2.2 Future Reserved Words
3195
3196 function isFutureReservedWord(id) {
3197 switch (id) {
3198 case 'enum':
3199 case 'export':
3200 case 'import':
3201 case 'super':
3202 return true;
3203 default:
3204 return false;
3205 }
3206 }
3207
3208 function isStrictModeReservedWord(id) {
3209 switch (id) {
3210 case 'implements':
3211 case 'interface':
3212 case 'package':
3213 case 'private':
3214 case 'protected':
3215 case 'public':
3216 case 'static':
3217 case 'yield':
3218 case 'let':
3219 return true;
3220 default:
3221 return false;
3222 }
3223 }
3224
3225 function isRestrictedWord(id) {
3226 return id === 'eval' || id === 'arguments';
3227 }
3228
3229 // ECMA-262 11.6.2.1 Keywords
3230
3231 function isKeyword(id) {
3232
3233 // 'const' is specialized as Keyword in V8.
3234 // 'yield' and 'let' are for compatibility with SpiderMonkey and ES.next.
3235 // Some others are from future reserved words.
3236
3237 switch (id.length) {
3238 case 2:
3239 return (id === 'if') || (id === 'in') || (id === 'do');
3240 case 3:
3241 return (id === 'var') || (id === 'for') || (id === 'new') ||
3242 (id === 'try') || (id === 'let');
3243 case 4:
3244 return (id === 'this') || (id === 'else') || (id === 'case') ||
3245 (id === 'void') || (id === 'with') || (id === 'enum');
3246 case 5:
3247 return (id === 'while') || (id === 'break') || (id === 'catch') ||
3248 (id === 'throw') || (id === 'const') || (id === 'yield') ||
3249 (id === 'class') || (id === 'super');
3250 case 6:
3251 return (id === 'return') || (id === 'typeof') || (id === 'delete') ||
3252 (id === 'switch') || (id === 'export') || (id === 'import');
3253 case 7:
3254 return (id === 'default') || (id === 'finally') || (id === 'extends');
3255 case 8:
3256 return (id === 'function') || (id === 'continue') || (id === 'debugger');
3257 case 10:
3258 return (id === 'instanceof');
3259 default:
3260 return false;
3261 }
3262 }
3263
3264 // ECMA-262 11.4 Comments
3265
3266 function addComment(type, value, start, end, loc) {
3267 var comment;
3268
3269 assert(typeof start === 'number', 'Comment must have valid position');
3270
3271 state.lastCommentStart = start;
3272
3273 comment = {
3274 type: type,
3275 value: value
3276 };
3277 if (extra.range) {
3278 comment.range = [start, end];
3279 }
3280 if (extra.loc) {
3281 comment.loc = loc;
3282 }
3283 extra.comments.push(comment);
3284 if (extra.attachComment) {
3285 extra.leadingComments.push(comment);
3286 extra.trailingComments.push(comment);
3287 }
3288 }
3289
3290 function skipSingleLineComment(offset) {
3291 var start, loc, ch, comment;
3292
3293 start = index - offset;
3294 loc = {
3295 start: {
3296 line: lineNumber,
3297 column: index - lineStart - offset
3298 }
3299 };
3300
3301 while (index < length) {
3302 ch = source.charCodeAt(index);
3303 ++index;
3304 if (isLineTerminator(ch)) {
3305 hasLineTerminator = true;
3306 if (extra.comments) {
3307 comment = source.slice(start + offset, index - 1);
3308 loc.end = {
3309 line: lineNumber,
3310 column: index - lineStart - 1
3311 };
3312 addComment('Line', comment, start, index - 1, loc);
3313 }
3314 if (ch === 13 && source.charCodeAt(index) === 10) {
3315 ++index;
3316 }
3317 ++lineNumber;
3318 lineStart = index;
3319 return;
3320 }
3321 }
3322
3323 if (extra.comments) {
3324 comment = source.slice(start + offset, index);
3325 loc.end = {
3326 line: lineNumber,
3327 column: index - lineStart
3328 };
3329 addComment('Line', comment, start, index, loc);
3330 }
3331 }
3332
3333 function skipMultiLineComment() {
3334 var start, loc, ch, comment;
3335
3336 if (extra.comments) {
3337 start = index - 2;
3338 loc = {
3339 start: {
3340 line: lineNumber,
3341 column: index - lineStart - 2
3342 }
3343 };
3344 }
3345
3346 while (index < length) {
3347 ch = source.charCodeAt(index);
3348 if (isLineTerminator(ch)) {
3349 if (ch === 0x0D && source.charCodeAt(index + 1) === 0x0A) {
3350 ++index;
3351 }
3352 hasLineTerminator = true;
3353 ++lineNumber;
3354 ++index;
3355 lineStart = index;
3356 } else if (ch === 0x2A) {
3357 // Block comment ends with '*/'.
3358 if (source.charCodeAt(index + 1) === 0x2F) {
3359 ++index;
3360 ++index;
3361 if (extra.comments) {
3362 comment = source.slice(start + 2, index - 2);
3363 loc.end = {
3364 line: lineNumber,
3365 column: index - lineStart
3366 };
3367 addComment('Block', comment, start, index, loc);
3368 }
3369 return;
3370 }
3371 ++index;
3372 } else {
3373 ++index;
3374 }
3375 }
3376
3377 // Ran off the end of the file - the whole thing is a comment
3378 if (extra.comments) {
3379 loc.end = {
3380 line: lineNumber,
3381 column: index - lineStart
3382 };
3383 comment = source.slice(start + 2, index);
3384 addComment('Block', comment, start, index, loc);
3385 }
3386 tolerateUnexpectedToken();
3387 }
3388
3389 function skipComment() {
3390 var ch, start;
3391 hasLineTerminator = false;
3392
3393 start = (index === 0);
3394 while (index < length) {
3395 ch = source.charCodeAt(index);
3396
3397 if (isWhiteSpace(ch)) {
3398 ++index;
3399 } else if (isLineTerminator(ch)) {
3400 hasLineTerminator = true;
3401 ++index;
3402 if (ch === 0x0D && source.charCodeAt(index) === 0x0A) {
3403 ++index;
3404 }
3405 ++lineNumber;
3406 lineStart = index;
3407 start = true;
3408 } else if (ch === 0x2F) { // U+002F is '/'
3409 ch = source.charCodeAt(index + 1);
3410 if (ch === 0x2F) {
3411 ++index;
3412 ++index;
3413 skipSingleLineComment(2);
3414 start = true;
3415 } else if (ch === 0x2A) { // U+002A is '*'
3416 ++index;
3417 ++index;
3418 skipMultiLineComment();
3419 } else {
3420 break;
3421 }
3422 } else if (start && ch === 0x2D) { // U+002D is '-'
3423 // U+003E is '>'
3424 if ((source.charCodeAt(index + 1) === 0x2D) && (source.charCodeAt(index + 2) === 0x3E)) {
3425 // '-->' is a single-line comment
3426 index += 3;
3427 skipSingleLineComment(3);
3428 } else {
3429 break;
3430 }
3431 } else if (ch === 0x3C) { // U+003C is '<'
3432 if (source.slice(index + 1, index + 4) === '!--') {
3433 ++index; // `<`
3434 ++index; // `!`
3435 ++index; // `-`
3436 ++index; // `-`
3437 skipSingleLineComment(4);
3438 } else {
3439 break;
3440 }
3441 } else {
3442 break;
3443 }
3444 }
3445 }
3446
3447 function scanHexEscape(prefix) {
3448 var i, len, ch, code = 0;
3449
3450 len = (prefix === 'u') ? 4 : 2;
3451 for (i = 0; i < len; ++i) {
3452 if (index < length && isHexDigit(source[index])) {
3453 ch = source[index++];
3454 code = code * 16 + '0123456789abcdef'.indexOf(ch.toLowerCase());
3455 } else {
3456 return '';
3457 }
3458 }
3459 return String.fromCharCode(code);
3460 }
3461
3462 function scanUnicodeCodePointEscape() {
3463 var ch, code;
3464
3465 ch = source[index];
3466 code = 0;
3467
3468 // At least, one hex digit is required.
3469 if (ch === '}') {
3470 throwUnexpectedToken();
3471 }
3472
3473 while (index < length) {
3474 ch = source[index++];
3475 if (!isHexDigit(ch)) {
3476 break;
3477 }
3478 code = code * 16 + '0123456789abcdef'.indexOf(ch.toLowerCase());
3479 }
3480
3481 if (code > 0x10FFFF || ch !== '}') {
3482 throwUnexpectedToken();
3483 }
3484
3485 return fromCodePoint(code);
3486 }
3487
3488 function codePointAt(i) {
3489 var cp, first, second;
3490
3491 cp = source.charCodeAt(i);
3492 if (cp >= 0xD800 && cp <= 0xDBFF) {
3493 second = source.charCodeAt(i + 1);
3494 if (second >= 0xDC00 && second <= 0xDFFF) {
3495 first = cp;
3496 cp = (first - 0xD800) * 0x400 + second - 0xDC00 + 0x10000;
3497 }
3498 }
3499
3500 return cp;
3501 }
3502
3503 function getComplexIdentifier() {
3504 var cp, ch, id;
3505
3506 cp = codePointAt(index);
3507 id = fromCodePoint(cp);
3508 index += id.length;
3509
3510 // '\u' (U+005C, U+0075) denotes an escaped character.
3511 if (cp === 0x5C) {
3512 if (source.charCodeAt(index) !== 0x75) {
3513 throwUnexpectedToken();
3514 }
3515 ++index;
3516 if (source[index] === '{') {
3517 ++index;
3518 ch = scanUnicodeCodePointEscape();
3519 } else {
3520 ch = scanHexEscape('u');
3521 cp = ch.charCodeAt(0);
3522 if (!ch || ch === '\\' || !isIdentifierStart(cp)) {
3523 throwUnexpectedToken();
3524 }
3525 }
3526 id = ch;
3527 }
3528
3529 while (index < length) {
3530 cp = codePointAt(index);
3531 if (!isIdentifierPart(cp)) {
3532 break;
3533 }
3534 ch = fromCodePoint(cp);
3535 id += ch;
3536 index += ch.length;
3537
3538 // '\u' (U+005C, U+0075) denotes an escaped character.
3539 if (cp === 0x5C) {
3540 id = id.substr(0, id.length - 1);
3541 if (source.charCodeAt(index) !== 0x75) {
3542 throwUnexpectedToken();
3543 }
3544 ++index;
3545 if (source[index] === '{') {
3546 ++index;
3547 ch = scanUnicodeCodePointEscape();
3548 } else {
3549 ch = scanHexEscape('u');
3550 cp = ch.charCodeAt(0);
3551 if (!ch || ch === '\\' || !isIdentifierPart(cp)) {
3552 throwUnexpectedToken();
3553 }
3554 }
3555 id += ch;
3556 }
3557 }
3558
3559 return id;
3560 }
3561
3562 function getIdentifier() {
3563 var start, ch;
3564
3565 start = index++;
3566 while (index < length) {
3567 ch = source.charCodeAt(index);
3568 if (ch === 0x5C) {
3569 // Blackslash (U+005C) marks Unicode escape sequence.
3570 index = start;
3571 return getComplexIdentifier();
3572 } else if (ch >= 0xD800 && ch < 0xDFFF) {
3573 // Need to handle surrogate pairs.
3574 index = start;
3575 return getComplexIdentifier();
3576 }
3577 if (isIdentifierPart(ch)) {
3578 ++index;
3579 } else {
3580 break;
3581 }
3582 }
3583
3584 return source.slice(start, index);
3585 }
3586
3587 function scanIdentifier() {
3588 var start, id, type;
3589
3590 start = index;
3591
3592 // Backslash (U+005C) starts an escaped character.
3593 id = (source.charCodeAt(index) === 0x5C) ? getComplexIdentifier() : getIdentifier();
3594
3595 // There is no keyword or literal with only one character.
3596 // Thus, it must be an identifier.
3597 if (id.length === 1) {
3598 type = Token.Identifier;
3599 } else if (isKeyword(id)) {
3600 type = Token.Keyword;
3601 } else if (id === 'null') {
3602 type = Token.NullLiteral;
3603 } else if (id === 'true' || id === 'false') {
3604 type = Token.BooleanLiteral;
3605 } else {
3606 type = Token.Identifier;
3607 }
3608
3609 return {
3610 type: type,
3611 value: id,
3612 lineNumber: lineNumber,
3613 lineStart: lineStart,
3614 start: start,
3615 end: index
3616 };
3617 }
3618
3619
3620 // ECMA-262 11.7 Punctuators
3621
3622 function scanPunctuator() {
3623 var token, str;
3624
3625 token = {
3626 type: Token.Punctuator,
3627 value: '',
3628 lineNumber: lineNumber,
3629 lineStart: lineStart,
3630 start: index,
3631 end: index
3632 };
3633
3634 // Check for most common single-character punctuators.
3635 str = source[index];
3636 switch (str) {
3637
3638 case '(':
3639 if (extra.tokenize) {
3640 extra.openParenToken = extra.tokens.length;
3641 }
3642 ++index;
3643 break;
3644
3645 case '{':
3646 if (extra.tokenize) {
3647 extra.openCurlyToken = extra.tokens.length;
3648 }
3649 state.curlyStack.push('{');
3650 ++index;
3651 break;
3652
3653 case '.':
3654 ++index;
3655 if (source[index] === '.' && source[index + 1] === '.') {
3656 // Spread operator: ...
3657 index += 2;
3658 str = '...';
3659 }
3660 break;
3661
3662 case '}':
3663 ++index;
3664 state.curlyStack.pop();
3665 break;
3666 case ')':
3667 case ';':
3668 case ',':
3669 case '[':
3670 case ']':
3671 case ':':
3672 case '?':
3673 case '~':
3674 ++index;
3675 break;
3676
3677 default:
3678 // 4-character punctuator.
3679 str = source.substr(index, 4);
3680 if (str === '>>>=') {
3681 index += 4;
3682 } else {
3683
3684 // 3-character punctuators.
3685 str = str.substr(0, 3);
3686 if (str === '===' || str === '!==' || str === '>>>' ||
3687 str === '<<=' || str === '>>=') {
3688 index += 3;
3689 } else {
3690
3691 // 2-character punctuators.
3692 str = str.substr(0, 2);
3693 if (str === '&&' || str === '||' || str === '==' || str === '!=' ||
3694 str === '+=' || str === '-=' || str === '*=' || str === '/=' ||
3695 str === '++' || str === '--' || str === '<<' || str === '>>' ||
3696 str === '&=' || str === '|=' || str === '^=' || str === '%=' ||
3697 str === '<=' || str === '>=' || str === '=>') {
3698 index += 2;
3699 } else {
3700
3701 // 1-character punctuators.
3702 str = source[index];
3703 if ('<>=!+-*%&|^/'.indexOf(str) >= 0) {
3704 ++index;
3705 }
3706 }
3707 }
3708 }
3709 }
3710
3711 if (index === token.start) {
3712 throwUnexpectedToken();
3713 }
3714
3715 token.end = index;
3716 token.value = str;
3717 return token;
3718 }
3719
3720 // ECMA-262 11.8.3 Numeric Literals
3721
3722 function scanHexLiteral(start) {
3723 var number = '';
3724
3725 while (index < length) {
3726 if (!isHexDigit(source[index])) {
3727 break;
3728 }
3729 number += source[index++];
3730 }
3731
3732 if (number.length === 0) {
3733 throwUnexpectedToken();
3734 }
3735
3736 if (isIdentifierStart(source.charCodeAt(index))) {
3737 throwUnexpectedToken();
3738 }
3739
3740 return {
3741 type: Token.NumericLiteral,
3742 value: parseInt('0x' + number, 16),
3743 lineNumber: lineNumber,
3744 lineStart: lineStart,
3745 start: start,
3746 end: index
3747 };
3748 }
3749
3750 function scanBinaryLiteral(start) {
3751 var ch, number;
3752
3753 number = '';
3754
3755 while (index < length) {
3756 ch = source[index];
3757 if (ch !== '0' && ch !== '1') {
3758 break;
3759 }
3760 number += source[index++];
3761 }
3762
3763 if (number.length === 0) {
3764 // only 0b or 0B
3765 throwUnexpectedToken();
3766 }
3767
3768 if (index < length) {
3769 ch = source.charCodeAt(index);
3770 /* istanbul ignore else */
3771 if (isIdentifierStart(ch) || isDecimalDigit(ch)) {
3772 throwUnexpectedToken();
3773 }
3774 }
3775
3776 return {
3777 type: Token.NumericLiteral,
3778 value: parseInt(number, 2),
3779 lineNumber: lineNumber,
3780 lineStart: lineStart,
3781 start: start,
3782 end: index
3783 };
3784 }
3785
3786 function scanOctalLiteral(prefix, start) {
3787 var number, octal;
3788
3789 if (isOctalDigit(prefix)) {
3790 octal = true;
3791 number = '0' + source[index++];
3792 } else {
3793 octal = false;
3794 ++index;
3795 number = '';
3796 }
3797
3798 while (index < length) {
3799 if (!isOctalDigit(source[index])) {
3800 break;
3801 }
3802 number += source[index++];
3803 }
3804
3805 if (!octal && number.length === 0) {
3806 // only 0o or 0O
3807 throwUnexpectedToken();
3808 }
3809
3810 if (isIdentifierStart(source.charCodeAt(index)) || isDecimalDigit(source.charCodeAt(index))) {
3811 throwUnexpectedToken();
3812 }
3813
3814 return {
3815 type: Token.NumericLiteral,
3816 value: parseInt(number, 8),
3817 octal: octal,
3818 lineNumber: lineNumber,
3819 lineStart: lineStart,
3820 start: start,
3821 end: index
3822 };
3823 }
3824
3825 function isImplicitOctalLiteral() {
3826 var i, ch;
3827
3828 // Implicit octal, unless there is a non-octal digit.
3829 // (Annex B.1.1 on Numeric Literals)
3830 for (i = index + 1; i < length; ++i) {
3831 ch = source[i];
3832 if (ch === '8' || ch === '9') {
3833 return false;
3834 }
3835 if (!isOctalDigit(ch)) {
3836 return true;
3837 }
3838 }
3839
3840 return true;
3841 }
3842
3843 function scanNumericLiteral() {
3844 var number, start, ch;
3845
3846 ch = source[index];
3847 assert(isDecimalDigit(ch.charCodeAt(0)) || (ch === '.'),
3848 'Numeric literal must start with a decimal digit or a decimal point');
3849
3850 start = index;
3851 number = '';
3852 if (ch !== '.') {
3853 number = source[index++];
3854 ch = source[index];
3855
3856 // Hex number starts with '0x'.
3857 // Octal number starts with '0'.
3858 // Octal number in ES6 starts with '0o'.
3859 // Binary number in ES6 starts with '0b'.
3860 if (number === '0') {
3861 if (ch === 'x' || ch === 'X') {
3862 ++index;
3863 return scanHexLiteral(start);
3864 }
3865 if (ch === 'b' || ch === 'B') {
3866 ++index;
3867 return scanBinaryLiteral(start);
3868 }
3869 if (ch === 'o' || ch === 'O') {
3870 return scanOctalLiteral(ch, start);
3871 }
3872
3873 if (isOctalDigit(ch)) {
3874 if (isImplicitOctalLiteral()) {
3875 return scanOctalLiteral(ch, start);
3876 }
3877 }
3878 }
3879
3880 while (isDecimalDigit(source.charCodeAt(index))) {
3881 number += source[index++];
3882 }
3883 ch = source[index];
3884 }
3885
3886 if (ch === '.') {
3887 number += source[index++];
3888 while (isDecimalDigit(source.charCodeAt(index))) {
3889 number += source[index++];
3890 }
3891 ch = source[index];
3892 }
3893
3894 if (ch === 'e' || ch === 'E') {
3895 number += source[index++];
3896
3897 ch = source[index];
3898 if (ch === '+' || ch === '-') {
3899 number += source[index++];
3900 }
3901 if (isDecimalDigit(source.charCodeAt(index))) {
3902 while (isDecimalDigit(source.charCodeAt(index))) {
3903 number += source[index++];
3904 }
3905 } else {
3906 throwUnexpectedToken();
3907 }
3908 }
3909
3910 if (isIdentifierStart(source.charCodeAt(index))) {
3911 throwUnexpectedToken();
3912 }
3913
3914 return {
3915 type: Token.NumericLiteral,
3916 value: parseFloat(number),
3917 lineNumber: lineNumber,
3918 lineStart: lineStart,
3919 start: start,
3920 end: index
3921 };
3922 }
3923
3924 // ECMA-262 11.8.4 String Literals
3925
3926 function scanStringLiteral() {
3927 var str = '', quote, start, ch, unescaped, octToDec, octal = false;
3928
3929 quote = source[index];
3930 assert((quote === '\'' || quote === '"'),
3931 'String literal must starts with a quote');
3932
3933 start = index;
3934 ++index;
3935
3936 while (index < length) {
3937 ch = source[index++];
3938
3939 if (ch === quote) {
3940 quote = '';
3941 break;
3942 } else if (ch === '\\') {
3943 ch = source[index++];
3944 if (!ch || !isLineTerminator(ch.charCodeAt(0))) {
3945 switch (ch) {
3946 case 'u':
3947 case 'x':
3948 if (source[index] === '{') {
3949 ++index;
3950 str += scanUnicodeCodePointEscape();
3951 } else {
3952 unescaped = scanHexEscape(ch);
3953 if (!unescaped) {
3954 throw throwUnexpectedToken();
3955 }
3956 str += unescaped;
3957 }
3958 break;
3959 case 'n':
3960 str += '\n';
3961 break;
3962 case 'r':
3963 str += '\r';
3964 break;
3965 case 't':
3966 str += '\t';
3967 break;
3968 case 'b':
3969 str += '\b';
3970 break;
3971 case 'f':
3972 str += '\f';
3973 break;
3974 case 'v':
3975 str += '\x0B';
3976 break;
3977 case '8':
3978 case '9':
3979 str += ch;
3980 tolerateUnexpectedToken();
3981 break;
3982
3983 default:
3984 if (isOctalDigit(ch)) {
3985 octToDec = octalToDecimal(ch);
3986
3987 octal = octToDec.octal || octal;
3988 str += String.fromCharCode(octToDec.code);
3989 } else {
3990 str += ch;
3991 }
3992 break;
3993 }
3994 } else {
3995 ++lineNumber;
3996 if (ch === '\r' && source[index] === '\n') {
3997 ++index;
3998 }
3999 lineStart = index;
4000 }
4001 } else if (isLineTerminator(ch.charCodeAt(0))) {
4002 break;
4003 } else {
4004 str += ch;
4005 }
4006 }
4007
4008 if (quote !== '') {
4009 throwUnexpectedToken();
4010 }
4011
4012 return {
4013 type: Token.StringLiteral,
4014 value: str,
4015 octal: octal,
4016 lineNumber: startLineNumber,
4017 lineStart: startLineStart,
4018 start: start,
4019 end: index
4020 };
4021 }
4022
4023 // ECMA-262 11.8.6 Template Literal Lexical Components
4024
4025 function scanTemplate() {
4026 var cooked = '', ch, start, rawOffset, terminated, head, tail, restore, unescaped;
4027
4028 terminated = false;
4029 tail = false;
4030 start = index;
4031 head = (source[index] === '`');
4032 rawOffset = 2;
4033
4034 ++index;
4035
4036 while (index < length) {
4037 ch = source[index++];
4038 if (ch === '`') {
4039 rawOffset = 1;
4040 tail = true;
4041 terminated = true;
4042 break;
4043 } else if (ch === '$') {
4044 if (source[index] === '{') {
4045 state.curlyStack.push('${');
4046 ++index;
4047 terminated = true;
4048 break;
4049 }
4050 cooked += ch;
4051 } else if (ch === '\\') {
4052 ch = source[index++];
4053 if (!isLineTerminator(ch.charCodeAt(0))) {
4054 switch (ch) {
4055 case 'n':
4056 cooked += '\n';
4057 break;
4058 case 'r':
4059 cooked += '\r';
4060 break;
4061 case 't':
4062 cooked += '\t';
4063 break;
4064 case 'u':
4065 case 'x':
4066 if (source[index] === '{') {
4067 ++index;
4068 cooked += scanUnicodeCodePointEscape();
4069 } else {
4070 restore = index;
4071 unescaped = scanHexEscape(ch);
4072 if (unescaped) {
4073 cooked += unescaped;
4074 } else {
4075 index = restore;
4076 cooked += ch;
4077 }
4078 }
4079 break;
4080 case 'b':
4081 cooked += '\b';
4082 break;
4083 case 'f':
4084 cooked += '\f';
4085 break;
4086 case 'v':
4087 cooked += '\v';
4088 break;
4089
4090 default:
4091 if (ch === '0') {
4092 if (isDecimalDigit(source.charCodeAt(index))) {
4093 // Illegal: \01 \02 and so on
4094 throwError(Messages.TemplateOctalLiteral);
4095 }
4096 cooked += '\0';
4097 } else if (isOctalDigit(ch)) {
4098 // Illegal: \1 \2
4099 throwError(Messages.TemplateOctalLiteral);
4100 } else {
4101 cooked += ch;
4102 }
4103 break;
4104 }
4105 } else {
4106 ++lineNumber;
4107 if (ch === '\r' && source[index] === '\n') {
4108 ++index;
4109 }
4110 lineStart = index;
4111 }
4112 } else if (isLineTerminator(ch.charCodeAt(0))) {
4113 ++lineNumber;
4114 if (ch === '\r' && source[index] === '\n') {
4115 ++index;
4116 }
4117 lineStart = index;
4118 cooked += '\n';
4119 } else {
4120 cooked += ch;
4121 }
4122 }
4123
4124 if (!terminated) {
4125 throwUnexpectedToken();
4126 }
4127
4128 if (!head) {
4129 state.curlyStack.pop();
4130 }
4131
4132 return {
4133 type: Token.Template,
4134 value: {
4135 cooked: cooked,
4136 raw: source.slice(start + 1, index - rawOffset)
4137 },
4138 head: head,
4139 tail: tail,
4140 lineNumber: lineNumber,
4141 lineStart: lineStart,
4142 start: start,
4143 end: index
4144 };
4145 }
4146
4147 // ECMA-262 11.8.5 Regular Expression Literals
4148
4149 function testRegExp(pattern, flags) {
4150 // The BMP character to use as a replacement for astral symbols when
4151 // translating an ES6 "u"-flagged pattern to an ES5-compatible
4152 // approximation.
4153 // Note: replacing with '\uFFFF' enables false positives in unlikely
4154 // scenarios. For example, `[\u{1044f}-\u{10440}]` is an invalid
4155 // pattern that would not be detected by this substitution.
4156 var astralSubstitute = '\uFFFF',
4157 tmp = pattern;
4158
4159 if (flags.indexOf('u') >= 0) {
4160 tmp = tmp
4161 // Replace every Unicode escape sequence with the equivalent
4162 // BMP character or a constant ASCII code point in the case of
4163 // astral symbols. (See the above note on `astralSubstitute`
4164 // for more information.)
4165 .replace(/\\u\{([0-9a-fA-F]+)\}|\\u([a-fA-F0-9]{4})/g, function ($0, $1, $2) {
4166 var codePoint = parseInt($1 || $2, 16);
4167 if (codePoint > 0x10FFFF) {
4168 throwUnexpectedToken(null, Messages.InvalidRegExp);
4169 }
4170 if (codePoint <= 0xFFFF) {
4171 return String.fromCharCode(codePoint);
4172 }
4173 return astralSubstitute;
4174 })
4175 // Replace each paired surrogate with a single ASCII symbol to
4176 // avoid throwing on regular expressions that are only valid in
4177 // combination with the "u" flag.
4178 .replace(
4179 /[\uD800-\uDBFF][\uDC00-\uDFFF]/g,
4180 astralSubstitute
4181 );
4182 }
4183
4184 // First, detect invalid regular expressions.
4185 try {
4186 RegExp(tmp);
4187 } catch (e) {
4188 throwUnexpectedToken(null, Messages.InvalidRegExp);
4189 }
4190
4191 // Return a regular expression object for this pattern-flag pair, or
4192 // `null` in case the current environment doesn't support the flags it
4193 // uses.
4194 try {
4195 return new RegExp(pattern, flags);
4196 } catch (exception) {
4197 return null;
4198 }
4199 }
4200
4201 function scanRegExpBody() {
4202 var ch, str, classMarker, terminated, body;
4203
4204 ch = source[index];
4205 assert(ch === '/', 'Regular expression literal must start with a slash');
4206 str = source[index++];
4207
4208 classMarker = false;
4209 terminated = false;
4210 while (index < length) {
4211 ch = source[index++];
4212 str += ch;
4213 if (ch === '\\') {
4214 ch = source[index++];
4215 // ECMA-262 7.8.5
4216 if (isLineTerminator(ch.charCodeAt(0))) {
4217 throwUnexpectedToken(null, Messages.UnterminatedRegExp);
4218 }
4219 str += ch;
4220 } else if (isLineTerminator(ch.charCodeAt(0))) {
4221 throwUnexpectedToken(null, Messages.UnterminatedRegExp);
4222 } else if (classMarker) {
4223 if (ch === ']') {
4224 classMarker = false;
4225 }
4226 } else {
4227 if (ch === '/') {
4228 terminated = true;
4229 break;
4230 } else if (ch === '[') {
4231 classMarker = true;
4232 }
4233 }
4234 }
4235
4236 if (!terminated) {
4237 throwUnexpectedToken(null, Messages.UnterminatedRegExp);
4238 }
4239
4240 // Exclude leading and trailing slash.
4241 body = str.substr(1, str.length - 2);
4242 return {
4243 value: body,
4244 literal: str
4245 };
4246 }
4247
4248 function scanRegExpFlags() {
4249 var ch, str, flags, restore;
4250
4251 str = '';
4252 flags = '';
4253 while (index < length) {
4254 ch = source[index];
4255 if (!isIdentifierPart(ch.charCodeAt(0))) {
4256 break;
4257 }
4258
4259 ++index;
4260 if (ch === '\\' && index < length) {
4261 ch = source[index];
4262 if (ch === 'u') {
4263 ++index;
4264 restore = index;
4265 ch = scanHexEscape('u');
4266 if (ch) {
4267 flags += ch;
4268 for (str += '\\u'; restore < index; ++restore) {
4269 str += source[restore];
4270 }
4271 } else {
4272 index = restore;
4273 flags += 'u';
4274 str += '\\u';
4275 }
4276 tolerateUnexpectedToken();
4277 } else {
4278 str += '\\';
4279 tolerateUnexpectedToken();
4280 }
4281 } else {
4282 flags += ch;
4283 str += ch;
4284 }
4285 }
4286
4287 return {
4288 value: flags,
4289 literal: str
4290 };
4291 }
4292
4293 function scanRegExp() {
4294 var start, body, flags, value;
4295 scanning = true;
4296
4297 lookahead = null;
4298 skipComment();
4299 start = index;
4300
4301 body = scanRegExpBody();
4302 flags = scanRegExpFlags();
4303 value = testRegExp(body.value, flags.value);
4304 scanning = false;
4305 if (extra.tokenize) {
4306 return {
4307 type: Token.RegularExpression,
4308 value: value,
4309 regex: {
4310 pattern: body.value,
4311 flags: flags.value
4312 },
4313 lineNumber: lineNumber,
4314 lineStart: lineStart,
4315 start: start,
4316 end: index
4317 };
4318 }
4319
4320 return {
4321 literal: body.literal + flags.literal,
4322 value: value,
4323 regex: {
4324 pattern: body.value,
4325 flags: flags.value
4326 },
4327 start: start,
4328 end: index
4329 };
4330 }
4331
4332 function collectRegex() {
4333 var pos, loc, regex, token;
4334
4335 skipComment();
4336
4337 pos = index;
4338 loc = {
4339 start: {
4340 line: lineNumber,
4341 column: index - lineStart
4342 }
4343 };
4344
4345 regex = scanRegExp();
4346
4347 loc.end = {
4348 line: lineNumber,
4349 column: index - lineStart
4350 };
4351
4352 /* istanbul ignore next */
4353 if (!extra.tokenize) {
4354 // Pop the previous token, which is likely '/' or '/='
4355 if (extra.tokens.length > 0) {
4356 token = extra.tokens[extra.tokens.length - 1];
4357 if (token.range[0] === pos && token.type === 'Punctuator') {
4358 if (token.value === '/' || token.value === '/=') {
4359 extra.tokens.pop();
4360 }
4361 }
4362 }
4363
4364 extra.tokens.push({
4365 type: 'RegularExpression',
4366 value: regex.literal,
4367 regex: regex.regex,
4368 range: [pos, index],
4369 loc: loc
4370 });
4371 }
4372
4373 return regex;
4374 }
4375
4376 function isIdentifierName(token) {
4377 return token.type === Token.Identifier ||
4378 token.type === Token.Keyword ||
4379 token.type === Token.BooleanLiteral ||
4380 token.type === Token.NullLiteral;
4381 }
4382
4383 function advanceSlash() {
4384 var prevToken,
4385 checkToken;
4386 // Using the following algorithm:
4387 // https://github.com/mozilla/sweet.js/wiki/design
4388 prevToken = extra.tokens[extra.tokens.length - 1];
4389 if (!prevToken) {
4390 // Nothing before that: it cannot be a division.
4391 return collectRegex();
4392 }
4393 if (prevToken.type === 'Punctuator') {
4394 if (prevToken.value === ']') {
4395 return scanPunctuator();
4396 }
4397 if (prevToken.value === ')') {
4398 checkToken = extra.tokens[extra.openParenToken - 1];
4399 if (checkToken &&
4400 checkToken.type === 'Keyword' &&
4401 (checkToken.value === 'if' ||
4402 checkToken.value === 'while' ||
4403 checkToken.value === 'for' ||
4404 checkToken.value === 'with')) {
4405 return collectRegex();
4406 }
4407 return scanPunctuator();
4408 }
4409 if (prevToken.value === '}') {
4410 // Dividing a function by anything makes little sense,
4411 // but we have to check for that.
4412 if (extra.tokens[extra.openCurlyToken - 3] &&
4413 extra.tokens[extra.openCurlyToken - 3].type === 'Keyword') {
4414 // Anonymous function.
4415 checkToken = extra.tokens[extra.openCurlyToken - 4];
4416 if (!checkToken) {
4417 return scanPunctuator();
4418 }
4419 } else if (extra.tokens[extra.openCurlyToken - 4] &&
4420 extra.tokens[extra.openCurlyToken - 4].type === 'Keyword') {
4421 // Named function.
4422 checkToken = extra.tokens[extra.openCurlyToken - 5];
4423 if (!checkToken) {
4424 return collectRegex();
4425 }
4426 } else {
4427 return scanPunctuator();
4428 }
4429 // checkToken determines whether the function is
4430 // a declaration or an expression.
4431 if (FnExprTokens.indexOf(checkToken.value) >= 0) {
4432 // It is an expression.
4433 return scanPunctuator();
4434 }
4435 // It is a declaration.
4436 return collectRegex();
4437 }
4438 return collectRegex();
4439 }
4440 if (prevToken.type === 'Keyword' && prevToken.value !== 'this') {
4441 return collectRegex();
4442 }
4443 return scanPunctuator();
4444 }
4445
4446 function advance() {
4447 var cp, token;
4448
4449 if (index >= length) {
4450 return {
4451 type: Token.EOF,
4452 lineNumber: lineNumber,
4453 lineStart: lineStart,
4454 start: index,
4455 end: index
4456 };
4457 }
4458
4459 cp = source.charCodeAt(index);
4460
4461 if (isIdentifierStart(cp)) {
4462 token = scanIdentifier();
4463 if (strict && isStrictModeReservedWord(token.value)) {
4464 token.type = Token.Keyword;
4465 }
4466 return token;
4467 }
4468
4469 // Very common: ( and ) and ;
4470 if (cp === 0x28 || cp === 0x29 || cp === 0x3B) {
4471 return scanPunctuator();
4472 }
4473
4474 // String literal starts with single quote (U+0027) or double quote (U+0022).
4475 if (cp === 0x27 || cp === 0x22) {
4476 return scanStringLiteral();
4477 }
4478
4479 // Dot (.) U+002E can also start a floating-point number, hence the need
4480 // to check the next character.
4481 if (cp === 0x2E) {
4482 if (isDecimalDigit(source.charCodeAt(index + 1))) {
4483 return scanNumericLiteral();
4484 }
4485 return scanPunctuator();
4486 }
4487
4488 if (isDecimalDigit(cp)) {
4489 return scanNumericLiteral();
4490 }
4491
4492 // Slash (/) U+002F can also start a regex.
4493 if (extra.tokenize && cp === 0x2F) {
4494 return advanceSlash();
4495 }
4496
4497 // Template literals start with ` (U+0060) for template head
4498 // or } (U+007D) for template middle or template tail.
4499 if (cp === 0x60 || (cp === 0x7D && state.curlyStack[state.curlyStack.length - 1] === '${')) {
4500 return scanTemplate();
4501 }
4502
4503 // Possible identifier start in a surrogate pair.
4504 if (cp >= 0xD800 && cp < 0xDFFF) {
4505 cp = codePointAt(index);
4506 if (isIdentifierStart(cp)) {
4507 return scanIdentifier();
4508 }
4509 }
4510
4511 return scanPunctuator();
4512 }
4513
4514 function collectToken() {
4515 var loc, token, value, entry;
4516
4517 loc = {
4518 start: {
4519 line: lineNumber,
4520 column: index - lineStart
4521 }
4522 };
4523
4524 token = advance();
4525 loc.end = {
4526 line: lineNumber,
4527 column: index - lineStart
4528 };
4529
4530 if (token.type !== Token.EOF) {
4531 value = source.slice(token.start, token.end);
4532 entry = {
4533 type: TokenName[token.type],
4534 value: value,
4535 range: [token.start, token.end],
4536 loc: loc
4537 };
4538 if (token.regex) {
4539 entry.regex = {
4540 pattern: token.regex.pattern,
4541 flags: token.regex.flags
4542 };
4543 }
4544 extra.tokens.push(entry);
4545 }
4546
4547 return token;
4548 }
4549
4550 function lex() {
4551 var token;
4552 scanning = true;
4553
4554 lastIndex = index;
4555 lastLineNumber = lineNumber;
4556 lastLineStart = lineStart;
4557
4558 skipComment();
4559
4560 token = lookahead;
4561
4562 startIndex = index;
4563 startLineNumber = lineNumber;
4564 startLineStart = lineStart;
4565
4566 lookahead = (typeof extra.tokens !== 'undefined') ? collectToken() : advance();
4567 scanning = false;
4568 return token;
4569 }
4570
4571 function peek() {
4572 scanning = true;
4573
4574 skipComment();
4575
4576 lastIndex = index;
4577 lastLineNumber = lineNumber;
4578 lastLineStart = lineStart;
4579
4580 startIndex = index;
4581 startLineNumber = lineNumber;
4582 startLineStart = lineStart;
4583
4584 lookahead = (typeof extra.tokens !== 'undefined') ? collectToken() : advance();
4585 scanning = false;
4586 }
4587
4588 function Position() {
4589 this.line = startLineNumber;
4590 this.column = startIndex - startLineStart;
4591 }
4592
4593 function SourceLocation() {
4594 this.start = new Position();
4595 this.end = null;
4596 }
4597
4598 function WrappingSourceLocation(startToken) {
4599 this.start = {
4600 line: startToken.lineNumber,
4601 column: startToken.start - startToken.lineStart
4602 };
4603 this.end = null;
4604 }
4605
4606 function Node() {
4607 if (extra.range) {
4608 this.range = [startIndex, 0];
4609 }
4610 if (extra.loc) {
4611 this.loc = new SourceLocation();
4612 }
4613 }
4614
4615 function WrappingNode(startToken) {
4616 if (extra.range) {
4617 this.range = [startToken.start, 0];
4618 }
4619 if (extra.loc) {
4620 this.loc = new WrappingSourceLocation(startToken);
4621 }
4622 }
4623
4624 WrappingNode.prototype = Node.prototype = {
4625
4626 processComment: function () {
4627 var lastChild,
4628 leadingComments,
4629 trailingComments,
4630 bottomRight = extra.bottomRightStack,
4631 i,
4632 comment,
4633 last = bottomRight[bottomRight.length - 1];
4634
4635 if (this.type === Syntax.Program) {
4636 if (this.body.length > 0) {
4637 return;
4638 }
4639 }
4640
4641 if (extra.trailingComments.length > 0) {
4642 trailingComments = [];
4643 for (i = extra.trailingComments.length - 1; i >= 0; --i) {
4644 comment = extra.trailingComments[i];
4645 if (comment.range[0] >= this.range[1]) {
4646 trailingComments.unshift(comment);
4647 extra.trailingComments.splice(i, 1);
4648 }
4649 }
4650 extra.trailingComments = [];
4651 } else {
4652 if (last && last.trailingComments && last.trailingComments[0].range[0] >= this.range[1]) {
4653 trailingComments = last.trailingComments;
4654 delete last.trailingComments;
4655 }
4656 }
4657
4658 // Eating the stack.
4659 while (last && last.range[0] >= this.range[0]) {
4660 lastChild = bottomRight.pop();
4661 last = bottomRight[bottomRight.length - 1];
4662 }
4663
4664 if (lastChild) {
4665 if (lastChild.leadingComments) {
4666 leadingComments = [];
4667 for (i = lastChild.leadingComments.length - 1; i >= 0; --i) {
4668 comment = lastChild.leadingComments[i];
4669 if (comment.range[1] <= this.range[0]) {
4670 leadingComments.unshift(comment);
4671 lastChild.leadingComments.splice(i, 1);
4672 }
4673 }
4674
4675 if (!lastChild.leadingComments.length) {
4676 lastChild.leadingComments = undefined;
4677 }
4678 }
4679 } else if (extra.leadingComments.length > 0) {
4680 leadingComments = [];
4681 for (i = extra.leadingComments.length - 1; i >= 0; --i) {
4682 comment = extra.leadingComments[i];
4683 if (comment.range[1] <= this.range[0]) {
4684 leadingComments.unshift(comment);
4685 extra.leadingComments.splice(i, 1);
4686 }
4687 }
4688 }
4689
4690
4691 if (leadingComments && leadingComments.length > 0) {
4692 this.leadingComments = leadingComments;
4693 }
4694 if (trailingComments && trailingComments.length > 0) {
4695 this.trailingComments = trailingComments;
4696 }
4697
4698 bottomRight.push(this);
4699 },
4700
4701 finish: function () {
4702 if (extra.range) {
4703 this.range[1] = lastIndex;
4704 }
4705 if (extra.loc) {
4706 this.loc.end = {
4707 line: lastLineNumber,
4708 column: lastIndex - lastLineStart
4709 };
4710 if (extra.source) {
4711 this.loc.source = extra.source;
4712 }
4713 }
4714
4715 if (extra.attachComment) {
4716 this.processComment();
4717 }
4718 },
4719
4720 finishArrayExpression: function (elements) {
4721 this.type = Syntax.ArrayExpression;
4722 this.elements = elements;
4723 this.finish();
4724 return this;
4725 },
4726
4727 finishArrayPattern: function (elements) {
4728 this.type = Syntax.ArrayPattern;
4729 this.elements = elements;
4730 this.finish();
4731 return this;
4732 },
4733
4734 finishArrowFunctionExpression: function (params, defaults, body, expression) {
4735 this.type = Syntax.ArrowFunctionExpression;
4736 this.id = null;
4737 this.params = params;
4738 this.defaults = defaults;
4739 this.body = body;
4740 this.generator = false;
4741 this.expression = expression;
4742 this.finish();
4743 return this;
4744 },
4745
4746 finishAssignmentExpression: function (operator, left, right) {
4747 this.type = Syntax.AssignmentExpression;
4748 this.operator = operator;
4749 this.left = left;
4750 this.right = right;
4751 this.finish();
4752 return this;
4753 },
4754
4755 finishAssignmentPattern: function (left, right) {
4756 this.type = Syntax.AssignmentPattern;
4757 this.left = left;
4758 this.right = right;
4759 this.finish();
4760 return this;
4761 },
4762
4763 finishBinaryExpression: function (operator, left, right) {
4764 this.type = (operator === '||' || operator === '&&') ? Syntax.LogicalExpression : Syntax.BinaryExpression;
4765 this.operator = operator;
4766 this.left = left;
4767 this.right = right;
4768 this.finish();
4769 return this;
4770 },
4771
4772 finishBlockStatement: function (body) {
4773 this.type = Syntax.BlockStatement;
4774 this.body = body;
4775 this.finish();
4776 return this;
4777 },
4778
4779 finishBreakStatement: function (label) {
4780 this.type = Syntax.BreakStatement;
4781 this.label = label;
4782 this.finish();
4783 return this;
4784 },
4785
4786 finishCallExpression: function (callee, args) {
4787 this.type = Syntax.CallExpression;
4788 this.callee = callee;
4789 this.arguments = args;
4790 this.finish();
4791 return this;
4792 },
4793
4794 finishCatchClause: function (param, body) {
4795 this.type = Syntax.CatchClause;
4796 this.param = param;
4797 this.body = body;
4798 this.finish();
4799 return this;
4800 },
4801
4802 finishClassBody: function (body) {
4803 this.type = Syntax.ClassBody;
4804 this.body = body;
4805 this.finish();
4806 return this;
4807 },
4808
4809 finishClassDeclaration: function (id, superClass, body) {
4810 this.type = Syntax.ClassDeclaration;
4811 this.id = id;
4812 this.superClass = superClass;
4813 this.body = body;
4814 this.finish();
4815 return this;
4816 },
4817
4818 finishClassExpression: function (id, superClass, body) {
4819 this.type = Syntax.ClassExpression;
4820 this.id = id;
4821 this.superClass = superClass;
4822 this.body = body;
4823 this.finish();
4824 return this;
4825 },
4826
4827 finishConditionalExpression: function (test, consequent, alternate) {
4828 this.type = Syntax.ConditionalExpression;
4829 this.test = test;
4830 this.consequent = consequent;
4831 this.alternate = alternate;
4832 this.finish();
4833 return this;
4834 },
4835
4836 finishContinueStatement: function (label) {
4837 this.type = Syntax.ContinueStatement;
4838 this.label = label;
4839 this.finish();
4840 return this;
4841 },
4842
4843 finishDebuggerStatement: function () {
4844 this.type = Syntax.DebuggerStatement;
4845 this.finish();
4846 return this;
4847 },
4848
4849 finishDoWhileStatement: function (body, test) {
4850 this.type = Syntax.DoWhileStatement;
4851 this.body = body;
4852 this.test = test;
4853 this.finish();
4854 return this;
4855 },
4856
4857 finishEmptyStatement: function () {
4858 this.type = Syntax.EmptyStatement;
4859 this.finish();
4860 return this;
4861 },
4862
4863 finishExpressionStatement: function (expression) {
4864 this.type = Syntax.ExpressionStatement;
4865 this.expression = expression;
4866 this.finish();
4867 return this;
4868 },
4869
4870 finishForStatement: function (init, test, update, body) {
4871 this.type = Syntax.ForStatement;
4872 this.init = init;
4873 this.test = test;
4874 this.update = update;
4875 this.body = body;
4876 this.finish();
4877 return this;
4878 },
4879
4880 finishForOfStatement: function (left, right, body) {
4881 this.type = Syntax.ForOfStatement;
4882 this.left = left;
4883 this.right = right;
4884 this.body = body;
4885 this.finish();
4886 return this;
4887 },
4888
4889 finishForInStatement: function (left, right, body) {
4890 this.type = Syntax.ForInStatement;
4891 this.left = left;
4892 this.right = right;
4893 this.body = body;
4894 this.each = false;
4895 this.finish();
4896 return this;
4897 },
4898
4899 finishFunctionDeclaration: function (id, params, defaults, body, generator) {
4900 this.type = Syntax.FunctionDeclaration;
4901 this.id = id;
4902 this.params = params;
4903 this.defaults = defaults;
4904 this.body = body;
4905 this.generator = generator;
4906 this.expression = false;
4907 this.finish();
4908 return this;
4909 },
4910
4911 finishFunctionExpression: function (id, params, defaults, body, generator) {
4912 this.type = Syntax.FunctionExpression;
4913 this.id = id;
4914 this.params = params;
4915 this.defaults = defaults;
4916 this.body = body;
4917 this.generator = generator;
4918 this.expression = false;
4919 this.finish();
4920 return this;
4921 },
4922
4923 finishIdentifier: function (name) {
4924 this.type = Syntax.Identifier;
4925 this.name = name;
4926 this.finish();
4927 return this;
4928 },
4929
4930 finishIfStatement: function (test, consequent, alternate) {
4931 this.type = Syntax.IfStatement;
4932 this.test = test;
4933 this.consequent = consequent;
4934 this.alternate = alternate;
4935 this.finish();
4936 return this;
4937 },
4938
4939 finishLabeledStatement: function (label, body) {
4940 this.type = Syntax.LabeledStatement;
4941 this.label = label;
4942 this.body = body;
4943 this.finish();
4944 return this;
4945 },
4946
4947 finishLiteral: function (token) {
4948 this.type = Syntax.Literal;
4949 this.value = token.value;
4950 this.raw = source.slice(token.start, token.end);
4951 if (token.regex) {
4952 this.regex = token.regex;
4953 }
4954 this.finish();
4955 return this;
4956 },
4957
4958 finishMemberExpression: function (accessor, object, property) {
4959 this.type = Syntax.MemberExpression;
4960 this.computed = accessor === '[';
4961 this.object = object;
4962 this.property = property;
4963 this.finish();
4964 return this;
4965 },
4966
4967 finishMetaProperty: function (meta, property) {
4968 this.type = Syntax.MetaProperty;
4969 this.meta = meta;
4970 this.property = property;
4971 this.finish();
4972 return this;
4973 },
4974
4975 finishNewExpression: function (callee, args) {
4976 this.type = Syntax.NewExpression;
4977 this.callee = callee;
4978 this.arguments = args;
4979 this.finish();
4980 return this;
4981 },
4982
4983 finishObjectExpression: function (properties) {
4984 this.type = Syntax.ObjectExpression;
4985 this.properties = properties;
4986 this.finish();
4987 return this;
4988 },
4989
4990 finishObjectPattern: function (properties) {
4991 this.type = Syntax.ObjectPattern;
4992 this.properties = properties;
4993 this.finish();
4994 return this;
4995 },
4996
4997 finishPostfixExpression: function (operator, argument) {
4998 this.type = Syntax.UpdateExpression;
4999 this.operator = operator;
5000 this.argument = argument;
5001 this.prefix = false;
5002 this.finish();
5003 return this;
5004 },
5005
5006 finishProgram: function (body, sourceType) {
5007 this.type = Syntax.Program;
5008 this.body = body;
5009 this.sourceType = sourceType;
5010 this.finish();
5011 return this;
5012 },
5013
5014 finishProperty: function (kind, key, computed, value, method, shorthand) {
5015 this.type = Syntax.Property;
5016 this.key = key;
5017 this.computed = computed;
5018 this.value = value;
5019 this.kind = kind;
5020 this.method = method;
5021 this.shorthand = shorthand;
5022 this.finish();
5023 return this;
5024 },
5025
5026 finishRestElement: function (argument) {
5027 this.type = Syntax.RestElement;
5028 this.argument = argument;
5029 this.finish();
5030 return this;
5031 },
5032
5033 finishReturnStatement: function (argument) {
5034 this.type = Syntax.ReturnStatement;
5035 this.argument = argument;
5036 this.finish();
5037 return this;
5038 },
5039
5040 finishSequenceExpression: function (expressions) {
5041 this.type = Syntax.SequenceExpression;
5042 this.expressions = expressions;
5043 this.finish();
5044 return this;
5045 },
5046
5047 finishSpreadElement: function (argument) {
5048 this.type = Syntax.SpreadElement;
5049 this.argument = argument;
5050 this.finish();
5051 return this;
5052 },
5053
5054 finishSwitchCase: function (test, consequent) {
5055 this.type = Syntax.SwitchCase;
5056 this.test = test;
5057 this.consequent = consequent;
5058 this.finish();
5059 return this;
5060 },
5061
5062 finishSuper: function () {
5063 this.type = Syntax.Super;
5064 this.finish();
5065 return this;
5066 },
5067
5068 finishSwitchStatement: function (discriminant, cases) {
5069 this.type = Syntax.SwitchStatement;
5070 this.discriminant = discriminant;
5071 this.cases = cases;
5072 this.finish();
5073 return this;
5074 },
5075
5076 finishTaggedTemplateExpression: function (tag, quasi) {
5077 this.type = Syntax.TaggedTemplateExpression;
5078 this.tag = tag;
5079 this.quasi = quasi;
5080 this.finish();
5081 return this;
5082 },
5083
5084 finishTemplateElement: function (value, tail) {
5085 this.type = Syntax.TemplateElement;
5086 this.value = value;
5087 this.tail = tail;
5088 this.finish();
5089 return this;
5090 },
5091
5092 finishTemplateLiteral: function (quasis, expressions) {
5093 this.type = Syntax.TemplateLiteral;
5094 this.quasis = quasis;
5095 this.expressions = expressions;
5096 this.finish();
5097 return this;
5098 },
5099
5100 finishThisExpression: function () {
5101 this.type = Syntax.ThisExpression;
5102 this.finish();
5103 return this;
5104 },
5105
5106 finishThrowStatement: function (argument) {
5107 this.type = Syntax.ThrowStatement;
5108 this.argument = argument;
5109 this.finish();
5110 return this;
5111 },
5112
5113 finishTryStatement: function (block, handler, finalizer) {
5114 this.type = Syntax.TryStatement;
5115 this.block = block;
5116 this.guardedHandlers = [];
5117 this.handlers = handler ? [handler] : [];
5118 this.handler = handler;
5119 this.finalizer = finalizer;
5120 this.finish();
5121 return this;
5122 },
5123
5124 finishUnaryExpression: function (operator, argument) {
5125 this.type = (operator === '++' || operator === '--') ? Syntax.UpdateExpression : Syntax.UnaryExpression;
5126 this.operator = operator;
5127 this.argument = argument;
5128 this.prefix = true;
5129 this.finish();
5130 return this;
5131 },
5132
5133 finishVariableDeclaration: function (declarations) {
5134 this.type = Syntax.VariableDeclaration;
5135 this.declarations = declarations;
5136 this.kind = 'var';
5137 this.finish();
5138 return this;
5139 },
5140
5141 finishLexicalDeclaration: function (declarations, kind) {
5142 this.type = Syntax.VariableDeclaration;
5143 this.declarations = declarations;
5144 this.kind = kind;
5145 this.finish();
5146 return this;
5147 },
5148
5149 finishVariableDeclarator: function (id, init) {
5150 this.type = Syntax.VariableDeclarator;
5151 this.id = id;
5152 this.init = init;
5153 this.finish();
5154 return this;
5155 },
5156
5157 finishWhileStatement: function (test, body) {
5158 this.type = Syntax.WhileStatement;
5159 this.test = test;
5160 this.body = body;
5161 this.finish();
5162 return this;
5163 },
5164
5165 finishWithStatement: function (object, body) {
5166 this.type = Syntax.WithStatement;
5167 this.object = object;
5168 this.body = body;
5169 this.finish();
5170 return this;
5171 },
5172
5173 finishExportSpecifier: function (local, exported) {
5174 this.type = Syntax.ExportSpecifier;
5175 this.exported = exported || local;
5176 this.local = local;
5177 this.finish();
5178 return this;
5179 },
5180
5181 finishImportDefaultSpecifier: function (local) {
5182 this.type = Syntax.ImportDefaultSpecifier;
5183 this.local = local;
5184 this.finish();
5185 return this;
5186 },
5187
5188 finishImportNamespaceSpecifier: function (local) {
5189 this.type = Syntax.ImportNamespaceSpecifier;
5190 this.local = local;
5191 this.finish();
5192 return this;
5193 },
5194
5195 finishExportNamedDeclaration: function (declaration, specifiers, src) {
5196 this.type = Syntax.ExportNamedDeclaration;
5197 this.declaration = declaration;
5198 this.specifiers = specifiers;
5199 this.source = src;
5200 this.finish();
5201 return this;
5202 },
5203
5204 finishExportDefaultDeclaration: function (declaration) {
5205 this.type = Syntax.ExportDefaultDeclaration;
5206 this.declaration = declaration;
5207 this.finish();
5208 return this;
5209 },
5210
5211 finishExportAllDeclaration: function (src) {
5212 this.type = Syntax.ExportAllDeclaration;
5213 this.source = src;
5214 this.finish();
5215 return this;
5216 },
5217
5218 finishImportSpecifier: function (local, imported) {
5219 this.type = Syntax.ImportSpecifier;
5220 this.local = local || imported;
5221 this.imported = imported;
5222 this.finish();
5223 return this;
5224 },
5225
5226 finishImportDeclaration: function (specifiers, src) {
5227 this.type = Syntax.ImportDeclaration;
5228 this.specifiers = specifiers;
5229 this.source = src;
5230 this.finish();
5231 return this;
5232 },
5233
5234 finishYieldExpression: function (argument, delegate) {
5235 this.type = Syntax.YieldExpression;
5236 this.argument = argument;
5237 this.delegate = delegate;
5238 this.finish();
5239 return this;
5240 }
5241 };
5242
5243
5244 function recordError(error) {
5245 var e, existing;
5246
5247 for (e = 0; e < extra.errors.length; e++) {
5248 existing = extra.errors[e];
5249 // Prevent duplicated error.
5250 /* istanbul ignore next */
5251 if (existing.index === error.index && existing.message === error.message) {
5252 return;
5253 }
5254 }
5255
5256 extra.errors.push(error);
5257 }
5258
5259 function constructError(msg, column) {
5260 var error = new Error(msg);
5261 try {
5262 throw error;
5263 } catch (base) {
5264 /* istanbul ignore else */
5265 if (Object.create && Object.defineProperty) {
5266 error = Object.create(base);
5267 Object.defineProperty(error, 'column', { value: column });
5268 }
5269 } finally {
5270 return error;
5271 }
5272 }
5273
5274 function createError(line, pos, description) {
5275 var msg, column, error;
5276
5277 msg = 'Line ' + line + ': ' + description;
5278 column = pos - (scanning ? lineStart : lastLineStart) + 1;
5279 error = constructError(msg, column);
5280 error.lineNumber = line;
5281 error.description = description;
5282 error.index = pos;
5283 return error;
5284 }
5285
5286 // Throw an exception
5287
5288 function throwError(messageFormat) {
5289 var args, msg;
5290
5291 args = Array.prototype.slice.call(arguments, 1);
5292 msg = messageFormat.replace(/%(\d)/g,
5293 function (whole, idx) {
5294 assert(idx < args.length, 'Message reference must be in range');
5295 return args[idx];
5296 }
5297 );
5298
5299 throw createError(lastLineNumber, lastIndex, msg);
5300 }
5301
5302 function tolerateError(messageFormat) {
5303 var args, msg, error;
5304
5305 args = Array.prototype.slice.call(arguments, 1);
5306 /* istanbul ignore next */
5307 msg = messageFormat.replace(/%(\d)/g,
5308 function (whole, idx) {
5309 assert(idx < args.length, 'Message reference must be in range');
5310 return args[idx];
5311 }
5312 );
5313
5314 error = createError(lineNumber, lastIndex, msg);
5315 if (extra.errors) {
5316 recordError(error);
5317 } else {
5318 throw error;
5319 }
5320 }
5321
5322 // Throw an exception because of the token.
5323
5324 function unexpectedTokenError(token, message) {
5325 var value, msg = message || Messages.UnexpectedToken;
5326
5327 if (token) {
5328 if (!message) {
5329 msg = (token.type === Token.EOF) ? Messages.UnexpectedEOS :
5330 (token.type === Token.Identifier) ? Messages.UnexpectedIdentifier :
5331 (token.type === Token.NumericLiteral) ? Messages.UnexpectedNumber :
5332 (token.type === Token.StringLiteral) ? Messages.UnexpectedString :
5333 (token.type === Token.Template) ? Messages.UnexpectedTemplate :
5334 Messages.UnexpectedToken;
5335
5336 if (token.type === Token.Keyword) {
5337 if (isFutureReservedWord(token.value)) {
5338 msg = Messages.UnexpectedReserved;
5339 } else if (strict && isStrictModeReservedWord(token.value)) {
5340 msg = Messages.StrictReservedWord;
5341 }
5342 }
5343 }
5344
5345 value = (token.type === Token.Template) ? token.value.raw : token.value;
5346 } else {
5347 value = 'ILLEGAL';
5348 }
5349
5350 msg = msg.replace('%0', value);
5351
5352 return (token && typeof token.lineNumber === 'number') ?
5353 createError(token.lineNumber, token.start, msg) :
5354 createError(scanning ? lineNumber : lastLineNumber, scanning ? index : lastIndex, msg);
5355 }
5356
5357 function throwUnexpectedToken(token, message) {
5358 throw unexpectedTokenError(token, message);
5359 }
5360
5361 function tolerateUnexpectedToken(token, message) {
5362 var error = unexpectedTokenError(token, message);
5363 if (extra.errors) {
5364 recordError(error);
5365 } else {
5366 throw error;
5367 }
5368 }
5369
5370 // Expect the next token to match the specified punctuator.
5371 // If not, an exception will be thrown.
5372
5373 function expect(value) {
5374 var token = lex();
5375 if (token.type !== Token.Punctuator || token.value !== value) {
5376 throwUnexpectedToken(token);
5377 }
5378 }
5379
5380 /**
5381 * @name expectCommaSeparator
5382 * @description Quietly expect a comma when in tolerant mode, otherwise delegates
5383 * to <code>expect(value)</code>
5384 * @since 2.0
5385 */
5386 function expectCommaSeparator() {
5387 var token;
5388
5389 if (extra.errors) {
5390 token = lookahead;
5391 if (token.type === Token.Punctuator && token.value === ',') {
5392 lex();
5393 } else if (token.type === Token.Punctuator && token.value === ';') {
5394 lex();
5395 tolerateUnexpectedToken(token);
5396 } else {
5397 tolerateUnexpectedToken(token, Messages.UnexpectedToken);
5398 }
5399 } else {
5400 expect(',');
5401 }
5402 }
5403
5404 // Expect the next token to match the specified keyword.
5405 // If not, an exception will be thrown.
5406
5407 function expectKeyword(keyword) {
5408 var token = lex();
5409 if (token.type !== Token.Keyword || token.value !== keyword) {
5410 throwUnexpectedToken(token);
5411 }
5412 }
5413
5414 // Return true if the next token matches the specified punctuator.
5415
5416 function match(value) {
5417 return lookahead.type === Token.Punctuator && lookahead.value === value;
5418 }
5419
5420 // Return true if the next token matches the specified keyword
5421
5422 function matchKeyword(keyword) {
5423 return lookahead.type === Token.Keyword && lookahead.value === keyword;
5424 }
5425
5426 // Return true if the next token matches the specified contextual keyword
5427 // (where an identifier is sometimes a keyword depending on the context)
5428
5429 function matchContextualKeyword(keyword) {
5430 return lookahead.type === Token.Identifier && lookahead.value === keyword;
5431 }
5432
5433 // Return true if the next token is an assignment operator
5434
5435 function matchAssign() {
5436 var op;
5437
5438 if (lookahead.type !== Token.Punctuator) {
5439 return false;
5440 }
5441 op = lookahead.value;
5442 return op === '=' ||
5443 op === '*=' ||
5444 op === '/=' ||
5445 op === '%=' ||
5446 op === '+=' ||
5447 op === '-=' ||
5448 op === '<<=' ||
5449 op === '>>=' ||
5450 op === '>>>=' ||
5451 op === '&=' ||
5452 op === '^=' ||
5453 op === '|=';
5454 }
5455
5456 function consumeSemicolon() {
5457 // Catch the very common case first: immediately a semicolon (U+003B).
5458 if (source.charCodeAt(startIndex) === 0x3B || match(';')) {
5459 lex();
5460 return;
5461 }
5462
5463 if (hasLineTerminator) {
5464 return;
5465 }
5466
5467 // FIXME(ikarienator): this is seemingly an issue in the previous location info convention.
5468 lastIndex = startIndex;
5469 lastLineNumber = startLineNumber;
5470 lastLineStart = startLineStart;
5471
5472 if (lookahead.type !== Token.EOF && !match('}')) {
5473 throwUnexpectedToken(lookahead);
5474 }
5475 }
5476
5477 // Cover grammar support.
5478 //
5479 // When an assignment expression position starts with an left parenthesis, the determination of the type
5480 // of the syntax is to be deferred arbitrarily long until the end of the parentheses pair (plus a lookahead)
5481 // or the first comma. This situation also defers the determination of all the expressions nested in the pair.
5482 //
5483 // There are three productions that can be parsed in a parentheses pair that needs to be determined
5484 // after the outermost pair is closed. They are:
5485 //
5486 // 1. AssignmentExpression
5487 // 2. BindingElements
5488 // 3. AssignmentTargets
5489 //
5490 // In order to avoid exponential backtracking, we use two flags to denote if the production can be
5491 // binding element or assignment target.
5492 //
5493 // The three productions have the relationship:
5494 //
5495 // BindingElements ⊆ AssignmentTargets ⊆ AssignmentExpression
5496 //
5497 // with a single exception that CoverInitializedName when used directly in an Expression, generates
5498 // an early error. Therefore, we need the third state, firstCoverInitializedNameError, to track the
5499 // first usage of CoverInitializedName and report it when we reached the end of the parentheses pair.
5500 //
5501 // isolateCoverGrammar function runs the given parser function with a new cover grammar context, and it does not
5502 // effect the current flags. This means the production the parser parses is only used as an expression. Therefore
5503 // the CoverInitializedName check is conducted.
5504 //
5505 // inheritCoverGrammar function runs the given parse function with a new cover grammar context, and it propagates
5506 // the flags outside of the parser. This means the production the parser parses is used as a part of a potential
5507 // pattern. The CoverInitializedName check is deferred.
5508 function isolateCoverGrammar(parser) {
5509 var oldIsBindingElement = isBindingElement,
5510 oldIsAssignmentTarget = isAssignmentTarget,
5511 oldFirstCoverInitializedNameError = firstCoverInitializedNameError,
5512 result;
5513 isBindingElement = true;
5514 isAssignmentTarget = true;
5515 firstCoverInitializedNameError = null;
5516 result = parser();
5517 if (firstCoverInitializedNameError !== null) {
5518 throwUnexpectedToken(firstCoverInitializedNameError);
5519 }
5520 isBindingElement = oldIsBindingElement;
5521 isAssignmentTarget = oldIsAssignmentTarget;
5522 firstCoverInitializedNameError = oldFirstCoverInitializedNameError;
5523 return result;
5524 }
5525
5526 function inheritCoverGrammar(parser) {
5527 var oldIsBindingElement = isBindingElement,
5528 oldIsAssignmentTarget = isAssignmentTarget,
5529 oldFirstCoverInitializedNameError = firstCoverInitializedNameError,
5530 result;
5531 isBindingElement = true;
5532 isAssignmentTarget = true;
5533 firstCoverInitializedNameError = null;
5534 result = parser();
5535 isBindingElement = isBindingElement && oldIsBindingElement;
5536 isAssignmentTarget = isAssignmentTarget && oldIsAssignmentTarget;
5537 firstCoverInitializedNameError = oldFirstCoverInitializedNameError || firstCoverInitializedNameError;
5538 return result;
5539 }
5540
5541 // ECMA-262 13.3.3 Destructuring Binding Patterns
5542
5543 function parseArrayPattern(params, kind) {
5544 var node = new Node(), elements = [], rest, restNode;
5545 expect('[');
5546
5547 while (!match(']')) {
5548 if (match(',')) {
5549 lex();
5550 elements.push(null);
5551 } else {
5552 if (match('...')) {
5553 restNode = new Node();
5554 lex();
5555 params.push(lookahead);
5556 rest = parseVariableIdentifier(params, kind);
5557 elements.push(restNode.finishRestElement(rest));
5558 break;
5559 } else {
5560 elements.push(parsePatternWithDefault(params, kind));
5561 }
5562 if (!match(']')) {
5563 expect(',');
5564 }
5565 }
5566
5567 }
5568
5569 expect(']');
5570
5571 return node.finishArrayPattern(elements);
5572 }
5573
5574 function parsePropertyPattern(params, kind) {
5575 var node = new Node(), key, keyToken, computed = match('['), init;
5576 if (lookahead.type === Token.Identifier) {
5577 keyToken = lookahead;
5578 key = parseVariableIdentifier();
5579 if (match('=')) {
5580 params.push(keyToken);
5581 lex();
5582 init = parseAssignmentExpression();
5583
5584 return node.finishProperty(
5585 'init', key, false,
5586 new WrappingNode(keyToken).finishAssignmentPattern(key, init), false, false);
5587 } else if (!match(':')) {
5588 params.push(keyToken);
5589 return node.finishProperty('init', key, false, key, false, true);
5590 }
5591 } else {
5592 key = parseObjectPropertyKey(params, kind);
5593 }
5594 expect(':');
5595 init = parsePatternWithDefault(params, kind);
5596 return node.finishProperty('init', key, computed, init, false, false);
5597 }
5598
5599 function parseObjectPattern(params, kind) {
5600 var node = new Node(), properties = [];
5601
5602 expect('{');
5603
5604 while (!match('}')) {
5605 properties.push(parsePropertyPattern(params, kind));
5606 if (!match('}')) {
5607 expect(',');
5608 }
5609 }
5610
5611 lex();
5612
5613 return node.finishObjectPattern(properties);
5614 }
5615
5616 function parsePattern(params, kind) {
5617 if (match('[')) {
5618 return parseArrayPattern(params, kind);
5619 } else if (match('{')) {
5620 return parseObjectPattern(params, kind);
5621 }
5622 params.push(lookahead);
5623 return parseVariableIdentifier(kind);
5624 }
5625
5626 function parsePatternWithDefault(params, kind) {
5627 var startToken = lookahead, pattern, previousAllowYield, right;
5628 pattern = parsePattern(params, kind);
5629 if (match('=')) {
5630 lex();
5631 previousAllowYield = state.allowYield;
5632 state.allowYield = true;
5633 right = isolateCoverGrammar(parseAssignmentExpression);
5634 state.allowYield = previousAllowYield;
5635 pattern = new WrappingNode(startToken).finishAssignmentPattern(pattern, right);
5636 }
5637 return pattern;
5638 }
5639
5640 // ECMA-262 12.2.5 Array Initializer
5641
5642 function parseArrayInitializer() {
5643 var elements = [], node = new Node(), restSpread;
5644
5645 expect('[');
5646
5647 while (!match(']')) {
5648 if (match(',')) {
5649 lex();
5650 elements.push(null);
5651 } else if (match('...')) {
5652 restSpread = new Node();
5653 lex();
5654 restSpread.finishSpreadElement(inheritCoverGrammar(parseAssignmentExpression));
5655
5656 if (!match(']')) {
5657 isAssignmentTarget = isBindingElement = false;
5658 expect(',');
5659 }
5660 elements.push(restSpread);
5661 } else {
5662 elements.push(inheritCoverGrammar(parseAssignmentExpression));
5663
5664 if (!match(']')) {
5665 expect(',');
5666 }
5667 }
5668 }
5669
5670 lex();
5671
5672 return node.finishArrayExpression(elements);
5673 }
5674
5675 // ECMA-262 12.2.6 Object Initializer
5676
5677 function parsePropertyFunction(node, paramInfo, isGenerator) {
5678 var previousStrict, body;
5679
5680 isAssignmentTarget = isBindingElement = false;
5681
5682 previousStrict = strict;
5683 body = isolateCoverGrammar(parseFunctionSourceElements);
5684
5685 if (strict && paramInfo.firstRestricted) {
5686 tolerateUnexpectedToken(paramInfo.firstRestricted, paramInfo.message);
5687 }
5688 if (strict && paramInfo.stricted) {
5689 tolerateUnexpectedToken(paramInfo.stricted, paramInfo.message);
5690 }
5691
5692 strict = previousStrict;
5693 return node.finishFunctionExpression(null, paramInfo.params, paramInfo.defaults, body, isGenerator);
5694 }
5695
5696 function parsePropertyMethodFunction() {
5697 var params, method, node = new Node(),
5698 previousAllowYield = state.allowYield;
5699
5700 state.allowYield = false;
5701 params = parseParams();
5702 state.allowYield = previousAllowYield;
5703
5704 state.allowYield = false;
5705 method = parsePropertyFunction(node, params, false);
5706 state.allowYield = previousAllowYield;
5707
5708 return method;
5709 }
5710
5711 function parseObjectPropertyKey() {
5712 var token, node = new Node(), expr;
5713
5714 token = lex();
5715
5716 // Note: This function is called only from parseObjectProperty(), where
5717 // EOF and Punctuator tokens are already filtered out.
5718
5719 switch (token.type) {
5720 case Token.StringLiteral:
5721 case Token.NumericLiteral:
5722 if (strict && token.octal) {
5723 tolerateUnexpectedToken(token, Messages.StrictOctalLiteral);
5724 }
5725 return node.finishLiteral(token);
5726 case Token.Identifier:
5727 case Token.BooleanLiteral:
5728 case Token.NullLiteral:
5729 case Token.Keyword:
5730 return node.finishIdentifier(token.value);
5731 case Token.Punctuator:
5732 if (token.value === '[') {
5733 expr = isolateCoverGrammar(parseAssignmentExpression);
5734 expect(']');
5735 return expr;
5736 }
5737 break;
5738 }
5739 throwUnexpectedToken(token);
5740 }
5741
5742 function lookaheadPropertyName() {
5743 switch (lookahead.type) {
5744 case Token.Identifier:
5745 case Token.StringLiteral:
5746 case Token.BooleanLiteral:
5747 case Token.NullLiteral:
5748 case Token.NumericLiteral:
5749 case Token.Keyword:
5750 return true;
5751 case Token.Punctuator:
5752 return lookahead.value === '[';
5753 }
5754 return false;
5755 }
5756
5757 // This function is to try to parse a MethodDefinition as defined in 14.3. But in the case of object literals,
5758 // it might be called at a position where there is in fact a short hand identifier pattern or a data property.
5759 // This can only be determined after we consumed up to the left parentheses.
5760 //
5761 // In order to avoid back tracking, it returns `null` if the position is not a MethodDefinition and the caller
5762 // is responsible to visit other options.
5763 function tryParseMethodDefinition(token, key, computed, node) {
5764 var value, options, methodNode, params,
5765 previousAllowYield = state.allowYield;
5766
5767 if (token.type === Token.Identifier) {
5768 // check for `get` and `set`;
5769
5770 if (token.value === 'get' && lookaheadPropertyName()) {
5771 computed = match('[');
5772 key = parseObjectPropertyKey();
5773 methodNode = new Node();
5774 expect('(');
5775 expect(')');
5776
5777 state.allowYield = false;
5778 value = parsePropertyFunction(methodNode, {
5779 params: [],
5780 defaults: [],
5781 stricted: null,
5782 firstRestricted: null,
5783 message: null
5784 }, false);
5785 state.allowYield = previousAllowYield;
5786
5787 return node.finishProperty('get', key, computed, value, false, false);
5788 } else if (token.value === 'set' && lookaheadPropertyName()) {
5789 computed = match('[');
5790 key = parseObjectPropertyKey();
5791 methodNode = new Node();
5792 expect('(');
5793
5794 options = {
5795 params: [],
5796 defaultCount: 0,
5797 defaults: [],
5798 firstRestricted: null,
5799 paramSet: {}
5800 };
5801 if (match(')')) {
5802 tolerateUnexpectedToken(lookahead);
5803 } else {
5804 state.allowYield = false;
5805 parseParam(options);
5806 state.allowYield = previousAllowYield;
5807 if (options.defaultCount === 0) {
5808 options.defaults = [];
5809 }
5810 }
5811 expect(')');
5812
5813 state.allowYield = false;
5814 value = parsePropertyFunction(methodNode, options, false);
5815 state.allowYield = previousAllowYield;
5816
5817 return node.finishProperty('set', key, computed, value, false, false);
5818 }
5819 } else if (token.type === Token.Punctuator && token.value === '*' && lookaheadPropertyName()) {
5820 computed = match('[');
5821 key = parseObjectPropertyKey();
5822 methodNode = new Node();
5823
5824 state.allowYield = true;
5825 params = parseParams();
5826 state.allowYield = previousAllowYield;
5827
5828 state.allowYield = false;
5829 value = parsePropertyFunction(methodNode, params, true);
5830 state.allowYield = previousAllowYield;
5831
5832 return node.finishProperty('init', key, computed, value, true, false);
5833 }
5834
5835 if (key && match('(')) {
5836 value = parsePropertyMethodFunction();
5837 return node.finishProperty('init', key, computed, value, true, false);
5838 }
5839
5840 // Not a MethodDefinition.
5841 return null;
5842 }
5843
5844 function parseObjectProperty(hasProto) {
5845 var token = lookahead, node = new Node(), computed, key, maybeMethod, proto, value;
5846
5847 computed = match('[');
5848 if (match('*')) {
5849 lex();
5850 } else {
5851 key = parseObjectPropertyKey();
5852 }
5853 maybeMethod = tryParseMethodDefinition(token, key, computed, node);
5854 if (maybeMethod) {
5855 return maybeMethod;
5856 }
5857
5858 if (!key) {
5859 throwUnexpectedToken(lookahead);
5860 }
5861
5862 // Check for duplicated __proto__
5863 if (!computed) {
5864 proto = (key.type === Syntax.Identifier && key.name === '__proto__') ||
5865 (key.type === Syntax.Literal && key.value === '__proto__');
5866 if (hasProto.value && proto) {
5867 tolerateError(Messages.DuplicateProtoProperty);
5868 }
5869 hasProto.value |= proto;
5870 }
5871
5872 if (match(':')) {
5873 lex();
5874 value = inheritCoverGrammar(parseAssignmentExpression);
5875 return node.finishProperty('init', key, computed, value, false, false);
5876 }
5877
5878 if (token.type === Token.Identifier) {
5879 if (match('=')) {
5880 firstCoverInitializedNameError = lookahead;
5881 lex();
5882 value = isolateCoverGrammar(parseAssignmentExpression);
5883 return node.finishProperty('init', key, computed,
5884 new WrappingNode(token).finishAssignmentPattern(key, value), false, true);
5885 }
5886 return node.finishProperty('init', key, computed, key, false, true);
5887 }
5888
5889 throwUnexpectedToken(lookahead);
5890 }
5891
5892 function parseObjectInitializer() {
5893 var properties = [], hasProto = {value: false}, node = new Node();
5894
5895 expect('{');
5896
5897 while (!match('}')) {
5898 properties.push(parseObjectProperty(hasProto));
5899
5900 if (!match('}')) {
5901 expectCommaSeparator();
5902 }
5903 }
5904
5905 expect('}');
5906
5907 return node.finishObjectExpression(properties);
5908 }
5909
5910 function reinterpretExpressionAsPattern(expr) {
5911 var i;
5912 switch (expr.type) {
5913 case Syntax.Identifier:
5914 case Syntax.MemberExpression:
5915 case Syntax.RestElement:
5916 case Syntax.AssignmentPattern:
5917 break;
5918 case Syntax.SpreadElement:
5919 expr.type = Syntax.RestElement;
5920 reinterpretExpressionAsPattern(expr.argument);
5921 break;
5922 case Syntax.ArrayExpression:
5923 expr.type = Syntax.ArrayPattern;
5924 for (i = 0; i < expr.elements.length; i++) {
5925 if (expr.elements[i] !== null) {
5926 reinterpretExpressionAsPattern(expr.elements[i]);
5927 }
5928 }
5929 break;
5930 case Syntax.ObjectExpression:
5931 expr.type = Syntax.ObjectPattern;
5932 for (i = 0; i < expr.properties.length; i++) {
5933 reinterpretExpressionAsPattern(expr.properties[i].value);
5934 }
5935 break;
5936 case Syntax.AssignmentExpression:
5937 expr.type = Syntax.AssignmentPattern;
5938 reinterpretExpressionAsPattern(expr.left);
5939 break;
5940 default:
5941 // Allow other node type for tolerant parsing.
5942 break;
5943 }
5944 }
5945
5946 // ECMA-262 12.2.9 Template Literals
5947
5948 function parseTemplateElement(option) {
5949 var node, token;
5950
5951 if (lookahead.type !== Token.Template || (option.head && !lookahead.head)) {
5952 throwUnexpectedToken();
5953 }
5954
5955 node = new Node();
5956 token = lex();
5957
5958 return node.finishTemplateElement({ raw: token.value.raw, cooked: token.value.cooked }, token.tail);
5959 }
5960
5961 function parseTemplateLiteral() {
5962 var quasi, quasis, expressions, node = new Node();
5963
5964 quasi = parseTemplateElement({ head: true });
5965 quasis = [quasi];
5966 expressions = [];
5967
5968 while (!quasi.tail) {
5969 expressions.push(parseExpression());
5970 quasi = parseTemplateElement({ head: false });
5971 quasis.push(quasi);
5972 }
5973
5974 return node.finishTemplateLiteral(quasis, expressions);
5975 }
5976
5977 // ECMA-262 12.2.10 The Grouping Operator
5978
5979 function parseGroupExpression() {
5980 var expr, expressions, startToken, i, params = [];
5981
5982 expect('(');
5983
5984 if (match(')')) {
5985 lex();
5986 if (!match('=>')) {
5987 expect('=>');
5988 }
5989 return {
5990 type: PlaceHolders.ArrowParameterPlaceHolder,
5991 params: [],
5992 rawParams: []
5993 };
5994 }
5995
5996 startToken = lookahead;
5997 if (match('...')) {
5998 expr = parseRestElement(params);
5999 expect(')');
6000 if (!match('=>')) {
6001 expect('=>');
6002 }
6003 return {
6004 type: PlaceHolders.ArrowParameterPlaceHolder,
6005 params: [expr]
6006 };
6007 }
6008
6009 isBindingElement = true;
6010 expr = inheritCoverGrammar(parseAssignmentExpression);
6011
6012 if (match(',')) {
6013 isAssignmentTarget = false;
6014 expressions = [expr];
6015
6016 while (startIndex < length) {
6017 if (!match(',')) {
6018 break;
6019 }
6020 lex();
6021
6022 if (match('...')) {
6023 if (!isBindingElement) {
6024 throwUnexpectedToken(lookahead);
6025 }
6026 expressions.push(parseRestElement(params));
6027 expect(')');
6028 if (!match('=>')) {
6029 expect('=>');
6030 }
6031 isBindingElement = false;
6032 for (i = 0; i < expressions.length; i++) {
6033 reinterpretExpressionAsPattern(expressions[i]);
6034 }
6035 return {
6036 type: PlaceHolders.ArrowParameterPlaceHolder,
6037 params: expressions
6038 };
6039 }
6040
6041 expressions.push(inheritCoverGrammar(parseAssignmentExpression));
6042 }
6043
6044 expr = new WrappingNode(startToken).finishSequenceExpression(expressions);
6045 }
6046
6047
6048 expect(')');
6049
6050 if (match('=>')) {
6051 if (expr.type === Syntax.Identifier && expr.name === 'yield') {
6052 return {
6053 type: PlaceHolders.ArrowParameterPlaceHolder,
6054 params: [expr]
6055 };
6056 }
6057
6058 if (!isBindingElement) {
6059 throwUnexpectedToken(lookahead);
6060 }
6061
6062 if (expr.type === Syntax.SequenceExpression) {
6063 for (i = 0; i < expr.expressions.length; i++) {
6064 reinterpretExpressionAsPattern(expr.expressions[i]);
6065 }
6066 } else {
6067 reinterpretExpressionAsPattern(expr);
6068 }
6069
6070 expr = {
6071 type: PlaceHolders.ArrowParameterPlaceHolder,
6072 params: expr.type === Syntax.SequenceExpression ? expr.expressions : [expr]
6073 };
6074 }
6075 isBindingElement = false;
6076 return expr;
6077 }
6078
6079
6080 // ECMA-262 12.2 Primary Expressions
6081
6082 function parsePrimaryExpression() {
6083 var type, token, expr, node;
6084
6085 if (match('(')) {
6086 isBindingElement = false;
6087 return inheritCoverGrammar(parseGroupExpression);
6088 }
6089
6090 if (match('[')) {
6091 return inheritCoverGrammar(parseArrayInitializer);
6092 }
6093
6094 if (match('{')) {
6095 return inheritCoverGrammar(parseObjectInitializer);
6096 }
6097
6098 type = lookahead.type;
6099 node = new Node();
6100
6101 if (type === Token.Identifier) {
6102 if (state.sourceType === 'module' && lookahead.value === 'await') {
6103 tolerateUnexpectedToken(lookahead);
6104 }
6105 expr = node.finishIdentifier(lex().value);
6106 } else if (type === Token.StringLiteral || type === Token.NumericLiteral) {
6107 isAssignmentTarget = isBindingElement = false;
6108 if (strict && lookahead.octal) {
6109 tolerateUnexpectedToken(lookahead, Messages.StrictOctalLiteral);
6110 }
6111 expr = node.finishLiteral(lex());
6112 } else if (type === Token.Keyword) {
6113 if (!strict && state.allowYield && matchKeyword('yield')) {
6114 return parseNonComputedProperty();
6115 }
6116 isAssignmentTarget = isBindingElement = false;
6117 if (matchKeyword('function')) {
6118 return parseFunctionExpression();
6119 }
6120 if (matchKeyword('this')) {
6121 lex();
6122 return node.finishThisExpression();
6123 }
6124 if (matchKeyword('class')) {
6125 return parseClassExpression();
6126 }
6127 throwUnexpectedToken(lex());
6128 } else if (type === Token.BooleanLiteral) {
6129 isAssignmentTarget = isBindingElement = false;
6130 token = lex();
6131 token.value = (token.value === 'true');
6132 expr = node.finishLiteral(token);
6133 } else if (type === Token.NullLiteral) {
6134 isAssignmentTarget = isBindingElement = false;
6135 token = lex();
6136 token.value = null;
6137 expr = node.finishLiteral(token);
6138 } else if (match('/') || match('/=')) {
6139 isAssignmentTarget = isBindingElement = false;
6140 index = startIndex;
6141
6142 if (typeof extra.tokens !== 'undefined') {
6143 token = collectRegex();
6144 } else {
6145 token = scanRegExp();
6146 }
6147 lex();
6148 expr = node.finishLiteral(token);
6149 } else if (type === Token.Template) {
6150 expr = parseTemplateLiteral();
6151 } else {
6152 throwUnexpectedToken(lex());
6153 }
6154
6155 return expr;
6156 }
6157
6158 // ECMA-262 12.3 Left-Hand-Side Expressions
6159
6160 function parseArguments() {
6161 var args = [], expr;
6162
6163 expect('(');
6164
6165 if (!match(')')) {
6166 while (startIndex < length) {
6167 if (match('...')) {
6168 expr = new Node();
6169 lex();
6170 expr.finishSpreadElement(isolateCoverGrammar(parseAssignmentExpression));
6171 } else {
6172 expr = isolateCoverGrammar(parseAssignmentExpression);
6173 }
6174 args.push(expr);
6175 if (match(')')) {
6176 break;
6177 }
6178 expectCommaSeparator();
6179 }
6180 }
6181
6182 expect(')');
6183
6184 return args;
6185 }
6186
6187 function parseNonComputedProperty() {
6188 var token, node = new Node();
6189
6190 token = lex();
6191
6192 if (!isIdentifierName(token)) {
6193 throwUnexpectedToken(token);
6194 }
6195
6196 return node.finishIdentifier(token.value);
6197 }
6198
6199 function parseNonComputedMember() {
6200 expect('.');
6201
6202 return parseNonComputedProperty();
6203 }
6204
6205 function parseComputedMember() {
6206 var expr;
6207
6208 expect('[');
6209
6210 expr = isolateCoverGrammar(parseExpression);
6211
6212 expect(']');
6213
6214 return expr;
6215 }
6216
6217 // ECMA-262 12.3.3 The new Operator
6218
6219 function parseNewExpression() {
6220 var callee, args, node = new Node();
6221
6222 expectKeyword('new');
6223
6224 if (match('.')) {
6225 lex();
6226 if (lookahead.type === Token.Identifier && lookahead.value === 'target') {
6227 if (state.inFunctionBody) {
6228 lex();
6229 return node.finishMetaProperty('new', 'target');
6230 }
6231 }
6232 throwUnexpectedToken(lookahead);
6233 }
6234
6235 callee = isolateCoverGrammar(parseLeftHandSideExpression);
6236 args = match('(') ? parseArguments() : [];
6237
6238 isAssignmentTarget = isBindingElement = false;
6239
6240 return node.finishNewExpression(callee, args);
6241 }
6242
6243 // ECMA-262 12.3.4 Function Calls
6244
6245 function parseLeftHandSideExpressionAllowCall() {
6246 var quasi, expr, args, property, startToken, previousAllowIn = state.allowIn;
6247
6248 startToken = lookahead;
6249 state.allowIn = true;
6250
6251 if (matchKeyword('super') && state.inFunctionBody) {
6252 expr = new Node();
6253 lex();
6254 expr = expr.finishSuper();
6255 if (!match('(') && !match('.') && !match('[')) {
6256 throwUnexpectedToken(lookahead);
6257 }
6258 } else {
6259 expr = inheritCoverGrammar(matchKeyword('new') ? parseNewExpression : parsePrimaryExpression);
6260 }
6261
6262 for (;;) {
6263 if (match('.')) {
6264 isBindingElement = false;
6265 isAssignmentTarget = true;
6266 property = parseNonComputedMember();
6267 expr = new WrappingNode(startToken).finishMemberExpression('.', expr, property);
6268 } else if (match('(')) {
6269 isBindingElement = false;
6270 isAssignmentTarget = false;
6271 args = parseArguments();
6272 expr = new WrappingNode(startToken).finishCallExpression(expr, args);
6273 } else if (match('[')) {
6274 isBindingElement = false;
6275 isAssignmentTarget = true;
6276 property = parseComputedMember();
6277 expr = new WrappingNode(startToken).finishMemberExpression('[', expr, property);
6278 } else if (lookahead.type === Token.Template && lookahead.head) {
6279 quasi = parseTemplateLiteral();
6280 expr = new WrappingNode(startToken).finishTaggedTemplateExpression(expr, quasi);
6281 } else {
6282 break;
6283 }
6284 }
6285 state.allowIn = previousAllowIn;
6286
6287 return expr;
6288 }
6289
6290 // ECMA-262 12.3 Left-Hand-Side Expressions
6291
6292 function parseLeftHandSideExpression() {
6293 var quasi, expr, property, startToken;
6294 assert(state.allowIn, 'callee of new expression always allow in keyword.');
6295
6296 startToken = lookahead;
6297
6298 if (matchKeyword('super') && state.inFunctionBody) {
6299 expr = new Node();
6300 lex();
6301 expr = expr.finishSuper();
6302 if (!match('[') && !match('.')) {
6303 throwUnexpectedToken(lookahead);
6304 }
6305 } else {
6306 expr = inheritCoverGrammar(matchKeyword('new') ? parseNewExpression : parsePrimaryExpression);
6307 }
6308
6309 for (;;) {
6310 if (match('[')) {
6311 isBindingElement = false;
6312 isAssignmentTarget = true;
6313 property = parseComputedMember();
6314 expr = new WrappingNode(startToken).finishMemberExpression('[', expr, property);
6315 } else if (match('.')) {
6316 isBindingElement = false;
6317 isAssignmentTarget = true;
6318 property = parseNonComputedMember();
6319 expr = new WrappingNode(startToken).finishMemberExpression('.', expr, property);
6320 } else if (lookahead.type === Token.Template && lookahead.head) {
6321 quasi = parseTemplateLiteral();
6322 expr = new WrappingNode(startToken).finishTaggedTemplateExpression(expr, quasi);
6323 } else {
6324 break;
6325 }
6326 }
6327 return expr;
6328 }
6329
6330 // ECMA-262 12.4 Postfix Expressions
6331
6332 function parsePostfixExpression() {
6333 var expr, token, startToken = lookahead;
6334
6335 expr = inheritCoverGrammar(parseLeftHandSideExpressionAllowCall);
6336
6337 if (!hasLineTerminator && lookahead.type === Token.Punctuator) {
6338 if (match('++') || match('--')) {
6339 // ECMA-262 11.3.1, 11.3.2
6340 if (strict && expr.type === Syntax.Identifier && isRestrictedWord(expr.name)) {
6341 tolerateError(Messages.StrictLHSPostfix);
6342 }
6343
6344 if (!isAssignmentTarget) {
6345 tolerateError(Messages.InvalidLHSInAssignment);
6346 }
6347
6348 isAssignmentTarget = isBindingElement = false;
6349
6350 token = lex();
6351 expr = new WrappingNode(startToken).finishPostfixExpression(token.value, expr);
6352 }
6353 }
6354
6355 return expr;
6356 }
6357
6358 // ECMA-262 12.5 Unary Operators
6359
6360 function parseUnaryExpression() {
6361 var token, expr, startToken;
6362
6363 if (lookahead.type !== Token.Punctuator && lookahead.type !== Token.Keyword) {
6364 expr = parsePostfixExpression();
6365 } else if (match('++') || match('--')) {
6366 startToken = lookahead;
6367 token = lex();
6368 expr = inheritCoverGrammar(parseUnaryExpression);
6369 // ECMA-262 11.4.4, 11.4.5
6370 if (strict && expr.type === Syntax.Identifier && isRestrictedWord(expr.name)) {
6371 tolerateError(Messages.StrictLHSPrefix);
6372 }
6373
6374 if (!isAssignmentTarget) {
6375 tolerateError(Messages.InvalidLHSInAssignment);
6376 }
6377 expr = new WrappingNode(startToken).finishUnaryExpression(token.value, expr);
6378 isAssignmentTarget = isBindingElement = false;
6379 } else if (match('+') || match('-') || match('~') || match('!')) {
6380 startToken = lookahead;
6381 token = lex();
6382 expr = inheritCoverGrammar(parseUnaryExpression);
6383 expr = new WrappingNode(startToken).finishUnaryExpression(token.value, expr);
6384 isAssignmentTarget = isBindingElement = false;
6385 } else if (matchKeyword('delete') || matchKeyword('void') || matchKeyword('typeof')) {
6386 startToken = lookahead;
6387 token = lex();
6388 expr = inheritCoverGrammar(parseUnaryExpression);
6389 expr = new WrappingNode(startToken).finishUnaryExpression(token.value, expr);
6390 if (strict && expr.operator === 'delete' && expr.argument.type === Syntax.Identifier) {
6391 tolerateError(Messages.StrictDelete);
6392 }
6393 isAssignmentTarget = isBindingElement = false;
6394 } else {
6395 expr = parsePostfixExpression();
6396 }
6397
6398 return expr;
6399 }
6400
6401 function binaryPrecedence(token, allowIn) {
6402 var prec = 0;
6403
6404 if (token.type !== Token.Punctuator && token.type !== Token.Keyword) {
6405 return 0;
6406 }
6407
6408 switch (token.value) {
6409 case '||':
6410 prec = 1;
6411 break;
6412
6413 case '&&':
6414 prec = 2;
6415 break;
6416
6417 case '|':
6418 prec = 3;
6419 break;
6420
6421 case '^':
6422 prec = 4;
6423 break;
6424
6425 case '&':
6426 prec = 5;
6427 break;
6428
6429 case '==':
6430 case '!=':
6431 case '===':
6432 case '!==':
6433 prec = 6;
6434 break;
6435
6436 case '<':
6437 case '>':
6438 case '<=':
6439 case '>=':
6440 case 'instanceof':
6441 prec = 7;
6442 break;
6443
6444 case 'in':
6445 prec = allowIn ? 7 : 0;
6446 break;
6447
6448 case '<<':
6449 case '>>':
6450 case '>>>':
6451 prec = 8;
6452 break;
6453
6454 case '+':
6455 case '-':
6456 prec = 9;
6457 break;
6458
6459 case '*':
6460 case '/':
6461 case '%':
6462 prec = 11;
6463 break;
6464
6465 default:
6466 break;
6467 }
6468
6469 return prec;
6470 }
6471
6472 // ECMA-262 12.6 Multiplicative Operators
6473 // ECMA-262 12.7 Additive Operators
6474 // ECMA-262 12.8 Bitwise Shift Operators
6475 // ECMA-262 12.9 Relational Operators
6476 // ECMA-262 12.10 Equality Operators
6477 // ECMA-262 12.11 Binary Bitwise Operators
6478 // ECMA-262 12.12 Binary Logical Operators
6479
6480 function parseBinaryExpression() {
6481 var marker, markers, expr, token, prec, stack, right, operator, left, i;
6482
6483 marker = lookahead;
6484 left = inheritCoverGrammar(parseUnaryExpression);
6485
6486 token = lookahead;
6487 prec = binaryPrecedence(token, state.allowIn);
6488 if (prec === 0) {
6489 return left;
6490 }
6491 isAssignmentTarget = isBindingElement = false;
6492 token.prec = prec;
6493 lex();
6494
6495 markers = [marker, lookahead];
6496 right = isolateCoverGrammar(parseUnaryExpression);
6497
6498 stack = [left, token, right];
6499
6500 while ((prec = binaryPrecedence(lookahead, state.allowIn)) > 0) {
6501
6502 // Reduce: make a binary expression from the three topmost entries.
6503 while ((stack.length > 2) && (prec <= stack[stack.length - 2].prec)) {
6504 right = stack.pop();
6505 operator = stack.pop().value;
6506 left = stack.pop();
6507 markers.pop();
6508 expr = new WrappingNode(markers[markers.length - 1]).finishBinaryExpression(operator, left, right);
6509 stack.push(expr);
6510 }
6511
6512 // Shift.
6513 token = lex();
6514 token.prec = prec;
6515 stack.push(token);
6516 markers.push(lookahead);
6517 expr = isolateCoverGrammar(parseUnaryExpression);
6518 stack.push(expr);
6519 }
6520
6521 // Final reduce to clean-up the stack.
6522 i = stack.length - 1;
6523 expr = stack[i];
6524 markers.pop();
6525 while (i > 1) {
6526 expr = new WrappingNode(markers.pop()).finishBinaryExpression(stack[i - 1].value, stack[i - 2], expr);
6527 i -= 2;
6528 }
6529
6530 return expr;
6531 }
6532
6533
6534 // ECMA-262 12.13 Conditional Operator
6535
6536 function parseConditionalExpression() {
6537 var expr, previousAllowIn, consequent, alternate, startToken;
6538
6539 startToken = lookahead;
6540
6541 expr = inheritCoverGrammar(parseBinaryExpression);
6542 if (match('?')) {
6543 lex();
6544 previousAllowIn = state.allowIn;
6545 state.allowIn = true;
6546 consequent = isolateCoverGrammar(parseAssignmentExpression);
6547 state.allowIn = previousAllowIn;
6548 expect(':');
6549 alternate = isolateCoverGrammar(parseAssignmentExpression);
6550
6551 expr = new WrappingNode(startToken).finishConditionalExpression(expr, consequent, alternate);
6552 isAssignmentTarget = isBindingElement = false;
6553 }
6554
6555 return expr;
6556 }
6557
6558 // ECMA-262 14.2 Arrow Function Definitions
6559
6560 function parseConciseBody() {
6561 if (match('{')) {
6562 return parseFunctionSourceElements();
6563 }
6564 return isolateCoverGrammar(parseAssignmentExpression);
6565 }
6566
6567 function checkPatternParam(options, param) {
6568 var i;
6569 switch (param.type) {
6570 case Syntax.Identifier:
6571 validateParam(options, param, param.name);
6572 break;
6573 case Syntax.RestElement:
6574 checkPatternParam(options, param.argument);
6575 break;
6576 case Syntax.AssignmentPattern:
6577 checkPatternParam(options, param.left);
6578 break;
6579 case Syntax.ArrayPattern:
6580 for (i = 0; i < param.elements.length; i++) {
6581 if (param.elements[i] !== null) {
6582 checkPatternParam(options, param.elements[i]);
6583 }
6584 }
6585 break;
6586 case Syntax.YieldExpression:
6587 break;
6588 default:
6589 assert(param.type === Syntax.ObjectPattern, 'Invalid type');
6590 for (i = 0; i < param.properties.length; i++) {
6591 checkPatternParam(options, param.properties[i].value);
6592 }
6593 break;
6594 }
6595 }
6596 function reinterpretAsCoverFormalsList(expr) {
6597 var i, len, param, params, defaults, defaultCount, options, token;
6598
6599 defaults = [];
6600 defaultCount = 0;
6601 params = [expr];
6602
6603 switch (expr.type) {
6604 case Syntax.Identifier:
6605 break;
6606 case PlaceHolders.ArrowParameterPlaceHolder:
6607 params = expr.params;
6608 break;
6609 default:
6610 return null;
6611 }
6612
6613 options = {
6614 paramSet: {}
6615 };
6616
6617 for (i = 0, len = params.length; i < len; i += 1) {
6618 param = params[i];
6619 switch (param.type) {
6620 case Syntax.AssignmentPattern:
6621 params[i] = param.left;
6622 if (param.right.type === Syntax.YieldExpression) {
6623 if (param.right.argument) {
6624 throwUnexpectedToken(lookahead);
6625 }
6626 param.right.type = Syntax.Identifier;
6627 param.right.name = 'yield';
6628 delete param.right.argument;
6629 delete param.right.delegate;
6630 }
6631 defaults.push(param.right);
6632 ++defaultCount;
6633 checkPatternParam(options, param.left);
6634 break;
6635 default:
6636 checkPatternParam(options, param);
6637 params[i] = param;
6638 defaults.push(null);
6639 break;
6640 }
6641 }
6642
6643 if (strict || !state.allowYield) {
6644 for (i = 0, len = params.length; i < len; i += 1) {
6645 param = params[i];
6646 if (param.type === Syntax.YieldExpression) {
6647 throwUnexpectedToken(lookahead);
6648 }
6649 }
6650 }
6651
6652 if (options.message === Messages.StrictParamDupe) {
6653 token = strict ? options.stricted : options.firstRestricted;
6654 throwUnexpectedToken(token, options.message);
6655 }
6656
6657 if (defaultCount === 0) {
6658 defaults = [];
6659 }
6660
6661 return {
6662 params: params,
6663 defaults: defaults,
6664 stricted: options.stricted,
6665 firstRestricted: options.firstRestricted,
6666 message: options.message
6667 };
6668 }
6669
6670 function parseArrowFunctionExpression(options, node) {
6671 var previousStrict, previousAllowYield, body;
6672
6673 if (hasLineTerminator) {
6674 tolerateUnexpectedToken(lookahead);
6675 }
6676 expect('=>');
6677
6678 previousStrict = strict;
6679 previousAllowYield = state.allowYield;
6680 state.allowYield = true;
6681
6682 body = parseConciseBody();
6683
6684 if (strict && options.firstRestricted) {
6685 throwUnexpectedToken(options.firstRestricted, options.message);
6686 }
6687 if (strict && options.stricted) {
6688 tolerateUnexpectedToken(options.stricted, options.message);
6689 }
6690
6691 strict = previousStrict;
6692 state.allowYield = previousAllowYield;
6693
6694 return node.finishArrowFunctionExpression(options.params, options.defaults, body, body.type !== Syntax.BlockStatement);
6695 }
6696
6697 // ECMA-262 14.4 Yield expression
6698
6699 function parseYieldExpression() {
6700 var argument, expr, delegate, previousAllowYield;
6701
6702 argument = null;
6703 expr = new Node();
6704
6705 expectKeyword('yield');
6706
6707 if (!hasLineTerminator) {
6708 previousAllowYield = state.allowYield;
6709 state.allowYield = false;
6710 delegate = match('*');
6711 if (delegate) {
6712 lex();
6713 argument = parseAssignmentExpression();
6714 } else {
6715 if (!match(';') && !match('}') && !match(')') && lookahead.type !== Token.EOF) {
6716 argument = parseAssignmentExpression();
6717 }
6718 }
6719 state.allowYield = previousAllowYield;
6720 }
6721
6722 return expr.finishYieldExpression(argument, delegate);
6723 }
6724
6725 // ECMA-262 12.14 Assignment Operators
6726
6727 function parseAssignmentExpression() {
6728 var token, expr, right, list, startToken;
6729
6730 startToken = lookahead;
6731 token = lookahead;
6732
6733 if (!state.allowYield && matchKeyword('yield')) {
6734 return parseYieldExpression();
6735 }
6736
6737 expr = parseConditionalExpression();
6738
6739 if (expr.type === PlaceHolders.ArrowParameterPlaceHolder || match('=>')) {
6740 isAssignmentTarget = isBindingElement = false;
6741 list = reinterpretAsCoverFormalsList(expr);
6742
6743 if (list) {
6744 firstCoverInitializedNameError = null;
6745 return parseArrowFunctionExpression(list, new WrappingNode(startToken));
6746 }
6747
6748 return expr;
6749 }
6750
6751 if (matchAssign()) {
6752 if (!isAssignmentTarget) {
6753 tolerateError(Messages.InvalidLHSInAssignment);
6754 }
6755
6756 // ECMA-262 12.1.1
6757 if (strict && expr.type === Syntax.Identifier) {
6758 if (isRestrictedWord(expr.name)) {
6759 tolerateUnexpectedToken(token, Messages.StrictLHSAssignment);
6760 }
6761 if (isStrictModeReservedWord(expr.name)) {
6762 tolerateUnexpectedToken(token, Messages.StrictReservedWord);
6763 }
6764 }
6765
6766 if (!match('=')) {
6767 isAssignmentTarget = isBindingElement = false;
6768 } else {
6769 reinterpretExpressionAsPattern(expr);
6770 }
6771
6772 token = lex();
6773 right = isolateCoverGrammar(parseAssignmentExpression);
6774 expr = new WrappingNode(startToken).finishAssignmentExpression(token.value, expr, right);
6775 firstCoverInitializedNameError = null;
6776 }
6777
6778 return expr;
6779 }
6780
6781 // ECMA-262 12.15 Comma Operator
6782
6783 function parseExpression() {
6784 var expr, startToken = lookahead, expressions;
6785
6786 expr = isolateCoverGrammar(parseAssignmentExpression);
6787
6788 if (match(',')) {
6789 expressions = [expr];
6790
6791 while (startIndex < length) {
6792 if (!match(',')) {
6793 break;
6794 }
6795 lex();
6796 expressions.push(isolateCoverGrammar(parseAssignmentExpression));
6797 }
6798
6799 expr = new WrappingNode(startToken).finishSequenceExpression(expressions);
6800 }
6801
6802 return expr;
6803 }
6804
6805 // ECMA-262 13.2 Block
6806
6807 function parseStatementListItem() {
6808 if (lookahead.type === Token.Keyword) {
6809 switch (lookahead.value) {
6810 case 'export':
6811 if (state.sourceType !== 'module') {
6812 tolerateUnexpectedToken(lookahead, Messages.IllegalExportDeclaration);
6813 }
6814 return parseExportDeclaration();
6815 case 'import':
6816 if (state.sourceType !== 'module') {
6817 tolerateUnexpectedToken(lookahead, Messages.IllegalImportDeclaration);
6818 }
6819 return parseImportDeclaration();
6820 case 'const':
6821 case 'let':
6822 return parseLexicalDeclaration({inFor: false});
6823 case 'function':
6824 return parseFunctionDeclaration(new Node());
6825 case 'class':
6826 return parseClassDeclaration();
6827 }
6828 }
6829
6830 return parseStatement();
6831 }
6832
6833 function parseStatementList() {
6834 var list = [];
6835 while (startIndex < length) {
6836 if (match('}')) {
6837 break;
6838 }
6839 list.push(parseStatementListItem());
6840 }
6841
6842 return list;
6843 }
6844
6845 function parseBlock() {
6846 var block, node = new Node();
6847
6848 expect('{');
6849
6850 block = parseStatementList();
6851
6852 expect('}');
6853
6854 return node.finishBlockStatement(block);
6855 }
6856
6857 // ECMA-262 13.3.2 Variable Statement
6858
6859 function parseVariableIdentifier(kind) {
6860 var token, node = new Node();
6861
6862 token = lex();
6863
6864 if (token.type === Token.Keyword && token.value === 'yield') {
6865 if (strict) {
6866 tolerateUnexpectedToken(token, Messages.StrictReservedWord);
6867 } if (!state.allowYield) {
6868 throwUnexpectedToken(token);
6869 }
6870 } else if (token.type !== Token.Identifier) {
6871 if (strict && token.type === Token.Keyword && isStrictModeReservedWord(token.value)) {
6872 tolerateUnexpectedToken(token, Messages.StrictReservedWord);
6873 } else {
6874 if (strict || token.value !== 'let' || kind !== 'var') {
6875 throwUnexpectedToken(token);
6876 }
6877 }
6878 } else if (state.sourceType === 'module' && token.type === Token.Identifier && token.value === 'await') {
6879 tolerateUnexpectedToken(token);
6880 }
6881
6882 return node.finishIdentifier(token.value);
6883 }
6884
6885 function parseVariableDeclaration(options) {
6886 var init = null, id, node = new Node(), params = [];
6887
6888 id = parsePattern(params, 'var');
6889
6890 // ECMA-262 12.2.1
6891 if (strict && isRestrictedWord(id.name)) {
6892 tolerateError(Messages.StrictVarName);
6893 }
6894
6895 if (match('=')) {
6896 lex();
6897 init = isolateCoverGrammar(parseAssignmentExpression);
6898 } else if (id.type !== Syntax.Identifier && !options.inFor) {
6899 expect('=');
6900 }
6901
6902 return node.finishVariableDeclarator(id, init);
6903 }
6904
6905 function parseVariableDeclarationList(options) {
6906 var list = [];
6907
6908 do {
6909 list.push(parseVariableDeclaration({ inFor: options.inFor }));
6910 if (!match(',')) {
6911 break;
6912 }
6913 lex();
6914 } while (startIndex < length);
6915
6916 return list;
6917 }
6918
6919 function parseVariableStatement(node) {
6920 var declarations;
6921
6922 expectKeyword('var');
6923
6924 declarations = parseVariableDeclarationList({ inFor: false });
6925
6926 consumeSemicolon();
6927
6928 return node.finishVariableDeclaration(declarations);
6929 }
6930
6931 // ECMA-262 13.3.1 Let and Const Declarations
6932
6933 function parseLexicalBinding(kind, options) {
6934 var init = null, id, node = new Node(), params = [];
6935
6936 id = parsePattern(params, kind);
6937
6938 // ECMA-262 12.2.1
6939 if (strict && id.type === Syntax.Identifier && isRestrictedWord(id.name)) {
6940 tolerateError(Messages.StrictVarName);
6941 }
6942
6943 if (kind === 'const') {
6944 if (!matchKeyword('in') && !matchContextualKeyword('of')) {
6945 expect('=');
6946 init = isolateCoverGrammar(parseAssignmentExpression);
6947 }
6948 } else if ((!options.inFor && id.type !== Syntax.Identifier) || match('=')) {
6949 expect('=');
6950 init = isolateCoverGrammar(parseAssignmentExpression);
6951 }
6952
6953 return node.finishVariableDeclarator(id, init);
6954 }
6955
6956 function parseBindingList(kind, options) {
6957 var list = [];
6958
6959 do {
6960 list.push(parseLexicalBinding(kind, options));
6961 if (!match(',')) {
6962 break;
6963 }
6964 lex();
6965 } while (startIndex < length);
6966
6967 return list;
6968 }
6969
6970 function parseLexicalDeclaration(options) {
6971 var kind, declarations, node = new Node();
6972
6973 kind = lex().value;
6974 assert(kind === 'let' || kind === 'const', 'Lexical declaration must be either let or const');
6975
6976 declarations = parseBindingList(kind, options);
6977
6978 consumeSemicolon();
6979
6980 return node.finishLexicalDeclaration(declarations, kind);
6981 }
6982
6983 function parseRestElement(params) {
6984 var param, node = new Node();
6985
6986 lex();
6987
6988 if (match('{')) {
6989 throwError(Messages.ObjectPatternAsRestParameter);
6990 }
6991
6992 params.push(lookahead);
6993
6994 param = parseVariableIdentifier();
6995
6996 if (match('=')) {
6997 throwError(Messages.DefaultRestParameter);
6998 }
6999
7000 if (!match(')')) {
7001 throwError(Messages.ParameterAfterRestParameter);
7002 }
7003
7004 return node.finishRestElement(param);
7005 }
7006
7007 // ECMA-262 13.4 Empty Statement
7008
7009 function parseEmptyStatement(node) {
7010 expect(';');
7011 return node.finishEmptyStatement();
7012 }
7013
7014 // ECMA-262 12.4 Expression Statement
7015
7016 function parseExpressionStatement(node) {
7017 var expr = parseExpression();
7018 consumeSemicolon();
7019 return node.finishExpressionStatement(expr);
7020 }
7021
7022 // ECMA-262 13.6 If statement
7023
7024 function parseIfStatement(node) {
7025 var test, consequent, alternate;
7026
7027 expectKeyword('if');
7028
7029 expect('(');
7030
7031 test = parseExpression();
7032
7033 expect(')');
7034
7035 consequent = parseStatement();
7036
7037 if (matchKeyword('else')) {
7038 lex();
7039 alternate = parseStatement();
7040 } else {
7041 alternate = null;
7042 }
7043
7044 return node.finishIfStatement(test, consequent, alternate);
7045 }
7046
7047 // ECMA-262 13.7 Iteration Statements
7048
7049 function parseDoWhileStatement(node) {
7050 var body, test, oldInIteration;
7051
7052 expectKeyword('do');
7053
7054 oldInIteration = state.inIteration;
7055 state.inIteration = true;
7056
7057 body = parseStatement();
7058
7059 state.inIteration = oldInIteration;
7060
7061 expectKeyword('while');
7062
7063 expect('(');
7064
7065 test = parseExpression();
7066
7067 expect(')');
7068
7069 if (match(';')) {
7070 lex();
7071 }
7072
7073 return node.finishDoWhileStatement(body, test);
7074 }
7075
7076 function parseWhileStatement(node) {
7077 var test, body, oldInIteration;
7078
7079 expectKeyword('while');
7080
7081 expect('(');
7082
7083 test = parseExpression();
7084
7085 expect(')');
7086
7087 oldInIteration = state.inIteration;
7088 state.inIteration = true;
7089
7090 body = parseStatement();
7091
7092 state.inIteration = oldInIteration;
7093
7094 return node.finishWhileStatement(test, body);
7095 }
7096
7097 function parseForStatement(node) {
7098 var init, forIn, initSeq, initStartToken, test, update, left, right, kind, declarations,
7099 body, oldInIteration, previousAllowIn = state.allowIn;
7100
7101 init = test = update = null;
7102 forIn = true;
7103
7104 expectKeyword('for');
7105
7106 expect('(');
7107
7108 if (match(';')) {
7109 lex();
7110 } else {
7111 if (matchKeyword('var')) {
7112 init = new Node();
7113 lex();
7114
7115 state.allowIn = false;
7116 declarations = parseVariableDeclarationList({ inFor: true });
7117 state.allowIn = previousAllowIn;
7118
7119 if (declarations.length === 1 && matchKeyword('in')) {
7120 init = init.finishVariableDeclaration(declarations);
7121 lex();
7122 left = init;
7123 right = parseExpression();
7124 init = null;
7125 } else if (declarations.length === 1 && declarations[0].init === null && matchContextualKeyword('of')) {
7126 init = init.finishVariableDeclaration(declarations);
7127 lex();
7128 left = init;
7129 right = parseAssignmentExpression();
7130 init = null;
7131 forIn = false;
7132 } else {
7133 init = init.finishVariableDeclaration(declarations);
7134 expect(';');
7135 }
7136 } else if (matchKeyword('const') || matchKeyword('let')) {
7137 init = new Node();
7138 kind = lex().value;
7139
7140 state.allowIn = false;
7141 declarations = parseBindingList(kind, {inFor: true});
7142 state.allowIn = previousAllowIn;
7143
7144 if (declarations.length === 1 && declarations[0].init === null && matchKeyword('in')) {
7145 init = init.finishLexicalDeclaration(declarations, kind);
7146 lex();
7147 left = init;
7148 right = parseExpression();
7149 init = null;
7150 } else if (declarations.length === 1 && declarations[0].init === null && matchContextualKeyword('of')) {
7151 init = init.finishLexicalDeclaration(declarations, kind);
7152 lex();
7153 left = init;
7154 right = parseAssignmentExpression();
7155 init = null;
7156 forIn = false;
7157 } else {
7158 consumeSemicolon();
7159 init = init.finishLexicalDeclaration(declarations, kind);
7160 }
7161 } else {
7162 initStartToken = lookahead;
7163 state.allowIn = false;
7164 init = inheritCoverGrammar(parseAssignmentExpression);
7165 state.allowIn = previousAllowIn;
7166
7167 if (matchKeyword('in')) {
7168 if (!isAssignmentTarget) {
7169 tolerateError(Messages.InvalidLHSInForIn);
7170 }
7171
7172 lex();
7173 reinterpretExpressionAsPattern(init);
7174 left = init;
7175 right = parseExpression();
7176 init = null;
7177 } else if (matchContextualKeyword('of')) {
7178 if (!isAssignmentTarget) {
7179 tolerateError(Messages.InvalidLHSInForLoop);
7180 }
7181
7182 lex();
7183 reinterpretExpressionAsPattern(init);
7184 left = init;
7185 right = parseAssignmentExpression();
7186 init = null;
7187 forIn = false;
7188 } else {
7189 if (match(',')) {
7190 initSeq = [init];
7191 while (match(',')) {
7192 lex();
7193 initSeq.push(isolateCoverGrammar(parseAssignmentExpression));
7194 }
7195 init = new WrappingNode(initStartToken).finishSequenceExpression(initSeq);
7196 }
7197 expect(';');
7198 }
7199 }
7200 }
7201
7202 if (typeof left === 'undefined') {
7203
7204 if (!match(';')) {
7205 test = parseExpression();
7206 }
7207 expect(';');
7208
7209 if (!match(')')) {
7210 update = parseExpression();
7211 }
7212 }
7213
7214 expect(')');
7215
7216 oldInIteration = state.inIteration;
7217 state.inIteration = true;
7218
7219 body = isolateCoverGrammar(parseStatement);
7220
7221 state.inIteration = oldInIteration;
7222
7223 return (typeof left === 'undefined') ?
7224 node.finishForStatement(init, test, update, body) :
7225 forIn ? node.finishForInStatement(left, right, body) :
7226 node.finishForOfStatement(left, right, body);
7227 }
7228
7229 // ECMA-262 13.8 The continue statement
7230
7231 function parseContinueStatement(node) {
7232 var label = null, key;
7233
7234 expectKeyword('continue');
7235
7236 // Optimize the most common form: 'continue;'.
7237 if (source.charCodeAt(startIndex) === 0x3B) {
7238 lex();
7239
7240 if (!state.inIteration) {
7241 throwError(Messages.IllegalContinue);
7242 }
7243
7244 return node.finishContinueStatement(null);
7245 }
7246
7247 if (hasLineTerminator) {
7248 if (!state.inIteration) {
7249 throwError(Messages.IllegalContinue);
7250 }
7251
7252 return node.finishContinueStatement(null);
7253 }
7254
7255 if (lookahead.type === Token.Identifier) {
7256 label = parseVariableIdentifier();
7257
7258 key = '$' + label.name;
7259 if (!Object.prototype.hasOwnProperty.call(state.labelSet, key)) {
7260 throwError(Messages.UnknownLabel, label.name);
7261 }
7262 }
7263
7264 consumeSemicolon();
7265
7266 if (label === null && !state.inIteration) {
7267 throwError(Messages.IllegalContinue);
7268 }
7269
7270 return node.finishContinueStatement(label);
7271 }
7272
7273 // ECMA-262 13.9 The break statement
7274
7275 function parseBreakStatement(node) {
7276 var label = null, key;
7277
7278 expectKeyword('break');
7279
7280 // Catch the very common case first: immediately a semicolon (U+003B).
7281 if (source.charCodeAt(lastIndex) === 0x3B) {
7282 lex();
7283
7284 if (!(state.inIteration || state.inSwitch)) {
7285 throwError(Messages.IllegalBreak);
7286 }
7287
7288 return node.finishBreakStatement(null);
7289 }
7290
7291 if (hasLineTerminator) {
7292 if (!(state.inIteration || state.inSwitch)) {
7293 throwError(Messages.IllegalBreak);
7294 }
7295
7296 return node.finishBreakStatement(null);
7297 }
7298
7299 if (lookahead.type === Token.Identifier) {
7300 label = parseVariableIdentifier();
7301
7302 key = '$' + label.name;
7303 if (!Object.prototype.hasOwnProperty.call(state.labelSet, key)) {
7304 throwError(Messages.UnknownLabel, label.name);
7305 }
7306 }
7307
7308 consumeSemicolon();
7309
7310 if (label === null && !(state.inIteration || state.inSwitch)) {
7311 throwError(Messages.IllegalBreak);
7312 }
7313
7314 return node.finishBreakStatement(label);
7315 }
7316
7317 // ECMA-262 13.10 The return statement
7318
7319 function parseReturnStatement(node) {
7320 var argument = null;
7321
7322 expectKeyword('return');
7323
7324 if (!state.inFunctionBody) {
7325 tolerateError(Messages.IllegalReturn);
7326 }
7327
7328 // 'return' followed by a space and an identifier is very common.
7329 if (source.charCodeAt(lastIndex) === 0x20) {
7330 if (isIdentifierStart(source.charCodeAt(lastIndex + 1))) {
7331 argument = parseExpression();
7332 consumeSemicolon();
7333 return node.finishReturnStatement(argument);
7334 }
7335 }
7336
7337 if (hasLineTerminator) {
7338 // HACK
7339 return node.finishReturnStatement(null);
7340 }
7341
7342 if (!match(';')) {
7343 if (!match('}') && lookahead.type !== Token.EOF) {
7344 argument = parseExpression();
7345 }
7346 }
7347
7348 consumeSemicolon();
7349
7350 return node.finishReturnStatement(argument);
7351 }
7352
7353 // ECMA-262 13.11 The with statement
7354
7355 function parseWithStatement(node) {
7356 var object, body;
7357
7358 if (strict) {
7359 tolerateError(Messages.StrictModeWith);
7360 }
7361
7362 expectKeyword('with');
7363
7364 expect('(');
7365
7366 object = parseExpression();
7367
7368 expect(')');
7369
7370 body = parseStatement();
7371
7372 return node.finishWithStatement(object, body);
7373 }
7374
7375 // ECMA-262 13.12 The switch statement
7376
7377 function parseSwitchCase() {
7378 var test, consequent = [], statement, node = new Node();
7379
7380 if (matchKeyword('default')) {
7381 lex();
7382 test = null;
7383 } else {
7384 expectKeyword('case');
7385 test = parseExpression();
7386 }
7387 expect(':');
7388
7389 while (startIndex < length) {
7390 if (match('}') || matchKeyword('default') || matchKeyword('case')) {
7391 break;
7392 }
7393 statement = parseStatementListItem();
7394 consequent.push(statement);
7395 }
7396
7397 return node.finishSwitchCase(test, consequent);
7398 }
7399
7400 function parseSwitchStatement(node) {
7401 var discriminant, cases, clause, oldInSwitch, defaultFound;
7402
7403 expectKeyword('switch');
7404
7405 expect('(');
7406
7407 discriminant = parseExpression();
7408
7409 expect(')');
7410
7411 expect('{');
7412
7413 cases = [];
7414
7415 if (match('}')) {
7416 lex();
7417 return node.finishSwitchStatement(discriminant, cases);
7418 }
7419
7420 oldInSwitch = state.inSwitch;
7421 state.inSwitch = true;
7422 defaultFound = false;
7423
7424 while (startIndex < length) {
7425 if (match('}')) {
7426 break;
7427 }
7428 clause = parseSwitchCase();
7429 if (clause.test === null) {
7430 if (defaultFound) {
7431 throwError(Messages.MultipleDefaultsInSwitch);
7432 }
7433 defaultFound = true;
7434 }
7435 cases.push(clause);
7436 }
7437
7438 state.inSwitch = oldInSwitch;
7439
7440 expect('}');
7441
7442 return node.finishSwitchStatement(discriminant, cases);
7443 }
7444
7445 // ECMA-262 13.14 The throw statement
7446
7447 function parseThrowStatement(node) {
7448 var argument;
7449
7450 expectKeyword('throw');
7451
7452 if (hasLineTerminator) {
7453 throwError(Messages.NewlineAfterThrow);
7454 }
7455
7456 argument = parseExpression();
7457
7458 consumeSemicolon();
7459
7460 return node.finishThrowStatement(argument);
7461 }
7462
7463 // ECMA-262 13.15 The try statement
7464
7465 function parseCatchClause() {
7466 var param, params = [], paramMap = {}, key, i, body, node = new Node();
7467
7468 expectKeyword('catch');
7469
7470 expect('(');
7471 if (match(')')) {
7472 throwUnexpectedToken(lookahead);
7473 }
7474
7475 param = parsePattern(params);
7476 for (i = 0; i < params.length; i++) {
7477 key = '$' + params[i].value;
7478 if (Object.prototype.hasOwnProperty.call(paramMap, key)) {
7479 tolerateError(Messages.DuplicateBinding, params[i].value);
7480 }
7481 paramMap[key] = true;
7482 }
7483
7484 // ECMA-262 12.14.1
7485 if (strict && isRestrictedWord(param.name)) {
7486 tolerateError(Messages.StrictCatchVariable);
7487 }
7488
7489 expect(')');
7490 body = parseBlock();
7491 return node.finishCatchClause(param, body);
7492 }
7493
7494 function parseTryStatement(node) {
7495 var block, handler = null, finalizer = null;
7496
7497 expectKeyword('try');
7498
7499 block = parseBlock();
7500
7501 if (matchKeyword('catch')) {
7502 handler = parseCatchClause();
7503 }
7504
7505 if (matchKeyword('finally')) {
7506 lex();
7507 finalizer = parseBlock();
7508 }
7509
7510 if (!handler && !finalizer) {
7511 throwError(Messages.NoCatchOrFinally);
7512 }
7513
7514 return node.finishTryStatement(block, handler, finalizer);
7515 }
7516
7517 // ECMA-262 13.16 The debugger statement
7518
7519 function parseDebuggerStatement(node) {
7520 expectKeyword('debugger');
7521
7522 consumeSemicolon();
7523
7524 return node.finishDebuggerStatement();
7525 }
7526
7527 // 13 Statements
7528
7529 function parseStatement() {
7530 var type = lookahead.type,
7531 expr,
7532 labeledBody,
7533 key,
7534 node;
7535
7536 if (type === Token.EOF) {
7537 throwUnexpectedToken(lookahead);
7538 }
7539
7540 if (type === Token.Punctuator && lookahead.value === '{') {
7541 return parseBlock();
7542 }
7543 isAssignmentTarget = isBindingElement = true;
7544 node = new Node();
7545
7546 if (type === Token.Punctuator) {
7547 switch (lookahead.value) {
7548 case ';':
7549 return parseEmptyStatement(node);
7550 case '(':
7551 return parseExpressionStatement(node);
7552 default:
7553 break;
7554 }
7555 } else if (type === Token.Keyword) {
7556 switch (lookahead.value) {
7557 case 'break':
7558 return parseBreakStatement(node);
7559 case 'continue':
7560 return parseContinueStatement(node);
7561 case 'debugger':
7562 return parseDebuggerStatement(node);
7563 case 'do':
7564 return parseDoWhileStatement(node);
7565 case 'for':
7566 return parseForStatement(node);
7567 case 'function':
7568 return parseFunctionDeclaration(node);
7569 case 'if':
7570 return parseIfStatement(node);
7571 case 'return':
7572 return parseReturnStatement(node);
7573 case 'switch':
7574 return parseSwitchStatement(node);
7575 case 'throw':
7576 return parseThrowStatement(node);
7577 case 'try':
7578 return parseTryStatement(node);
7579 case 'var':
7580 return parseVariableStatement(node);
7581 case 'while':
7582 return parseWhileStatement(node);
7583 case 'with':
7584 return parseWithStatement(node);
7585 default:
7586 break;
7587 }
7588 }
7589
7590 expr = parseExpression();
7591
7592 // ECMA-262 12.12 Labelled Statements
7593 if ((expr.type === Syntax.Identifier) && match(':')) {
7594 lex();
7595
7596 key = '$' + expr.name;
7597 if (Object.prototype.hasOwnProperty.call(state.labelSet, key)) {
7598 throwError(Messages.Redeclaration, 'Label', expr.name);
7599 }
7600
7601 state.labelSet[key] = true;
7602 labeledBody = parseStatement();
7603 delete state.labelSet[key];
7604 return node.finishLabeledStatement(expr, labeledBody);
7605 }
7606
7607 consumeSemicolon();
7608
7609 return node.finishExpressionStatement(expr);
7610 }
7611
7612 // ECMA-262 14.1 Function Definition
7613
7614 function parseFunctionSourceElements() {
7615 var statement, body = [], token, directive, firstRestricted,
7616 oldLabelSet, oldInIteration, oldInSwitch, oldInFunctionBody, oldParenthesisCount,
7617 node = new Node();
7618
7619 expect('{');
7620
7621 while (startIndex < length) {
7622 if (lookahead.type !== Token.StringLiteral) {
7623 break;
7624 }
7625 token = lookahead;
7626
7627 statement = parseStatementListItem();
7628 body.push(statement);
7629 if (statement.expression.type !== Syntax.Literal) {
7630 // this is not directive
7631 break;
7632 }
7633 directive = source.slice(token.start + 1, token.end - 1);
7634 if (directive === 'use strict') {
7635 strict = true;
7636 if (firstRestricted) {
7637 tolerateUnexpectedToken(firstRestricted, Messages.StrictOctalLiteral);
7638 }
7639 } else {
7640 if (!firstRestricted && token.octal) {
7641 firstRestricted = token;
7642 }
7643 }
7644 }
7645
7646 oldLabelSet = state.labelSet;
7647 oldInIteration = state.inIteration;
7648 oldInSwitch = state.inSwitch;
7649 oldInFunctionBody = state.inFunctionBody;
7650 oldParenthesisCount = state.parenthesizedCount;
7651
7652 state.labelSet = {};
7653 state.inIteration = false;
7654 state.inSwitch = false;
7655 state.inFunctionBody = true;
7656 state.parenthesizedCount = 0;
7657
7658 while (startIndex < length) {
7659 if (match('}')) {
7660 break;
7661 }
7662 body.push(parseStatementListItem());
7663 }
7664
7665 expect('}');
7666
7667 state.labelSet = oldLabelSet;
7668 state.inIteration = oldInIteration;
7669 state.inSwitch = oldInSwitch;
7670 state.inFunctionBody = oldInFunctionBody;
7671 state.parenthesizedCount = oldParenthesisCount;
7672
7673 return node.finishBlockStatement(body);
7674 }
7675
7676 function validateParam(options, param, name) {
7677 var key = '$' + name;
7678 if (strict) {
7679 if (isRestrictedWord(name)) {
7680 options.stricted = param;
7681 options.message = Messages.StrictParamName;
7682 }
7683 if (Object.prototype.hasOwnProperty.call(options.paramSet, key)) {
7684 options.stricted = param;
7685 options.message = Messages.StrictParamDupe;
7686 }
7687 } else if (!options.firstRestricted) {
7688 if (isRestrictedWord(name)) {
7689 options.firstRestricted = param;
7690 options.message = Messages.StrictParamName;
7691 } else if (isStrictModeReservedWord(name)) {
7692 options.firstRestricted = param;
7693 options.message = Messages.StrictReservedWord;
7694 } else if (Object.prototype.hasOwnProperty.call(options.paramSet, key)) {
7695 options.stricted = param;
7696 options.message = Messages.StrictParamDupe;
7697 }
7698 }
7699 options.paramSet[key] = true;
7700 }
7701
7702 function parseParam(options) {
7703 var token, param, params = [], i, def;
7704
7705 token = lookahead;
7706 if (token.value === '...') {
7707 param = parseRestElement(params);
7708 validateParam(options, param.argument, param.argument.name);
7709 options.params.push(param);
7710 options.defaults.push(null);
7711 return false;
7712 }
7713
7714 param = parsePatternWithDefault(params);
7715 for (i = 0; i < params.length; i++) {
7716 validateParam(options, params[i], params[i].value);
7717 }
7718
7719 if (param.type === Syntax.AssignmentPattern) {
7720 def = param.right;
7721 param = param.left;
7722 ++options.defaultCount;
7723 }
7724
7725 options.params.push(param);
7726 options.defaults.push(def);
7727
7728 return !match(')');
7729 }
7730
7731 function parseParams(firstRestricted) {
7732 var options;
7733
7734 options = {
7735 params: [],
7736 defaultCount: 0,
7737 defaults: [],
7738 firstRestricted: firstRestricted
7739 };
7740
7741 expect('(');
7742
7743 if (!match(')')) {
7744 options.paramSet = {};
7745 while (startIndex < length) {
7746 if (!parseParam(options)) {
7747 break;
7748 }
7749 expect(',');
7750 }
7751 }
7752
7753 expect(')');
7754
7755 if (options.defaultCount === 0) {
7756 options.defaults = [];
7757 }
7758
7759 return {
7760 params: options.params,
7761 defaults: options.defaults,
7762 stricted: options.stricted,
7763 firstRestricted: options.firstRestricted,
7764 message: options.message
7765 };
7766 }
7767
7768 function parseFunctionDeclaration(node, identifierIsOptional) {
7769 var id = null, params = [], defaults = [], body, token, stricted, tmp, firstRestricted, message, previousStrict,
7770 isGenerator, previousAllowYield;
7771
7772 previousAllowYield = state.allowYield;
7773
7774 expectKeyword('function');
7775
7776 isGenerator = match('*');
7777 if (isGenerator) {
7778 lex();
7779 }
7780
7781 if (!identifierIsOptional || !match('(')) {
7782 token = lookahead;
7783 id = parseVariableIdentifier();
7784 if (strict) {
7785 if (isRestrictedWord(token.value)) {
7786 tolerateUnexpectedToken(token, Messages.StrictFunctionName);
7787 }
7788 } else {
7789 if (isRestrictedWord(token.value)) {
7790 firstRestricted = token;
7791 message = Messages.StrictFunctionName;
7792 } else if (isStrictModeReservedWord(token.value)) {
7793 firstRestricted = token;
7794 message = Messages.StrictReservedWord;
7795 }
7796 }
7797 }
7798
7799 state.allowYield = !isGenerator;
7800 tmp = parseParams(firstRestricted);
7801 params = tmp.params;
7802 defaults = tmp.defaults;
7803 stricted = tmp.stricted;
7804 firstRestricted = tmp.firstRestricted;
7805 if (tmp.message) {
7806 message = tmp.message;
7807 }
7808
7809
7810 previousStrict = strict;
7811 body = parseFunctionSourceElements();
7812 if (strict && firstRestricted) {
7813 throwUnexpectedToken(firstRestricted, message);
7814 }
7815 if (strict && stricted) {
7816 tolerateUnexpectedToken(stricted, message);
7817 }
7818
7819 strict = previousStrict;
7820 state.allowYield = previousAllowYield;
7821
7822 return node.finishFunctionDeclaration(id, params, defaults, body, isGenerator);
7823 }
7824
7825 function parseFunctionExpression() {
7826 var token, id = null, stricted, firstRestricted, message, tmp,
7827 params = [], defaults = [], body, previousStrict, node = new Node(),
7828 isGenerator, previousAllowYield;
7829
7830 previousAllowYield = state.allowYield;
7831
7832 expectKeyword('function');
7833
7834 isGenerator = match('*');
7835 if (isGenerator) {
7836 lex();
7837 }
7838
7839 state.allowYield = !isGenerator;
7840 if (!match('(')) {
7841 token = lookahead;
7842 id = (!strict && !isGenerator && matchKeyword('yield')) ? parseNonComputedProperty() : parseVariableIdentifier();
7843 if (strict) {
7844 if (isRestrictedWord(token.value)) {
7845 tolerateUnexpectedToken(token, Messages.StrictFunctionName);
7846 }
7847 } else {
7848 if (isRestrictedWord(token.value)) {
7849 firstRestricted = token;
7850 message = Messages.StrictFunctionName;
7851 } else if (isStrictModeReservedWord(token.value)) {
7852 firstRestricted = token;
7853 message = Messages.StrictReservedWord;
7854 }
7855 }
7856 }
7857
7858 tmp = parseParams(firstRestricted);
7859 params = tmp.params;
7860 defaults = tmp.defaults;
7861 stricted = tmp.stricted;
7862 firstRestricted = tmp.firstRestricted;
7863 if (tmp.message) {
7864 message = tmp.message;
7865 }
7866
7867 previousStrict = strict;
7868 body = parseFunctionSourceElements();
7869 if (strict && firstRestricted) {
7870 throwUnexpectedToken(firstRestricted, message);
7871 }
7872 if (strict && stricted) {
7873 tolerateUnexpectedToken(stricted, message);
7874 }
7875 strict = previousStrict;
7876 state.allowYield = previousAllowYield;
7877
7878 return node.finishFunctionExpression(id, params, defaults, body, isGenerator);
7879 }
7880
7881 // ECMA-262 14.5 Class Definitions
7882
7883 function parseClassBody() {
7884 var classBody, token, isStatic, hasConstructor = false, body, method, computed, key;
7885
7886 classBody = new Node();
7887
7888 expect('{');
7889 body = [];
7890 while (!match('}')) {
7891 if (match(';')) {
7892 lex();
7893 } else {
7894 method = new Node();
7895 token = lookahead;
7896 isStatic = false;
7897 computed = match('[');
7898 if (match('*')) {
7899 lex();
7900 } else {
7901 key = parseObjectPropertyKey();
7902 if (key.name === 'static' && (lookaheadPropertyName() || match('*'))) {
7903 token = lookahead;
7904 isStatic = true;
7905 computed = match('[');
7906 if (match('*')) {
7907 lex();
7908 } else {
7909 key = parseObjectPropertyKey();
7910 }
7911 }
7912 }
7913 method = tryParseMethodDefinition(token, key, computed, method);
7914 if (method) {
7915 method['static'] = isStatic; // jscs:ignore requireDotNotation
7916 if (method.kind === 'init') {
7917 method.kind = 'method';
7918 }
7919 if (!isStatic) {
7920 if (!method.computed && (method.key.name || method.key.value.toString()) === 'constructor') {
7921 if (method.kind !== 'method' || !method.method || method.value.generator) {
7922 throwUnexpectedToken(token, Messages.ConstructorSpecialMethod);
7923 }
7924 if (hasConstructor) {
7925 throwUnexpectedToken(token, Messages.DuplicateConstructor);
7926 } else {
7927 hasConstructor = true;
7928 }
7929 method.kind = 'constructor';
7930 }
7931 } else {
7932 if (!method.computed && (method.key.name || method.key.value.toString()) === 'prototype') {
7933 throwUnexpectedToken(token, Messages.StaticPrototype);
7934 }
7935 }
7936 method.type = Syntax.MethodDefinition;
7937 delete method.method;
7938 delete method.shorthand;
7939 body.push(method);
7940 } else {
7941 throwUnexpectedToken(lookahead);
7942 }
7943 }
7944 }
7945 lex();
7946 return classBody.finishClassBody(body);
7947 }
7948
7949 function parseClassDeclaration(identifierIsOptional) {
7950 var id = null, superClass = null, classNode = new Node(), classBody, previousStrict = strict;
7951 strict = true;
7952
7953 expectKeyword('class');
7954
7955 if (!identifierIsOptional || lookahead.type === Token.Identifier) {
7956 id = parseVariableIdentifier();
7957 }
7958
7959 if (matchKeyword('extends')) {
7960 lex();
7961 superClass = isolateCoverGrammar(parseLeftHandSideExpressionAllowCall);
7962 }
7963 classBody = parseClassBody();
7964 strict = previousStrict;
7965
7966 return classNode.finishClassDeclaration(id, superClass, classBody);
7967 }
7968
7969 function parseClassExpression() {
7970 var id = null, superClass = null, classNode = new Node(), classBody, previousStrict = strict;
7971 strict = true;
7972
7973 expectKeyword('class');
7974
7975 if (lookahead.type === Token.Identifier) {
7976 id = parseVariableIdentifier();
7977 }
7978
7979 if (matchKeyword('extends')) {
7980 lex();
7981 superClass = isolateCoverGrammar(parseLeftHandSideExpressionAllowCall);
7982 }
7983 classBody = parseClassBody();
7984 strict = previousStrict;
7985
7986 return classNode.finishClassExpression(id, superClass, classBody);
7987 }
7988
7989 // ECMA-262 15.2 Modules
7990
7991 function parseModuleSpecifier() {
7992 var node = new Node();
7993
7994 if (lookahead.type !== Token.StringLiteral) {
7995 throwError(Messages.InvalidModuleSpecifier);
7996 }
7997 return node.finishLiteral(lex());
7998 }
7999
8000 // ECMA-262 15.2.3 Exports
8001
8002 function parseExportSpecifier() {
8003 var exported, local, node = new Node(), def;
8004 if (matchKeyword('default')) {
8005 // export {default} from 'something';
8006 def = new Node();
8007 lex();
8008 local = def.finishIdentifier('default');
8009 } else {
8010 local = parseVariableIdentifier();
8011 }
8012 if (matchContextualKeyword('as')) {
8013 lex();
8014 exported = parseNonComputedProperty();
8015 }
8016 return node.finishExportSpecifier(local, exported);
8017 }
8018
8019 function parseExportNamedDeclaration(node) {
8020 var declaration = null,
8021 isExportFromIdentifier,
8022 src = null, specifiers = [];
8023
8024 // non-default export
8025 if (lookahead.type === Token.Keyword) {
8026 // covers:
8027 // export var f = 1;
8028 switch (lookahead.value) {
8029 case 'let':
8030 case 'const':
8031 case 'var':
8032 case 'class':
8033 case 'function':
8034 declaration = parseStatementListItem();
8035 return node.finishExportNamedDeclaration(declaration, specifiers, null);
8036 }
8037 }
8038
8039 expect('{');
8040 while (!match('}')) {
8041 isExportFromIdentifier = isExportFromIdentifier || matchKeyword('default');
8042 specifiers.push(parseExportSpecifier());
8043 if (!match('}')) {
8044 expect(',');
8045 if (match('}')) {
8046 break;
8047 }
8048 }
8049 }
8050 expect('}');
8051
8052 if (matchContextualKeyword('from')) {
8053 // covering:
8054 // export {default} from 'foo';
8055 // export {foo} from 'foo';
8056 lex();
8057 src = parseModuleSpecifier();
8058 consumeSemicolon();
8059 } else if (isExportFromIdentifier) {
8060 // covering:
8061 // export {default}; // missing fromClause
8062 throwError(lookahead.value ?
8063 Messages.UnexpectedToken : Messages.MissingFromClause, lookahead.value);
8064 } else {
8065 // cover
8066 // export {foo};
8067 consumeSemicolon();
8068 }
8069 return node.finishExportNamedDeclaration(declaration, specifiers, src);
8070 }
8071
8072 function parseExportDefaultDeclaration(node) {
8073 var declaration = null,
8074 expression = null;
8075
8076 // covers:
8077 // export default ...
8078 expectKeyword('default');
8079
8080 if (matchKeyword('function')) {
8081 // covers:
8082 // export default function foo () {}
8083 // export default function () {}
8084 declaration = parseFunctionDeclaration(new Node(), true);
8085 return node.finishExportDefaultDeclaration(declaration);
8086 }
8087 if (matchKeyword('class')) {
8088 declaration = parseClassDeclaration(true);
8089 return node.finishExportDefaultDeclaration(declaration);
8090 }
8091
8092 if (matchContextualKeyword('from')) {
8093 throwError(Messages.UnexpectedToken, lookahead.value);
8094 }
8095
8096 // covers:
8097 // export default {};
8098 // export default [];
8099 // export default (1 + 2);
8100 if (match('{')) {
8101 expression = parseObjectInitializer();
8102 } else if (match('[')) {
8103 expression = parseArrayInitializer();
8104 } else {
8105 expression = parseAssignmentExpression();
8106 }
8107 consumeSemicolon();
8108 return node.finishExportDefaultDeclaration(expression);
8109 }
8110
8111 function parseExportAllDeclaration(node) {
8112 var src;
8113
8114 // covers:
8115 // export * from 'foo';
8116 expect('*');
8117 if (!matchContextualKeyword('from')) {
8118 throwError(lookahead.value ?
8119 Messages.UnexpectedToken : Messages.MissingFromClause, lookahead.value);
8120 }
8121 lex();
8122 src = parseModuleSpecifier();
8123 consumeSemicolon();
8124
8125 return node.finishExportAllDeclaration(src);
8126 }
8127
8128 function parseExportDeclaration() {
8129 var node = new Node();
8130 if (state.inFunctionBody) {
8131 throwError(Messages.IllegalExportDeclaration);
8132 }
8133
8134 expectKeyword('export');
8135
8136 if (matchKeyword('default')) {
8137 return parseExportDefaultDeclaration(node);
8138 }
8139 if (match('*')) {
8140 return parseExportAllDeclaration(node);
8141 }
8142 return parseExportNamedDeclaration(node);
8143 }
8144
8145 // ECMA-262 15.2.2 Imports
8146
8147 function parseImportSpecifier() {
8148 // import {<foo as bar>} ...;
8149 var local, imported, node = new Node();
8150
8151 imported = parseNonComputedProperty();
8152 if (matchContextualKeyword('as')) {
8153 lex();
8154 local = parseVariableIdentifier();
8155 }
8156
8157 return node.finishImportSpecifier(local, imported);
8158 }
8159
8160 function parseNamedImports() {
8161 var specifiers = [];
8162 // {foo, bar as bas}
8163 expect('{');
8164 while (!match('}')) {
8165 specifiers.push(parseImportSpecifier());
8166 if (!match('}')) {
8167 expect(',');
8168 if (match('}')) {
8169 break;
8170 }
8171 }
8172 }
8173 expect('}');
8174 return specifiers;
8175 }
8176
8177 function parseImportDefaultSpecifier() {
8178 // import <foo> ...;
8179 var local, node = new Node();
8180
8181 local = parseNonComputedProperty();
8182
8183 return node.finishImportDefaultSpecifier(local);
8184 }
8185
8186 function parseImportNamespaceSpecifier() {
8187 // import <* as foo> ...;
8188 var local, node = new Node();
8189
8190 expect('*');
8191 if (!matchContextualKeyword('as')) {
8192 throwError(Messages.NoAsAfterImportNamespace);
8193 }
8194 lex();
8195 local = parseNonComputedProperty();
8196
8197 return node.finishImportNamespaceSpecifier(local);
8198 }
8199
8200 function parseImportDeclaration() {
8201 var specifiers = [], src, node = new Node();
8202
8203 if (state.inFunctionBody) {
8204 throwError(Messages.IllegalImportDeclaration);
8205 }
8206
8207 expectKeyword('import');
8208
8209 if (lookahead.type === Token.StringLiteral) {
8210 // import 'foo';
8211 src = parseModuleSpecifier();
8212 } else {
8213
8214 if (match('{')) {
8215 // import {bar}
8216 specifiers = specifiers.concat(parseNamedImports());
8217 } else if (match('*')) {
8218 // import * as foo
8219 specifiers.push(parseImportNamespaceSpecifier());
8220 } else if (isIdentifierName(lookahead) && !matchKeyword('default')) {
8221 // import foo
8222 specifiers.push(parseImportDefaultSpecifier());
8223 if (match(',')) {
8224 lex();
8225 if (match('*')) {
8226 // import foo, * as foo
8227 specifiers.push(parseImportNamespaceSpecifier());
8228 } else if (match('{')) {
8229 // import foo, {bar}
8230 specifiers = specifiers.concat(parseNamedImports());
8231 } else {
8232 throwUnexpectedToken(lookahead);
8233 }
8234 }
8235 } else {
8236 throwUnexpectedToken(lex());
8237 }
8238
8239 if (!matchContextualKeyword('from')) {
8240 throwError(lookahead.value ?
8241 Messages.UnexpectedToken : Messages.MissingFromClause, lookahead.value);
8242 }
8243 lex();
8244 src = parseModuleSpecifier();
8245 }
8246
8247 consumeSemicolon();
8248 return node.finishImportDeclaration(specifiers, src);
8249 }
8250
8251 // ECMA-262 15.1 Scripts
8252
8253 function parseScriptBody() {
8254 var statement, body = [], token, directive, firstRestricted;
8255
8256 while (startIndex < length) {
8257 token = lookahead;
8258 if (token.type !== Token.StringLiteral) {
8259 break;
8260 }
8261
8262 statement = parseStatementListItem();
8263 body.push(statement);
8264 if (statement.expression.type !== Syntax.Literal) {
8265 // this is not directive
8266 break;
8267 }
8268 directive = source.slice(token.start + 1, token.end - 1);
8269 if (directive === 'use strict') {
8270 strict = true;
8271 if (firstRestricted) {
8272 tolerateUnexpectedToken(firstRestricted, Messages.StrictOctalLiteral);
8273 }
8274 } else {
8275 if (!firstRestricted && token.octal) {
8276 firstRestricted = token;
8277 }
8278 }
8279 }
8280
8281 while (startIndex < length) {
8282 statement = parseStatementListItem();
8283 /* istanbul ignore if */
8284 if (typeof statement === 'undefined') {
8285 break;
8286 }
8287 body.push(statement);
8288 }
8289 return body;
8290 }
8291
8292 function parseProgram() {
8293 var body, node;
8294
8295 peek();
8296 node = new Node();
8297
8298 body = parseScriptBody();
8299 return node.finishProgram(body, state.sourceType);
8300 }
8301
8302 function filterTokenLocation() {
8303 var i, entry, token, tokens = [];
8304
8305 for (i = 0; i < extra.tokens.length; ++i) {
8306 entry = extra.tokens[i];
8307 token = {
8308 type: entry.type,
8309 value: entry.value
8310 };
8311 if (entry.regex) {
8312 token.regex = {
8313 pattern: entry.regex.pattern,
8314 flags: entry.regex.flags
8315 };
8316 }
8317 if (extra.range) {
8318 token.range = entry.range;
8319 }
8320 if (extra.loc) {
8321 token.loc = entry.loc;
8322 }
8323 tokens.push(token);
8324 }
8325
8326 extra.tokens = tokens;
8327 }
8328
8329 function tokenize(code, options) {
8330 var toString,
8331 tokens;
8332
8333 toString = String;
8334 if (typeof code !== 'string' && !(code instanceof String)) {
8335 code = toString(code);
8336 }
8337
8338 source = code;
8339 index = 0;
8340 lineNumber = (source.length > 0) ? 1 : 0;
8341 lineStart = 0;
8342 startIndex = index;
8343 startLineNumber = lineNumber;
8344 startLineStart = lineStart;
8345 length = source.length;
8346 lookahead = null;
8347 state = {
8348 allowIn: true,
8349 allowYield: true,
8350 labelSet: {},
8351 inFunctionBody: false,
8352 inIteration: false,
8353 inSwitch: false,
8354 lastCommentStart: -1,
8355 curlyStack: []
8356 };
8357
8358 extra = {};
8359
8360 // Options matching.
8361 options = options || {};
8362
8363 // Of course we collect tokens here.
8364 options.tokens = true;
8365 extra.tokens = [];
8366 extra.tokenize = true;
8367 // The following two fields are necessary to compute the Regex tokens.
8368 extra.openParenToken = -1;
8369 extra.openCurlyToken = -1;
8370
8371 extra.range = (typeof options.range === 'boolean') && options.range;
8372 extra.loc = (typeof options.loc === 'boolean') && options.loc;
8373
8374 if (typeof options.comment === 'boolean' && options.comment) {
8375 extra.comments = [];
8376 }
8377 if (typeof options.tolerant === 'boolean' && options.tolerant) {
8378 extra.errors = [];
8379 }
8380
8381 try {
8382 peek();
8383 if (lookahead.type === Token.EOF) {
8384 return extra.tokens;
8385 }
8386
8387 lex();
8388 while (lookahead.type !== Token.EOF) {
8389 try {
8390 lex();
8391 } catch (lexError) {
8392 if (extra.errors) {
8393 recordError(lexError);
8394 // We have to break on the first error
8395 // to avoid infinite loops.
8396 break;
8397 } else {
8398 throw lexError;
8399 }
8400 }
8401 }
8402
8403 filterTokenLocation();
8404 tokens = extra.tokens;
8405 if (typeof extra.comments !== 'undefined') {
8406 tokens.comments = extra.comments;
8407 }
8408 if (typeof extra.errors !== 'undefined') {
8409 tokens.errors = extra.errors;
8410 }
8411 } catch (e) {
8412 throw e;
8413 } finally {
8414 extra = {};
8415 }
8416 return tokens;
8417 }
8418
8419 function parse(code, options) {
8420 var program, toString;
8421
8422 toString = String;
8423 if (typeof code !== 'string' && !(code instanceof String)) {
8424 code = toString(code);
8425 }
8426
8427 source = code;
8428 index = 0;
8429 lineNumber = (source.length > 0) ? 1 : 0;
8430 lineStart = 0;
8431 startIndex = index;
8432 startLineNumber = lineNumber;
8433 startLineStart = lineStart;
8434 length = source.length;
8435 lookahead = null;
8436 state = {
8437 allowIn: true,
8438 allowYield: true,
8439 labelSet: {},
8440 inFunctionBody: false,
8441 inIteration: false,
8442 inSwitch: false,
8443 lastCommentStart: -1,
8444 curlyStack: [],
8445 sourceType: 'script'
8446 };
8447 strict = false;
8448
8449 extra = {};
8450 if (typeof options !== 'undefined') {
8451 extra.range = (typeof options.range === 'boolean') && options.range;
8452 extra.loc = (typeof options.loc === 'boolean') && options.loc;
8453 extra.attachComment = (typeof options.attachComment === 'boolean') && options.attachComment;
8454
8455 if (extra.loc && options.source !== null && options.source !== undefined) {
8456 extra.source = toString(options.source);
8457 }
8458
8459 if (typeof options.tokens === 'boolean' && options.tokens) {
8460 extra.tokens = [];
8461 }
8462 if (typeof options.comment === 'boolean' && options.comment) {
8463 extra.comments = [];
8464 }
8465 if (typeof options.tolerant === 'boolean' && options.tolerant) {
8466 extra.errors = [];
8467 }
8468 if (extra.attachComment) {
8469 extra.range = true;
8470 extra.comments = [];
8471 extra.bottomRightStack = [];
8472 extra.trailingComments = [];
8473 extra.leadingComments = [];
8474 }
8475 if (options.sourceType === 'module') {
8476 // very restrictive condition for now
8477 state.sourceType = options.sourceType;
8478 strict = true;
8479 }
8480 }
8481
8482 try {
8483 program = parseProgram();
8484 if (typeof extra.comments !== 'undefined') {
8485 program.comments = extra.comments;
8486 }
8487 if (typeof extra.tokens !== 'undefined') {
8488 filterTokenLocation();
8489 program.tokens = extra.tokens;
8490 }
8491 if (typeof extra.errors !== 'undefined') {
8492 program.errors = extra.errors;
8493 }
8494 } catch (e) {
8495 throw e;
8496 } finally {
8497 extra = {};
8498 }
8499
8500 return program;
8501 }
8502
8503 // Sync with *.json manifests.
8504 exports.version = '2.6.0';
8505
8506 exports.tokenize = tokenize;
8507
8508 exports.parse = parse;
8509
8510 // Deep copy.
8511 /* istanbul ignore next */
8512 exports.Syntax = (function () {
8513 var name, types = {};
8514
8515 if (typeof Object.create === 'function') {
8516 types = Object.create(null);
8517 }
8518
8519 for (name in Syntax) {
8520 if (Syntax.hasOwnProperty(name)) {
8521 types[name] = Syntax[name];
8522 }
8523 }
8524
8525 if (typeof Object.freeze === 'function') {
8526 Object.freeze(types);
8527 }
8528
8529 return types;
8530 }());
8531
8532}));
8533/* vim: set sw=4 ts=4 et tw=80 : */
8534
8535},{}],34:[function(_dereq_,module,exports){
8536/*
8537 Copyright (C) 2012-2013 Yusuke Suzuki <utatane.tea@gmail.com>
8538 Copyright (C) 2012 Ariya Hidayat <ariya.hidayat@gmail.com>
8539
8540 Redistribution and use in source and binary forms, with or without
8541 modification, are permitted provided that the following conditions are met:
8542
8543 * Redistributions of source code must retain the above copyright
8544 notice, this list of conditions and the following disclaimer.
8545 * Redistributions in binary form must reproduce the above copyright
8546 notice, this list of conditions and the following disclaimer in the
8547 documentation and/or other materials provided with the distribution.
8548
8549 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
8550 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
8551 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
8552 ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
8553 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
8554 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
8555 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
8556 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
8557 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
8558 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
8559*/
8560/*jslint vars:false, bitwise:true*/
8561/*jshint indent:4*/
8562/*global exports:true*/
8563(function clone(exports) {
8564 'use strict';
8565
8566 var Syntax,
8567 isArray,
8568 VisitorOption,
8569 VisitorKeys,
8570 objectCreate,
8571 objectKeys,
8572 BREAK,
8573 SKIP,
8574 REMOVE;
8575
8576 function ignoreJSHintError() { }
8577
8578 isArray = Array.isArray;
8579 if (!isArray) {
8580 isArray = function isArray(array) {
8581 return Object.prototype.toString.call(array) === '[object Array]';
8582 };
8583 }
8584
8585 function deepCopy(obj) {
8586 var ret = {}, key, val;
8587 for (key in obj) {
8588 if (obj.hasOwnProperty(key)) {
8589 val = obj[key];
8590 if (typeof val === 'object' && val !== null) {
8591 ret[key] = deepCopy(val);
8592 } else {
8593 ret[key] = val;
8594 }
8595 }
8596 }
8597 return ret;
8598 }
8599
8600 function shallowCopy(obj) {
8601 var ret = {}, key;
8602 for (key in obj) {
8603 if (obj.hasOwnProperty(key)) {
8604 ret[key] = obj[key];
8605 }
8606 }
8607 return ret;
8608 }
8609 ignoreJSHintError(shallowCopy);
8610
8611 // based on LLVM libc++ upper_bound / lower_bound
8612 // MIT License
8613
8614 function upperBound(array, func) {
8615 var diff, len, i, current;
8616
8617 len = array.length;
8618 i = 0;
8619
8620 while (len) {
8621 diff = len >>> 1;
8622 current = i + diff;
8623 if (func(array[current])) {
8624 len = diff;
8625 } else {
8626 i = current + 1;
8627 len -= diff + 1;
8628 }
8629 }
8630 return i;
8631 }
8632
8633 function lowerBound(array, func) {
8634 var diff, len, i, current;
8635
8636 len = array.length;
8637 i = 0;
8638
8639 while (len) {
8640 diff = len >>> 1;
8641 current = i + diff;
8642 if (func(array[current])) {
8643 i = current + 1;
8644 len -= diff + 1;
8645 } else {
8646 len = diff;
8647 }
8648 }
8649 return i;
8650 }
8651 ignoreJSHintError(lowerBound);
8652
8653 objectCreate = Object.create || (function () {
8654 function F() { }
8655
8656 return function (o) {
8657 F.prototype = o;
8658 return new F();
8659 };
8660 })();
8661
8662 objectKeys = Object.keys || function (o) {
8663 var keys = [], key;
8664 for (key in o) {
8665 keys.push(key);
8666 }
8667 return keys;
8668 };
8669
8670 function extend(to, from) {
8671 var keys = objectKeys(from), key, i, len;
8672 for (i = 0, len = keys.length; i < len; i += 1) {
8673 key = keys[i];
8674 to[key] = from[key];
8675 }
8676 return to;
8677 }
8678
8679 Syntax = {
8680 AssignmentExpression: 'AssignmentExpression',
8681 AssignmentPattern: 'AssignmentPattern',
8682 ArrayExpression: 'ArrayExpression',
8683 ArrayPattern: 'ArrayPattern',
8684 ArrowFunctionExpression: 'ArrowFunctionExpression',
8685 AwaitExpression: 'AwaitExpression', // CAUTION: It's deferred to ES7.
8686 BlockStatement: 'BlockStatement',
8687 BinaryExpression: 'BinaryExpression',
8688 BreakStatement: 'BreakStatement',
8689 CallExpression: 'CallExpression',
8690 CatchClause: 'CatchClause',
8691 ClassBody: 'ClassBody',
8692 ClassDeclaration: 'ClassDeclaration',
8693 ClassExpression: 'ClassExpression',
8694 ComprehensionBlock: 'ComprehensionBlock', // CAUTION: It's deferred to ES7.
8695 ComprehensionExpression: 'ComprehensionExpression', // CAUTION: It's deferred to ES7.
8696 ConditionalExpression: 'ConditionalExpression',
8697 ContinueStatement: 'ContinueStatement',
8698 DebuggerStatement: 'DebuggerStatement',
8699 DirectiveStatement: 'DirectiveStatement',
8700 DoWhileStatement: 'DoWhileStatement',
8701 EmptyStatement: 'EmptyStatement',
8702 ExportAllDeclaration: 'ExportAllDeclaration',
8703 ExportDefaultDeclaration: 'ExportDefaultDeclaration',
8704 ExportNamedDeclaration: 'ExportNamedDeclaration',
8705 ExportSpecifier: 'ExportSpecifier',
8706 ExpressionStatement: 'ExpressionStatement',
8707 ForStatement: 'ForStatement',
8708 ForInStatement: 'ForInStatement',
8709 ForOfStatement: 'ForOfStatement',
8710 FunctionDeclaration: 'FunctionDeclaration',
8711 FunctionExpression: 'FunctionExpression',
8712 GeneratorExpression: 'GeneratorExpression', // CAUTION: It's deferred to ES7.
8713 Identifier: 'Identifier',
8714 IfStatement: 'IfStatement',
8715 ImportDeclaration: 'ImportDeclaration',
8716 ImportDefaultSpecifier: 'ImportDefaultSpecifier',
8717 ImportNamespaceSpecifier: 'ImportNamespaceSpecifier',
8718 ImportSpecifier: 'ImportSpecifier',
8719 Literal: 'Literal',
8720 LabeledStatement: 'LabeledStatement',
8721 LogicalExpression: 'LogicalExpression',
8722 MemberExpression: 'MemberExpression',
8723 MetaProperty: 'MetaProperty',
8724 MethodDefinition: 'MethodDefinition',
8725 ModuleSpecifier: 'ModuleSpecifier',
8726 NewExpression: 'NewExpression',
8727 ObjectExpression: 'ObjectExpression',
8728 ObjectPattern: 'ObjectPattern',
8729 Program: 'Program',
8730 Property: 'Property',
8731 RestElement: 'RestElement',
8732 ReturnStatement: 'ReturnStatement',
8733 SequenceExpression: 'SequenceExpression',
8734 SpreadElement: 'SpreadElement',
8735 Super: 'Super',
8736 SwitchStatement: 'SwitchStatement',
8737 SwitchCase: 'SwitchCase',
8738 TaggedTemplateExpression: 'TaggedTemplateExpression',
8739 TemplateElement: 'TemplateElement',
8740 TemplateLiteral: 'TemplateLiteral',
8741 ThisExpression: 'ThisExpression',
8742 ThrowStatement: 'ThrowStatement',
8743 TryStatement: 'TryStatement',
8744 UnaryExpression: 'UnaryExpression',
8745 UpdateExpression: 'UpdateExpression',
8746 VariableDeclaration: 'VariableDeclaration',
8747 VariableDeclarator: 'VariableDeclarator',
8748 WhileStatement: 'WhileStatement',
8749 WithStatement: 'WithStatement',
8750 YieldExpression: 'YieldExpression'
8751 };
8752
8753 VisitorKeys = {
8754 AssignmentExpression: ['left', 'right'],
8755 AssignmentPattern: ['left', 'right'],
8756 ArrayExpression: ['elements'],
8757 ArrayPattern: ['elements'],
8758 ArrowFunctionExpression: ['params', 'body'],
8759 AwaitExpression: ['argument'], // CAUTION: It's deferred to ES7.
8760 BlockStatement: ['body'],
8761 BinaryExpression: ['left', 'right'],
8762 BreakStatement: ['label'],
8763 CallExpression: ['callee', 'arguments'],
8764 CatchClause: ['param', 'body'],
8765 ClassBody: ['body'],
8766 ClassDeclaration: ['id', 'superClass', 'body'],
8767 ClassExpression: ['id', 'superClass', 'body'],
8768 ComprehensionBlock: ['left', 'right'], // CAUTION: It's deferred to ES7.
8769 ComprehensionExpression: ['blocks', 'filter', 'body'], // CAUTION: It's deferred to ES7.
8770 ConditionalExpression: ['test', 'consequent', 'alternate'],
8771 ContinueStatement: ['label'],
8772 DebuggerStatement: [],
8773 DirectiveStatement: [],
8774 DoWhileStatement: ['body', 'test'],
8775 EmptyStatement: [],
8776 ExportAllDeclaration: ['source'],
8777 ExportDefaultDeclaration: ['declaration'],
8778 ExportNamedDeclaration: ['declaration', 'specifiers', 'source'],
8779 ExportSpecifier: ['exported', 'local'],
8780 ExpressionStatement: ['expression'],
8781 ForStatement: ['init', 'test', 'update', 'body'],
8782 ForInStatement: ['left', 'right', 'body'],
8783 ForOfStatement: ['left', 'right', 'body'],
8784 FunctionDeclaration: ['id', 'params', 'body'],
8785 FunctionExpression: ['id', 'params', 'body'],
8786 GeneratorExpression: ['blocks', 'filter', 'body'], // CAUTION: It's deferred to ES7.
8787 Identifier: [],
8788 IfStatement: ['test', 'consequent', 'alternate'],
8789 ImportDeclaration: ['specifiers', 'source'],
8790 ImportDefaultSpecifier: ['local'],
8791 ImportNamespaceSpecifier: ['local'],
8792 ImportSpecifier: ['imported', 'local'],
8793 Literal: [],
8794 LabeledStatement: ['label', 'body'],
8795 LogicalExpression: ['left', 'right'],
8796 MemberExpression: ['object', 'property'],
8797 MetaProperty: ['meta', 'property'],
8798 MethodDefinition: ['key', 'value'],
8799 ModuleSpecifier: [],
8800 NewExpression: ['callee', 'arguments'],
8801 ObjectExpression: ['properties'],
8802 ObjectPattern: ['properties'],
8803 Program: ['body'],
8804 Property: ['key', 'value'],
8805 RestElement: [ 'argument' ],
8806 ReturnStatement: ['argument'],
8807 SequenceExpression: ['expressions'],
8808 SpreadElement: ['argument'],
8809 Super: [],
8810 SwitchStatement: ['discriminant', 'cases'],
8811 SwitchCase: ['test', 'consequent'],
8812 TaggedTemplateExpression: ['tag', 'quasi'],
8813 TemplateElement: [],
8814 TemplateLiteral: ['quasis', 'expressions'],
8815 ThisExpression: [],
8816 ThrowStatement: ['argument'],
8817 TryStatement: ['block', 'handler', 'finalizer'],
8818 UnaryExpression: ['argument'],
8819 UpdateExpression: ['argument'],
8820 VariableDeclaration: ['declarations'],
8821 VariableDeclarator: ['id', 'init'],
8822 WhileStatement: ['test', 'body'],
8823 WithStatement: ['object', 'body'],
8824 YieldExpression: ['argument']
8825 };
8826
8827 // unique id
8828 BREAK = {};
8829 SKIP = {};
8830 REMOVE = {};
8831
8832 VisitorOption = {
8833 Break: BREAK,
8834 Skip: SKIP,
8835 Remove: REMOVE
8836 };
8837
8838 function Reference(parent, key) {
8839 this.parent = parent;
8840 this.key = key;
8841 }
8842
8843 Reference.prototype.replace = function replace(node) {
8844 this.parent[this.key] = node;
8845 };
8846
8847 Reference.prototype.remove = function remove() {
8848 if (isArray(this.parent)) {
8849 this.parent.splice(this.key, 1);
8850 return true;
8851 } else {
8852 this.replace(null);
8853 return false;
8854 }
8855 };
8856
8857 function Element(node, path, wrap, ref) {
8858 this.node = node;
8859 this.path = path;
8860 this.wrap = wrap;
8861 this.ref = ref;
8862 }
8863
8864 function Controller() { }
8865
8866 // API:
8867 // return property path array from root to current node
8868 Controller.prototype.path = function path() {
8869 var i, iz, j, jz, result, element;
8870
8871 function addToPath(result, path) {
8872 if (isArray(path)) {
8873 for (j = 0, jz = path.length; j < jz; ++j) {
8874 result.push(path[j]);
8875 }
8876 } else {
8877 result.push(path);
8878 }
8879 }
8880
8881 // root node
8882 if (!this.__current.path) {
8883 return null;
8884 }
8885
8886 // first node is sentinel, second node is root element
8887 result = [];
8888 for (i = 2, iz = this.__leavelist.length; i < iz; ++i) {
8889 element = this.__leavelist[i];
8890 addToPath(result, element.path);
8891 }
8892 addToPath(result, this.__current.path);
8893 return result;
8894 };
8895
8896 // API:
8897 // return type of current node
8898 Controller.prototype.type = function () {
8899 var node = this.current();
8900 return node.type || this.__current.wrap;
8901 };
8902
8903 // API:
8904 // return array of parent elements
8905 Controller.prototype.parents = function parents() {
8906 var i, iz, result;
8907
8908 // first node is sentinel
8909 result = [];
8910 for (i = 1, iz = this.__leavelist.length; i < iz; ++i) {
8911 result.push(this.__leavelist[i].node);
8912 }
8913
8914 return result;
8915 };
8916
8917 // API:
8918 // return current node
8919 Controller.prototype.current = function current() {
8920 return this.__current.node;
8921 };
8922
8923 Controller.prototype.__execute = function __execute(callback, element) {
8924 var previous, result;
8925
8926 result = undefined;
8927
8928 previous = this.__current;
8929 this.__current = element;
8930 this.__state = null;
8931 if (callback) {
8932 result = callback.call(this, element.node, this.__leavelist[this.__leavelist.length - 1].node);
8933 }
8934 this.__current = previous;
8935
8936 return result;
8937 };
8938
8939 // API:
8940 // notify control skip / break
8941 Controller.prototype.notify = function notify(flag) {
8942 this.__state = flag;
8943 };
8944
8945 // API:
8946 // skip child nodes of current node
8947 Controller.prototype.skip = function () {
8948 this.notify(SKIP);
8949 };
8950
8951 // API:
8952 // break traversals
8953 Controller.prototype['break'] = function () {
8954 this.notify(BREAK);
8955 };
8956
8957 // API:
8958 // remove node
8959 Controller.prototype.remove = function () {
8960 this.notify(REMOVE);
8961 };
8962
8963 Controller.prototype.__initialize = function(root, visitor) {
8964 this.visitor = visitor;
8965 this.root = root;
8966 this.__worklist = [];
8967 this.__leavelist = [];
8968 this.__current = null;
8969 this.__state = null;
8970 this.__fallback = visitor.fallback === 'iteration';
8971 this.__keys = VisitorKeys;
8972 if (visitor.keys) {
8973 this.__keys = extend(objectCreate(this.__keys), visitor.keys);
8974 }
8975 };
8976
8977 function isNode(node) {
8978 if (node == null) {
8979 return false;
8980 }
8981 return typeof node === 'object' && typeof node.type === 'string';
8982 }
8983
8984 function isProperty(nodeType, key) {
8985 return (nodeType === Syntax.ObjectExpression || nodeType === Syntax.ObjectPattern) && 'properties' === key;
8986 }
8987
8988 Controller.prototype.traverse = function traverse(root, visitor) {
8989 var worklist,
8990 leavelist,
8991 element,
8992 node,
8993 nodeType,
8994 ret,
8995 key,
8996 current,
8997 current2,
8998 candidates,
8999 candidate,
9000 sentinel;
9001
9002 this.__initialize(root, visitor);
9003
9004 sentinel = {};
9005
9006 // reference
9007 worklist = this.__worklist;
9008 leavelist = this.__leavelist;
9009
9010 // initialize
9011 worklist.push(new Element(root, null, null, null));
9012 leavelist.push(new Element(null, null, null, null));
9013
9014 while (worklist.length) {
9015 element = worklist.pop();
9016
9017 if (element === sentinel) {
9018 element = leavelist.pop();
9019
9020 ret = this.__execute(visitor.leave, element);
9021
9022 if (this.__state === BREAK || ret === BREAK) {
9023 return;
9024 }
9025 continue;
9026 }
9027
9028 if (element.node) {
9029
9030 ret = this.__execute(visitor.enter, element);
9031
9032 if (this.__state === BREAK || ret === BREAK) {
9033 return;
9034 }
9035
9036 worklist.push(sentinel);
9037 leavelist.push(element);
9038
9039 if (this.__state === SKIP || ret === SKIP) {
9040 continue;
9041 }
9042
9043 node = element.node;
9044 nodeType = element.wrap || node.type;
9045 candidates = this.__keys[nodeType];
9046 if (!candidates) {
9047 if (this.__fallback) {
9048 candidates = objectKeys(node);
9049 } else {
9050 throw new Error('Unknown node type ' + nodeType + '.');
9051 }
9052 }
9053
9054 current = candidates.length;
9055 while ((current -= 1) >= 0) {
9056 key = candidates[current];
9057 candidate = node[key];
9058 if (!candidate) {
9059 continue;
9060 }
9061
9062 if (isArray(candidate)) {
9063 current2 = candidate.length;
9064 while ((current2 -= 1) >= 0) {
9065 if (!candidate[current2]) {
9066 continue;
9067 }
9068 if (isProperty(nodeType, candidates[current])) {
9069 element = new Element(candidate[current2], [key, current2], 'Property', null);
9070 } else if (isNode(candidate[current2])) {
9071 element = new Element(candidate[current2], [key, current2], null, null);
9072 } else {
9073 continue;
9074 }
9075 worklist.push(element);
9076 }
9077 } else if (isNode(candidate)) {
9078 worklist.push(new Element(candidate, key, null, null));
9079 }
9080 }
9081 }
9082 }
9083 };
9084
9085 Controller.prototype.replace = function replace(root, visitor) {
9086 function removeElem(element) {
9087 var i,
9088 key,
9089 nextElem,
9090 parent;
9091
9092 if (element.ref.remove()) {
9093 // When the reference is an element of an array.
9094 key = element.ref.key;
9095 parent = element.ref.parent;
9096
9097 // If removed from array, then decrease following items' keys.
9098 i = worklist.length;
9099 while (i--) {
9100 nextElem = worklist[i];
9101 if (nextElem.ref && nextElem.ref.parent === parent) {
9102 if (nextElem.ref.key < key) {
9103 break;
9104 }
9105 --nextElem.ref.key;
9106 }
9107 }
9108 }
9109 }
9110
9111 var worklist,
9112 leavelist,
9113 node,
9114 nodeType,
9115 target,
9116 element,
9117 current,
9118 current2,
9119 candidates,
9120 candidate,
9121 sentinel,
9122 outer,
9123 key;
9124
9125 this.__initialize(root, visitor);
9126
9127 sentinel = {};
9128
9129 // reference
9130 worklist = this.__worklist;
9131 leavelist = this.__leavelist;
9132
9133 // initialize
9134 outer = {
9135 root: root
9136 };
9137 element = new Element(root, null, null, new Reference(outer, 'root'));
9138 worklist.push(element);
9139 leavelist.push(element);
9140
9141 while (worklist.length) {
9142 element = worklist.pop();
9143
9144 if (element === sentinel) {
9145 element = leavelist.pop();
9146
9147 target = this.__execute(visitor.leave, element);
9148
9149 // node may be replaced with null,
9150 // so distinguish between undefined and null in this place
9151 if (target !== undefined && target !== BREAK && target !== SKIP && target !== REMOVE) {
9152 // replace
9153 element.ref.replace(target);
9154 }
9155
9156 if (this.__state === REMOVE || target === REMOVE) {
9157 removeElem(element);
9158 }
9159
9160 if (this.__state === BREAK || target === BREAK) {
9161 return outer.root;
9162 }
9163 continue;
9164 }
9165
9166 target = this.__execute(visitor.enter, element);
9167
9168 // node may be replaced with null,
9169 // so distinguish between undefined and null in this place
9170 if (target !== undefined && target !== BREAK && target !== SKIP && target !== REMOVE) {
9171 // replace
9172 element.ref.replace(target);
9173 element.node = target;
9174 }
9175
9176 if (this.__state === REMOVE || target === REMOVE) {
9177 removeElem(element);
9178 element.node = null;
9179 }
9180
9181 if (this.__state === BREAK || target === BREAK) {
9182 return outer.root;
9183 }
9184
9185 // node may be null
9186 node = element.node;
9187 if (!node) {
9188 continue;
9189 }
9190
9191 worklist.push(sentinel);
9192 leavelist.push(element);
9193
9194 if (this.__state === SKIP || target === SKIP) {
9195 continue;
9196 }
9197
9198 nodeType = element.wrap || node.type;
9199 candidates = this.__keys[nodeType];
9200 if (!candidates) {
9201 if (this.__fallback) {
9202 candidates = objectKeys(node);
9203 } else {
9204 throw new Error('Unknown node type ' + nodeType + '.');
9205 }
9206 }
9207
9208 current = candidates.length;
9209 while ((current -= 1) >= 0) {
9210 key = candidates[current];
9211 candidate = node[key];
9212 if (!candidate) {
9213 continue;
9214 }
9215
9216 if (isArray(candidate)) {
9217 current2 = candidate.length;
9218 while ((current2 -= 1) >= 0) {
9219 if (!candidate[current2]) {
9220 continue;
9221 }
9222 if (isProperty(nodeType, candidates[current])) {
9223 element = new Element(candidate[current2], [key, current2], 'Property', new Reference(candidate, current2));
9224 } else if (isNode(candidate[current2])) {
9225 element = new Element(candidate[current2], [key, current2], null, new Reference(candidate, current2));
9226 } else {
9227 continue;
9228 }
9229 worklist.push(element);
9230 }
9231 } else if (isNode(candidate)) {
9232 worklist.push(new Element(candidate, key, null, new Reference(node, key)));
9233 }
9234 }
9235 }
9236
9237 return outer.root;
9238 };
9239
9240 function traverse(root, visitor) {
9241 var controller = new Controller();
9242 return controller.traverse(root, visitor);
9243 }
9244
9245 function replace(root, visitor) {
9246 var controller = new Controller();
9247 return controller.replace(root, visitor);
9248 }
9249
9250 function extendCommentRange(comment, tokens) {
9251 var target;
9252
9253 target = upperBound(tokens, function search(token) {
9254 return token.range[0] > comment.range[0];
9255 });
9256
9257 comment.extendedRange = [comment.range[0], comment.range[1]];
9258
9259 if (target !== tokens.length) {
9260 comment.extendedRange[1] = tokens[target].range[0];
9261 }
9262
9263 target -= 1;
9264 if (target >= 0) {
9265 comment.extendedRange[0] = tokens[target].range[1];
9266 }
9267
9268 return comment;
9269 }
9270
9271 function attachComments(tree, providedComments, tokens) {
9272 // At first, we should calculate extended comment ranges.
9273 var comments = [], comment, len, i, cursor;
9274
9275 if (!tree.range) {
9276 throw new Error('attachComments needs range information');
9277 }
9278
9279 // tokens array is empty, we attach comments to tree as 'leadingComments'
9280 if (!tokens.length) {
9281 if (providedComments.length) {
9282 for (i = 0, len = providedComments.length; i < len; i += 1) {
9283 comment = deepCopy(providedComments[i]);
9284 comment.extendedRange = [0, tree.range[0]];
9285 comments.push(comment);
9286 }
9287 tree.leadingComments = comments;
9288 }
9289 return tree;
9290 }
9291
9292 for (i = 0, len = providedComments.length; i < len; i += 1) {
9293 comments.push(extendCommentRange(deepCopy(providedComments[i]), tokens));
9294 }
9295
9296 // This is based on John Freeman's implementation.
9297 cursor = 0;
9298 traverse(tree, {
9299 enter: function (node) {
9300 var comment;
9301
9302 while (cursor < comments.length) {
9303 comment = comments[cursor];
9304 if (comment.extendedRange[1] > node.range[0]) {
9305 break;
9306 }
9307
9308 if (comment.extendedRange[1] === node.range[0]) {
9309 if (!node.leadingComments) {
9310 node.leadingComments = [];
9311 }
9312 node.leadingComments.push(comment);
9313 comments.splice(cursor, 1);
9314 } else {
9315 cursor += 1;
9316 }
9317 }
9318
9319 // already out of owned node
9320 if (cursor === comments.length) {
9321 return VisitorOption.Break;
9322 }
9323
9324 if (comments[cursor].extendedRange[0] > node.range[1]) {
9325 return VisitorOption.Skip;
9326 }
9327 }
9328 });
9329
9330 cursor = 0;
9331 traverse(tree, {
9332 leave: function (node) {
9333 var comment;
9334
9335 while (cursor < comments.length) {
9336 comment = comments[cursor];
9337 if (node.range[1] < comment.extendedRange[0]) {
9338 break;
9339 }
9340
9341 if (node.range[1] === comment.extendedRange[0]) {
9342 if (!node.trailingComments) {
9343 node.trailingComments = [];
9344 }
9345 node.trailingComments.push(comment);
9346 comments.splice(cursor, 1);
9347 } else {
9348 cursor += 1;
9349 }
9350 }
9351
9352 // already out of owned node
9353 if (cursor === comments.length) {
9354 return VisitorOption.Break;
9355 }
9356
9357 if (comments[cursor].extendedRange[0] > node.range[1]) {
9358 return VisitorOption.Skip;
9359 }
9360 }
9361 });
9362
9363 return tree;
9364 }
9365
9366 exports.version = _dereq_('./package.json').version;
9367 exports.Syntax = Syntax;
9368 exports.traverse = traverse;
9369 exports.replace = replace;
9370 exports.attachComments = attachComments;
9371 exports.VisitorKeys = VisitorKeys;
9372 exports.VisitorOption = VisitorOption;
9373 exports.Controller = Controller;
9374 exports.cloneEnvironment = function () { return clone({}); };
9375
9376 return exports;
9377}(exports));
9378/* vim: set sw=4 ts=4 et tw=80 : */
9379
9380},{"./package.json":35}],35:[function(_dereq_,module,exports){
9381module.exports={
9382 "name": "estraverse",
9383 "description": "ECMAScript JS AST traversal functions",
9384 "homepage": "https://github.com/estools/estraverse",
9385 "main": "estraverse.js",
9386 "version": "4.1.0",
9387 "engines": {
9388 "node": ">=0.10.0"
9389 },
9390 "maintainers": [
9391 {
9392 "name": "constellation",
9393 "email": "utatane.tea@gmail.com"
9394 },
9395 {
9396 "name": "michaelficarra",
9397 "email": "npm@michael.ficarra.me"
9398 }
9399 ],
9400 "repository": {
9401 "type": "git",
9402 "url": "git+ssh://git@github.com/estools/estraverse.git"
9403 },
9404 "devDependencies": {
9405 "chai": "^2.1.1",
9406 "coffee-script": "^1.8.0",
9407 "espree": "^1.11.0",
9408 "gulp": "^3.8.10",
9409 "gulp-bump": "^0.2.2",
9410 "gulp-filter": "^2.0.0",
9411 "gulp-git": "^1.0.1",
9412 "gulp-tag-version": "^1.2.1",
9413 "jshint": "^2.5.6",
9414 "mocha": "^2.1.0"
9415 },
9416 "licenses": [
9417 {
9418 "type": "BSD",
9419 "url": "http://github.com/estools/estraverse/raw/master/LICENSE.BSD"
9420 }
9421 ],
9422 "scripts": {
9423 "test": "npm run-script lint && npm run-script unit-test",
9424 "lint": "jshint estraverse.js",
9425 "unit-test": "mocha --compilers coffee:coffee-script/register"
9426 },
9427 "gitHead": "347d52996336719b5910c7ffb5ff3ea8ecb87cf3",
9428 "bugs": {
9429 "url": "https://github.com/estools/estraverse/issues"
9430 },
9431 "_id": "estraverse@4.1.0",
9432 "_shasum": "40f23a76092041be6467d7f235c933b670766e05",
9433 "_from": "estraverse@4.1.0",
9434 "_npmVersion": "2.8.3",
9435 "_nodeVersion": "1.8.1",
9436 "_npmUser": {
9437 "name": "constellation",
9438 "email": "utatane.tea@gmail.com"
9439 },
9440 "dist": {
9441 "shasum": "40f23a76092041be6467d7f235c933b670766e05",
9442 "tarball": "http://registry.npmjs.org/estraverse/-/estraverse-4.1.0.tgz"
9443 },
9444 "directories": {},
9445 "_resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.1.0.tgz",
9446 "readme": "ERROR: No README data found!"
9447}
9448
9449},{}],36:[function(_dereq_,module,exports){
9450
9451var indexOf = [].indexOf;
9452
9453module.exports = function(arr, obj){
9454 if (indexOf) return arr.indexOf(obj);
9455 for (var i = 0; i < arr.length; ++i) {
9456 if (arr[i] === obj) return i;
9457 }
9458 return -1;
9459};
9460},{}],37:[function(_dereq_,module,exports){
9461'use strict';
9462
9463// modified from https://github.com/es-shims/es5-shim
9464var has = Object.prototype.hasOwnProperty;
9465var toStr = Object.prototype.toString;
9466var slice = Array.prototype.slice;
9467var isArgs = _dereq_('./isArguments');
9468var hasDontEnumBug = !({ 'toString': null }).propertyIsEnumerable('toString');
9469var hasProtoEnumBug = function () {}.propertyIsEnumerable('prototype');
9470var dontEnums = [
9471 'toString',
9472 'toLocaleString',
9473 'valueOf',
9474 'hasOwnProperty',
9475 'isPrototypeOf',
9476 'propertyIsEnumerable',
9477 'constructor'
9478];
9479var equalsConstructorPrototype = function (o) {
9480 var ctor = o.constructor;
9481 return ctor && ctor.prototype === o;
9482};
9483var blacklistedKeys = {
9484 $window: true,
9485 $console: true,
9486 $parent: true,
9487 $self: true,
9488 $frames: true,
9489 $webkitIndexedDB: true,
9490 $webkitStorageInfo: true
9491};
9492var hasAutomationEqualityBug = (function () {
9493 /* global window */
9494 if (typeof window === 'undefined') { return false; }
9495 for (var k in window) {
9496 if (!blacklistedKeys['$' + k] && has.call(window, k) && window[k] !== null && typeof window[k] === 'object') {
9497 try {
9498 equalsConstructorPrototype(window[k]);
9499 } catch (e) {
9500 return true;
9501 }
9502 }
9503 }
9504 return false;
9505}());
9506var equalsConstructorPrototypeIfNotBuggy = function (o) {
9507 /* global window */
9508 if (typeof window === 'undefined' && !hasAutomationEqualityBug) {
9509 return equalsConstructorPrototype(o);
9510 }
9511 try {
9512 return equalsConstructorPrototype(o);
9513 } catch (e) {
9514 return false;
9515 }
9516};
9517
9518var keysShim = function keys(object) {
9519 var isObject = object !== null && typeof object === 'object';
9520 var isFunction = toStr.call(object) === '[object Function]';
9521 var isArguments = isArgs(object);
9522 var isString = isObject && toStr.call(object) === '[object String]';
9523 var theKeys = [];
9524
9525 if (!isObject && !isFunction && !isArguments) {
9526 throw new TypeError('Object.keys called on a non-object');
9527 }
9528
9529 var skipProto = hasProtoEnumBug && isFunction;
9530 if (isString && object.length > 0 && !has.call(object, 0)) {
9531 for (var i = 0; i < object.length; ++i) {
9532 theKeys.push(String(i));
9533 }
9534 }
9535
9536 if (isArguments && object.length > 0) {
9537 for (var j = 0; j < object.length; ++j) {
9538 theKeys.push(String(j));
9539 }
9540 } else {
9541 for (var name in object) {
9542 if (!(skipProto && name === 'prototype') && has.call(object, name)) {
9543 theKeys.push(String(name));
9544 }
9545 }
9546 }
9547
9548 if (hasDontEnumBug) {
9549 var skipConstructor = equalsConstructorPrototypeIfNotBuggy(object);
9550
9551 for (var k = 0; k < dontEnums.length; ++k) {
9552 if (!(skipConstructor && dontEnums[k] === 'constructor') && has.call(object, dontEnums[k])) {
9553 theKeys.push(dontEnums[k]);
9554 }
9555 }
9556 }
9557 return theKeys;
9558};
9559
9560keysShim.shim = function shimObjectKeys() {
9561 if (!Object.keys) {
9562 Object.keys = keysShim;
9563 } else {
9564 var keysWorksWithArguments = (function () {
9565 // Safari 5.0 bug
9566 return (Object.keys(arguments) || '').length === 2;
9567 }(1, 2));
9568 if (!keysWorksWithArguments) {
9569 var originalKeys = Object.keys;
9570 Object.keys = function keys(object) {
9571 if (isArgs(object)) {
9572 return originalKeys(slice.call(object));
9573 } else {
9574 return originalKeys(object);
9575 }
9576 };
9577 }
9578 }
9579 return Object.keys || keysShim;
9580};
9581
9582module.exports = keysShim;
9583
9584},{"./isArguments":38}],38:[function(_dereq_,module,exports){
9585'use strict';
9586
9587var toStr = Object.prototype.toString;
9588
9589module.exports = function isArguments(value) {
9590 var str = toStr.call(value);
9591 var isArgs = str === '[object Arguments]';
9592 if (!isArgs) {
9593 isArgs = str !== '[object Array]' &&
9594 value !== null &&
9595 typeof value === 'object' &&
9596 typeof value.length === 'number' &&
9597 value.length >= 0 &&
9598 toStr.call(value.callee) === '[object Function]';
9599 }
9600 return isArgs;
9601};
9602
9603},{}],39:[function(_dereq_,module,exports){
9604/**
9605 * power-assert-formatter.js - Power Assert output formatter
9606 *
9607 * https://github.com/power-assert-js/power-assert-formatter
9608 *
9609 * Copyright (c) 2013-2015 Takuto Wada
9610 * Licensed under the MIT license.
9611 * https://github.com/power-assert-js/power-assert-formatter/blob/master/MIT-LICENSE.txt
9612 */
9613'use strict';
9614
9615module.exports = _dereq_('./lib/create');
9616
9617},{"./lib/create":44}],40:[function(_dereq_,module,exports){
9618'use strict';
9619
9620function AssertionRenderer (config) {
9621}
9622
9623AssertionRenderer.prototype.init = function (traversal) {
9624 var assertionLine;
9625 traversal.on('start', function (context) {
9626 assertionLine = context.source.content;
9627 });
9628 traversal.on('render', function (writer) {
9629 writer.write('');
9630 writer.write(assertionLine);
9631 });
9632};
9633
9634module.exports = AssertionRenderer;
9635
9636},{}],41:[function(_dereq_,module,exports){
9637'use strict';
9638
9639var typeName = _dereq_('type-name');
9640var keys = Object.keys || _dereq_('object-keys');
9641var syntax = _dereq_('estraverse').Syntax;
9642var forEach = _dereq_('array-foreach');
9643
9644
9645function BinaryExpressionRenderer(config) {
9646 this.config = config;
9647 this.stringify = config.stringify;
9648 this.diff = config.diff;
9649 this.espathToPair = {};
9650}
9651
9652BinaryExpressionRenderer.prototype.init = function (traversal) {
9653 var _this = this;
9654 traversal.on('esnode', function (esNode) {
9655 var pair;
9656 if (!esNode.isCaptured()) {
9657 if (isTargetBinaryExpression(esNode.getParent()) && esNode.currentNode.type === syntax.Literal) {
9658 _this.espathToPair[esNode.parentEspath][esNode.currentProp] = {code: esNode.code(), value: esNode.value()};
9659 }
9660 return;
9661 }
9662 if (isTargetBinaryExpression(esNode.getParent())) {
9663 _this.espathToPair[esNode.parentEspath][esNode.currentProp] = {code: esNode.code(), value: esNode.value()};
9664 }
9665 if (isTargetBinaryExpression(esNode)) {
9666 pair = {
9667 operator: esNode.currentNode.operator,
9668 value: esNode.value()
9669 };
9670 _this.espathToPair[esNode.espath] = pair;
9671 }
9672 });
9673 traversal.on('render', function (writer) {
9674 var pairs = [];
9675 forEach(keys(_this.espathToPair), function (espath) {
9676 var pair = _this.espathToPair[espath];
9677 if (pair.left && pair.right) {
9678 pairs.push(pair);
9679 }
9680 });
9681 forEach(pairs, function (pair) {
9682 _this.compare(pair, writer);
9683 });
9684 });
9685};
9686
9687BinaryExpressionRenderer.prototype.compare = function (pair, writer) {
9688 if (isStringDiffTarget(pair)) {
9689 this.showStringDiff(pair, writer);
9690 } else {
9691 this.showExpectedAndActual(pair, writer);
9692 }
9693};
9694
9695BinaryExpressionRenderer.prototype.showExpectedAndActual = function (pair, writer) {
9696 writer.write('');
9697 writer.write('[' + typeName(pair.right.value) + '] ' + pair.right.code);
9698 writer.write('=> ' + this.stringify(pair.right.value));
9699 writer.write('[' + typeName(pair.left.value) + '] ' + pair.left.code);
9700 writer.write('=> ' + this.stringify(pair.left.value));
9701};
9702
9703BinaryExpressionRenderer.prototype.showStringDiff = function (pair, writer) {
9704 writer.write('');
9705 writer.write('--- [string] ' + pair.right.code);
9706 writer.write('+++ [string] ' + pair.left.code);
9707 writer.write(this.diff(pair.right.value, pair.left.value, this.config));
9708};
9709
9710function isTargetBinaryExpression (esNode) {
9711 return esNode &&
9712 esNode.currentNode.type === syntax.BinaryExpression &&
9713 (esNode.currentNode.operator === '===' || esNode.currentNode.operator === '==') &&
9714 esNode.isCaptured() &&
9715 !(esNode.value());
9716}
9717
9718function isStringDiffTarget(pair) {
9719 return typeof pair.left.value === 'string' && typeof pair.right.value === 'string';
9720}
9721
9722module.exports = BinaryExpressionRenderer;
9723
9724},{"array-foreach":9,"estraverse":34,"object-keys":37,"type-name":59}],42:[function(_dereq_,module,exports){
9725'use strict';
9726
9727var forEach = _dereq_('array-foreach');
9728
9729function DiagramRenderer (config) {
9730 this.config = config;
9731 this.events = [];
9732 this.stringify = config.stringify;
9733 this.widthOf = config.widthOf;
9734 this.initialVertivalBarLength = 1;
9735}
9736
9737DiagramRenderer.prototype.init = function (traversal) {
9738 var _this = this;
9739 traversal.on('start', function (context) {
9740 _this.context = context;
9741 _this.assertionLine = context.source.content;
9742 _this.initializeRows();
9743 });
9744 traversal.on('esnode', function (esNode) {
9745 if (!esNode.isCaptured()) {
9746 return;
9747 }
9748 _this.events.push({value: esNode.value(), loc: esNode.location()});
9749 });
9750 traversal.on('render', function (writer) {
9751 _this.events.sort(rightToLeft);
9752 _this.constructRows(_this.events);
9753 forEach(_this.rows, function (columns) {
9754 writer.write(columns.join(''));
9755 });
9756 });
9757};
9758
9759DiagramRenderer.prototype.initializeRows = function () {
9760 this.rows = [];
9761 for (var i = 0; i <= this.initialVertivalBarLength; i += 1) {
9762 this.addOneMoreRow();
9763 }
9764};
9765
9766DiagramRenderer.prototype.newRowFor = function (assertionLine) {
9767 return createRow(this.widthOf(assertionLine), ' ');
9768};
9769
9770DiagramRenderer.prototype.addOneMoreRow = function () {
9771 this.rows.push(this.newRowFor(this.assertionLine));
9772};
9773
9774DiagramRenderer.prototype.lastRow = function () {
9775 return this.rows[this.rows.length - 1];
9776};
9777
9778DiagramRenderer.prototype.renderVerticalBarAt = function (columnIndex) {
9779 var i, lastRowIndex = this.rows.length - 1;
9780 for (i = 0; i < lastRowIndex; i += 1) {
9781 this.rows[i].splice(columnIndex, 1, '|');
9782 }
9783};
9784
9785DiagramRenderer.prototype.renderValueAt = function (columnIndex, dumpedValue) {
9786 var i, width = this.widthOf(dumpedValue);
9787 for (i = 0; i < width; i += 1) {
9788 this.lastRow().splice(columnIndex + i, 1, dumpedValue.charAt(i));
9789 }
9790};
9791
9792DiagramRenderer.prototype.isOverlapped = function (prevCapturing, nextCaputuring, dumpedValue) {
9793 return (typeof prevCapturing !== 'undefined') && this.startColumnFor(prevCapturing) <= (this.startColumnFor(nextCaputuring) + this.widthOf(dumpedValue));
9794};
9795
9796DiagramRenderer.prototype.constructRows = function (capturedEvents) {
9797 var that = this;
9798 var prevCaptured;
9799 forEach(capturedEvents, function (captured) {
9800 var dumpedValue = that.stringify(captured.value);
9801 if (that.isOverlapped(prevCaptured, captured, dumpedValue)) {
9802 that.addOneMoreRow();
9803 }
9804 that.renderVerticalBarAt(that.startColumnFor(captured));
9805 that.renderValueAt(that.startColumnFor(captured), dumpedValue);
9806 prevCaptured = captured;
9807 });
9808};
9809
9810DiagramRenderer.prototype.startColumnFor = function (captured) {
9811 return this.widthOf(this.assertionLine.slice(0, captured.loc.start.column));
9812};
9813
9814function createRow (numCols, initial) {
9815 var row = [], i;
9816 for(i = 0; i < numCols; i += 1) {
9817 row[i] = initial;
9818 }
9819 return row;
9820}
9821
9822function rightToLeft (a, b) {
9823 return b.loc.start.column - a.loc.start.column;
9824}
9825
9826module.exports = DiagramRenderer;
9827
9828},{"array-foreach":9}],43:[function(_dereq_,module,exports){
9829'use strict';
9830
9831function FileRenderer (config) {
9832}
9833
9834FileRenderer.prototype.init = function (traversal) {
9835 var filepath, lineNumber;
9836 traversal.on('start', function (context) {
9837 filepath = context.source.filepath;
9838 lineNumber = context.source.line;
9839 });
9840 traversal.on('render', function (writer) {
9841 if (filepath) {
9842 writer.write('# ' + [filepath, lineNumber].join(':'));
9843 } else {
9844 writer.write('# at line: ' + lineNumber);
9845 }
9846 });
9847};
9848
9849module.exports = FileRenderer;
9850
9851},{}],44:[function(_dereq_,module,exports){
9852'use strict';
9853
9854var stringifier = _dereq_('stringifier');
9855var stringWidth = _dereq_('./string-width');
9856var StringWriter = _dereq_('./string-writer');
9857var ContextTraversal = _dereq_('./traverse');
9858var udiff = _dereq_('./udiff');
9859var defaultOptions = _dereq_('./default-options');
9860var typeName = _dereq_('type-name');
9861var extend = _dereq_('xtend');
9862var map = _dereq_('array-map');
9863
9864var AssertionRenderer = _dereq_('./built-in/assertion');
9865var FileRenderer = _dereq_('./built-in/file');
9866var DiagramRenderer = _dereq_('./built-in/diagram');
9867var BinaryExpressionRenderer = _dereq_('./built-in/binary-expression');
9868
9869// "Browserify can only analyze static requires. It is not in the scope of browserify to handle dynamic requires."
9870// https://github.com/substack/node-browserify/issues/377
9871var defaultRendererClasses = {
9872 './built-in/file': FileRenderer,
9873 './built-in/assertion': AssertionRenderer,
9874 './built-in/diagram': DiagramRenderer,
9875 './built-in/binary-expression': BinaryExpressionRenderer
9876};
9877
9878function findRendererClass (rendererName, config) {
9879 var RendererClass;
9880 if (typeName(rendererName) === 'function') {
9881 RendererClass = rendererName;
9882 } else if (typeName(rendererName) === 'string') {
9883 if (defaultRendererClasses[rendererName]) {
9884 RendererClass = defaultRendererClasses[rendererName];
9885 } else {
9886 RendererClass = _dereq_(rendererName);
9887 }
9888 }
9889 return RendererClass;
9890}
9891
9892function configure (options) {
9893 var config = extend(defaultOptions(), options);
9894 if (typeof config.widthOf !== 'function') {
9895 config.widthOf = stringWidth(extend(config));
9896 }
9897 if (typeof config.stringify !== 'function') {
9898 config.stringify = stringifier(extend(config));
9899 }
9900 if (typeof config.diff !== 'function') {
9901 config.diff = udiff(extend(config));
9902 }
9903 if (!config.writerClass) {
9904 config.writerClass = StringWriter;
9905 }
9906 return config;
9907}
9908
9909function create (options) {
9910 var config = configure(options);
9911 var rendererClasses = map(config.renderers, function (rendererName) {
9912 return findRendererClass(rendererName, config);
9913 });
9914 return function (context) {
9915 var traversal = new ContextTraversal(context);
9916 var writer = new config.writerClass(extend(config));
9917 var renderers = map(rendererClasses, function (RendererClass) {
9918 var renderer;
9919 if (RendererClass.length === 2) {
9920 renderer = new RendererClass(traversal, extend(config));
9921 } else {
9922 renderer = new RendererClass(extend(config));
9923 renderer.init(traversal);
9924 }
9925 return renderer;
9926 });
9927 traversal.emit('start', context);
9928 traversal.traverse();
9929 traversal.emit('render', writer);
9930 writer.write('');
9931 renderers.length = 0;
9932 return writer.flush();
9933 };
9934}
9935
9936create.renderers = {
9937 AssertionRenderer: AssertionRenderer,
9938 FileRenderer: FileRenderer,
9939 DiagramRenderer: DiagramRenderer,
9940 BinaryExpressionRenderer: BinaryExpressionRenderer
9941};
9942create.defaultOptions = defaultOptions;
9943create.stringWidth = stringWidth;
9944module.exports = create;
9945
9946},{"./built-in/assertion":40,"./built-in/binary-expression":41,"./built-in/diagram":42,"./built-in/file":43,"./default-options":45,"./string-width":48,"./string-writer":49,"./traverse":50,"./udiff":51,"array-map":10,"stringifier":55,"type-name":59,"xtend":60}],45:[function(_dereq_,module,exports){
9947module.exports = function defaultOptions () {
9948 'use strict';
9949 return {
9950 lineDiffThreshold: 5,
9951 maxDepth: 1,
9952 outputOffset: 2,
9953 anonymous: 'Object',
9954 circular: '#@Circular#',
9955 lineSeparator: '\n',
9956 ambiguousEastAsianCharWidth: 2,
9957 renderers: [
9958 './built-in/file',
9959 './built-in/assertion',
9960 './built-in/diagram',
9961 './built-in/binary-expression'
9962 ]
9963 };
9964};
9965
9966},{}],46:[function(_dereq_,module,exports){
9967'use strict';
9968
9969var syntax = _dereq_('estraverse').Syntax;
9970var locationOf = _dereq_('./location');
9971
9972function EsNode (path, currentNode, parentNode, espathToValue, jsCode, tokens) {
9973 if (path) {
9974 this.espath = path.join('/');
9975 this.parentEspath = path.slice(0, path.length - 1).join('/');
9976 this.currentProp = path[path.length - 1];
9977 } else {
9978 this.espath = '';
9979 this.parentEspath = '';
9980 this.currentProp = null;
9981 }
9982 this.currentNode = currentNode;
9983 this.parentNode = parentNode;
9984 this.parentEsNode = null;
9985 this.espathToValue = espathToValue;
9986 this.jsCode = jsCode;
9987 this.tokens = tokens;
9988}
9989
9990EsNode.prototype.setParent = function (parentEsNode) {
9991 this.parentEsNode = parentEsNode;
9992};
9993
9994EsNode.prototype.getParent = function () {
9995 return this.parentEsNode;
9996};
9997
9998EsNode.prototype.code = function () {
9999 return this.jsCode.slice(this.currentNode.loc.start.column, this.currentNode.loc.end.column);
10000};
10001
10002EsNode.prototype.value = function () {
10003 if (this.currentNode.type === syntax.Literal) {
10004 return this.currentNode.value;
10005 }
10006 return this.espathToValue[this.espath];
10007};
10008
10009EsNode.prototype.isCaptured = function () {
10010 return this.espathToValue.hasOwnProperty(this.espath);
10011};
10012
10013EsNode.prototype.location = function () {
10014 return locationOf(this.currentNode, this.tokens);
10015};
10016
10017module.exports = EsNode;
10018
10019},{"./location":47,"estraverse":34}],47:[function(_dereq_,module,exports){
10020'use strict';
10021
10022var syntax = _dereq_('estraverse').Syntax;
10023
10024function locationOf(currentNode, tokens) {
10025 switch(currentNode.type) {
10026 case syntax.MemberExpression:
10027 return propertyLocationOf(currentNode, tokens);
10028 case syntax.CallExpression:
10029 if (currentNode.callee.type === syntax.MemberExpression) {
10030 return propertyLocationOf(currentNode.callee, tokens);
10031 }
10032 break;
10033 case syntax.BinaryExpression:
10034 case syntax.LogicalExpression:
10035 case syntax.AssignmentExpression:
10036 return infixOperatorLocationOf(currentNode, tokens);
10037 default:
10038 break;
10039 }
10040 return currentNode.loc;
10041}
10042
10043function propertyLocationOf(memberExpression, tokens) {
10044 var prop = memberExpression.property;
10045 var token;
10046 if (!memberExpression.computed) {
10047 return prop.loc;
10048 }
10049 token = findLeftBracketTokenOf(memberExpression, tokens);
10050 return token ? token.loc : prop.loc;
10051}
10052
10053// calculate location of infix operator for BinaryExpression, AssignmentExpression and LogicalExpression.
10054function infixOperatorLocationOf (expression, tokens) {
10055 var token = findOperatorTokenOf(expression, tokens);
10056 return token ? token.loc : expression.left.loc;
10057}
10058
10059function findLeftBracketTokenOf(expression, tokens) {
10060 var fromLine = expression.loc.start.line;
10061 var toLine = expression.property.loc.start.line;
10062 var fromColumn = expression.property.loc.start.column;
10063 return searchToken(tokens, fromLine, toLine, function (token, index) {
10064 var prevToken;
10065 if (token.loc.start.column === fromColumn) {
10066 prevToken = tokens[index - 1];
10067 if (prevToken.type === 'Punctuator' && prevToken.value === '[') { // esprima
10068 // if (prevToken.type.label === '[') { // acorn
10069 return prevToken;
10070 }
10071 }
10072 return undefined;
10073 });
10074}
10075
10076function findOperatorTokenOf(expression, tokens) {
10077 var fromLine = expression.left.loc.end.line;
10078 var toLine = expression.right.loc.start.line;
10079 var fromColumn = expression.left.loc.end.column;
10080 var toColumn = expression.right.loc.start.column;
10081 return searchToken(tokens, fromLine, toLine, function (token, index) {
10082 if (fromColumn < token.loc.start.column &&
10083 token.loc.end.column < toColumn &&
10084 token.value === expression.operator) {
10085 return token;
10086 }
10087 return undefined;
10088 });
10089}
10090
10091function searchToken(tokens, fromLine, toLine, predicate) {
10092 var i, token, found;
10093 for(i = 0; i < tokens.length; i += 1) {
10094 token = tokens[i];
10095 if (token.loc.start.line < fromLine) {
10096 continue;
10097 }
10098 if (toLine < token.loc.end.line) {
10099 break;
10100 }
10101 found = predicate(token, i);
10102 if (found) {
10103 return found;
10104 }
10105 }
10106 return undefined;
10107}
10108
10109module.exports = locationOf;
10110
10111},{"estraverse":34}],48:[function(_dereq_,module,exports){
10112'use strict';
10113
10114var eaw = _dereq_('eastasianwidth');
10115
10116function stringWidth (config) {
10117 var ambiguousCharWidth = (config && config.ambiguousEastAsianCharWidth) || 1;
10118 return function widthOf (str) {
10119 var i, code, width = 0;
10120 for(i = 0; i < str.length; i+=1) {
10121 code = eaw.eastAsianWidth(str.charAt(i));
10122 switch(code) {
10123 case 'F':
10124 case 'W':
10125 width += 2;
10126 break;
10127 case 'H':
10128 case 'Na':
10129 case 'N':
10130 width += 1;
10131 break;
10132 case 'A':
10133 width += ambiguousCharWidth;
10134 break;
10135 }
10136 }
10137 return width;
10138 };
10139}
10140
10141module.exports = stringWidth;
10142
10143},{"eastasianwidth":52}],49:[function(_dereq_,module,exports){
10144'use strict';
10145
10146function spacerStr (len) {
10147 var str = '';
10148 for(var i = 0; i < len; i += 1) {
10149 str += ' ';
10150 }
10151 return str;
10152}
10153
10154function StringWriter (config) {
10155 this.lines = [];
10156 this.lineSeparator = config.lineSeparator;
10157 this.regex = new RegExp(this.lineSeparator, 'g');
10158 this.spacer = spacerStr(config.outputOffset);
10159}
10160
10161StringWriter.prototype.write = function (str) {
10162 this.lines.push(this.spacer + str.replace(this.regex, this.lineSeparator + this.spacer));
10163};
10164
10165StringWriter.prototype.flush = function () {
10166 var str = this.lines.join(this.lineSeparator);
10167 this.lines.length = 0;
10168 return str;
10169};
10170
10171module.exports = StringWriter;
10172
10173},{}],50:[function(_dereq_,module,exports){
10174'use strict';
10175
10176var estraverse = _dereq_('estraverse');
10177var esprima = _dereq_('esprima');
10178var EventEmitter = _dereq_('events').EventEmitter;
10179var inherits = _dereq_('util').inherits;
10180var EsNode = _dereq_('./esnode');
10181var forEach = _dereq_('array-foreach');
10182var reduce = _dereq_('array-reduce');
10183
10184function ContextTraversal (context) {
10185 this.context = context;
10186 EventEmitter.call(this);
10187}
10188inherits(ContextTraversal, EventEmitter);
10189
10190ContextTraversal.prototype.traverse = function () {
10191 var _this = this;
10192 forEach(this.context.args, function (arg) {
10193 onEachEsNode(arg, _this.context.source.content, function (esNode) {
10194 _this.emit('esnode', esNode);
10195 });
10196 });
10197};
10198
10199function onEachEsNode(arg, jsCode, callback) {
10200 var jsAST = esprima.parse(jsCode, {sourceType: 'module', tolerant: true, loc: true, tokens: true, raw: true});
10201 var tokens = jsAST.tokens;
10202 var espathToValue = reduce(arg.events, function (accum, ev) {
10203 accum[ev.espath] = ev.value;
10204 return accum;
10205 }, {});
10206 var nodeStack = [];
10207 estraverse.traverse(extractExpressionFrom(jsAST), {
10208 enter: function (currentNode, parentNode) {
10209 var esNode = new EsNode(this.path(), currentNode, parentNode, espathToValue, jsCode, tokens);
10210 if (1 < nodeStack.length) {
10211 esNode.setParent(nodeStack[nodeStack.length - 1]);
10212 }
10213 nodeStack.push(esNode);
10214 callback(esNode);
10215 },
10216 leave: function (currentNode, parentNode) {
10217 nodeStack.pop();
10218 }
10219 });
10220}
10221
10222function extractExpressionFrom (tree) {
10223 var expressionStatement = tree.body[0];
10224 var expression = expressionStatement.expression;
10225 return expression;
10226}
10227
10228module.exports = ContextTraversal;
10229
10230},{"./esnode":46,"array-foreach":9,"array-reduce":11,"esprima":33,"estraverse":34,"events":3,"util":7}],51:[function(_dereq_,module,exports){
10231'use strict';
10232
10233var DiffMatchPatch = _dereq_('googlediff');
10234var dmp = new DiffMatchPatch();
10235
10236function udiff (config) {
10237 return function diff (text1, text2) {
10238 var patch;
10239 if (config && shouldUseLineLevelDiff(text1, config)) {
10240 patch = udiffLines(text1, text2);
10241 } else {
10242 patch = udiffChars(text1, text2);
10243 }
10244 return decodeURIComponent(patch);
10245 };
10246}
10247
10248function shouldUseLineLevelDiff (text, config) {
10249 return config.lineDiffThreshold < text.split(/\r\n|\r|\n/).length;
10250}
10251
10252function udiffLines(text1, text2) {
10253 /*jshint camelcase: false */
10254 var a = dmp.diff_linesToChars_(text1, text2);
10255 var diffs = dmp.diff_main(a.chars1, a.chars2, false);
10256 dmp.diff_charsToLines_(diffs, a.lineArray);
10257 dmp.diff_cleanupSemantic(diffs);
10258 return dmp.patch_toText(dmp.patch_make(text1, diffs));
10259}
10260
10261function udiffChars (text1, text2) {
10262 /*jshint camelcase: false */
10263 var diffs = dmp.diff_main(text1, text2, false);
10264 dmp.diff_cleanupSemantic(diffs);
10265 return dmp.patch_toText(dmp.patch_make(text1, diffs));
10266}
10267
10268module.exports = udiff;
10269
10270},{"googlediff":53}],52:[function(_dereq_,module,exports){
10271var eaw = exports;
10272
10273eaw.eastAsianWidth = function(character) {
10274 var x = character.charCodeAt(0);
10275 var y = (character.length == 2) ? character.charCodeAt(1) : 0;
10276 var codePoint = x;
10277 if ((0xD800 <= x && x <= 0xDBFF) && (0xDC00 <= y && y <= 0xDFFF)) {
10278 x &= 0x3FF;
10279 y &= 0x3FF;
10280 codePoint = (x << 10) | y;
10281 codePoint += 0x10000;
10282 }
10283
10284 if ((0x3000 == codePoint) ||
10285 (0xFF01 <= codePoint && codePoint <= 0xFF60) ||
10286 (0xFFE0 <= codePoint && codePoint <= 0xFFE6)) {
10287 return 'F';
10288 }
10289 if ((0x20A9 == codePoint) ||
10290 (0xFF61 <= codePoint && codePoint <= 0xFFBE) ||
10291 (0xFFC2 <= codePoint && codePoint <= 0xFFC7) ||
10292 (0xFFCA <= codePoint && codePoint <= 0xFFCF) ||
10293 (0xFFD2 <= codePoint && codePoint <= 0xFFD7) ||
10294 (0xFFDA <= codePoint && codePoint <= 0xFFDC) ||
10295 (0xFFE8 <= codePoint && codePoint <= 0xFFEE)) {
10296 return 'H';
10297 }
10298 if ((0x1100 <= codePoint && codePoint <= 0x115F) ||
10299 (0x11A3 <= codePoint && codePoint <= 0x11A7) ||
10300 (0x11FA <= codePoint && codePoint <= 0x11FF) ||
10301 (0x2329 <= codePoint && codePoint <= 0x232A) ||
10302 (0x2E80 <= codePoint && codePoint <= 0x2E99) ||
10303 (0x2E9B <= codePoint && codePoint <= 0x2EF3) ||
10304 (0x2F00 <= codePoint && codePoint <= 0x2FD5) ||
10305 (0x2FF0 <= codePoint && codePoint <= 0x2FFB) ||
10306 (0x3001 <= codePoint && codePoint <= 0x303E) ||
10307 (0x3041 <= codePoint && codePoint <= 0x3096) ||
10308 (0x3099 <= codePoint && codePoint <= 0x30FF) ||
10309 (0x3105 <= codePoint && codePoint <= 0x312D) ||
10310 (0x3131 <= codePoint && codePoint <= 0x318E) ||
10311 (0x3190 <= codePoint && codePoint <= 0x31BA) ||
10312 (0x31C0 <= codePoint && codePoint <= 0x31E3) ||
10313 (0x31F0 <= codePoint && codePoint <= 0x321E) ||
10314 (0x3220 <= codePoint && codePoint <= 0x3247) ||
10315 (0x3250 <= codePoint && codePoint <= 0x32FE) ||
10316 (0x3300 <= codePoint && codePoint <= 0x4DBF) ||
10317 (0x4E00 <= codePoint && codePoint <= 0xA48C) ||
10318 (0xA490 <= codePoint && codePoint <= 0xA4C6) ||
10319 (0xA960 <= codePoint && codePoint <= 0xA97C) ||
10320 (0xAC00 <= codePoint && codePoint <= 0xD7A3) ||
10321 (0xD7B0 <= codePoint && codePoint <= 0xD7C6) ||
10322 (0xD7CB <= codePoint && codePoint <= 0xD7FB) ||
10323 (0xF900 <= codePoint && codePoint <= 0xFAFF) ||
10324 (0xFE10 <= codePoint && codePoint <= 0xFE19) ||
10325 (0xFE30 <= codePoint && codePoint <= 0xFE52) ||
10326 (0xFE54 <= codePoint && codePoint <= 0xFE66) ||
10327 (0xFE68 <= codePoint && codePoint <= 0xFE6B) ||
10328 (0x1B000 <= codePoint && codePoint <= 0x1B001) ||
10329 (0x1F200 <= codePoint && codePoint <= 0x1F202) ||
10330 (0x1F210 <= codePoint && codePoint <= 0x1F23A) ||
10331 (0x1F240 <= codePoint && codePoint <= 0x1F248) ||
10332 (0x1F250 <= codePoint && codePoint <= 0x1F251) ||
10333 (0x20000 <= codePoint && codePoint <= 0x2F73F) ||
10334 (0x2B740 <= codePoint && codePoint <= 0x2FFFD) ||
10335 (0x30000 <= codePoint && codePoint <= 0x3FFFD)) {
10336 return 'W';
10337 }
10338 if ((0x0020 <= codePoint && codePoint <= 0x007E) ||
10339 (0x00A2 <= codePoint && codePoint <= 0x00A3) ||
10340 (0x00A5 <= codePoint && codePoint <= 0x00A6) ||
10341 (0x00AC == codePoint) ||
10342 (0x00AF == codePoint) ||
10343 (0x27E6 <= codePoint && codePoint <= 0x27ED) ||
10344 (0x2985 <= codePoint && codePoint <= 0x2986)) {
10345 return 'Na';
10346 }
10347 if ((0x00A1 == codePoint) ||
10348 (0x00A4 == codePoint) ||
10349 (0x00A7 <= codePoint && codePoint <= 0x00A8) ||
10350 (0x00AA == codePoint) ||
10351 (0x00AD <= codePoint && codePoint <= 0x00AE) ||
10352 (0x00B0 <= codePoint && codePoint <= 0x00B4) ||
10353 (0x00B6 <= codePoint && codePoint <= 0x00BA) ||
10354 (0x00BC <= codePoint && codePoint <= 0x00BF) ||
10355 (0x00C6 == codePoint) ||
10356 (0x00D0 == codePoint) ||
10357 (0x00D7 <= codePoint && codePoint <= 0x00D8) ||
10358 (0x00DE <= codePoint && codePoint <= 0x00E1) ||
10359 (0x00E6 == codePoint) ||
10360 (0x00E8 <= codePoint && codePoint <= 0x00EA) ||
10361 (0x00EC <= codePoint && codePoint <= 0x00ED) ||
10362 (0x00F0 == codePoint) ||
10363 (0x00F2 <= codePoint && codePoint <= 0x00F3) ||
10364 (0x00F7 <= codePoint && codePoint <= 0x00FA) ||
10365 (0x00FC == codePoint) ||
10366 (0x00FE == codePoint) ||
10367 (0x0101 == codePoint) ||
10368 (0x0111 == codePoint) ||
10369 (0x0113 == codePoint) ||
10370 (0x011B == codePoint) ||
10371 (0x0126 <= codePoint && codePoint <= 0x0127) ||
10372 (0x012B == codePoint) ||
10373 (0x0131 <= codePoint && codePoint <= 0x0133) ||
10374 (0x0138 == codePoint) ||
10375 (0x013F <= codePoint && codePoint <= 0x0142) ||
10376 (0x0144 == codePoint) ||
10377 (0x0148 <= codePoint && codePoint <= 0x014B) ||
10378 (0x014D == codePoint) ||
10379 (0x0152 <= codePoint && codePoint <= 0x0153) ||
10380 (0x0166 <= codePoint && codePoint <= 0x0167) ||
10381 (0x016B == codePoint) ||
10382 (0x01CE == codePoint) ||
10383 (0x01D0 == codePoint) ||
10384 (0x01D2 == codePoint) ||
10385 (0x01D4 == codePoint) ||
10386 (0x01D6 == codePoint) ||
10387 (0x01D8 == codePoint) ||
10388 (0x01DA == codePoint) ||
10389 (0x01DC == codePoint) ||
10390 (0x0251 == codePoint) ||
10391 (0x0261 == codePoint) ||
10392 (0x02C4 == codePoint) ||
10393 (0x02C7 == codePoint) ||
10394 (0x02C9 <= codePoint && codePoint <= 0x02CB) ||
10395 (0x02CD == codePoint) ||
10396 (0x02D0 == codePoint) ||
10397 (0x02D8 <= codePoint && codePoint <= 0x02DB) ||
10398 (0x02DD == codePoint) ||
10399 (0x02DF == codePoint) ||
10400 (0x0300 <= codePoint && codePoint <= 0x036F) ||
10401 (0x0391 <= codePoint && codePoint <= 0x03A1) ||
10402 (0x03A3 <= codePoint && codePoint <= 0x03A9) ||
10403 (0x03B1 <= codePoint && codePoint <= 0x03C1) ||
10404 (0x03C3 <= codePoint && codePoint <= 0x03C9) ||
10405 (0x0401 == codePoint) ||
10406 (0x0410 <= codePoint && codePoint <= 0x044F) ||
10407 (0x0451 == codePoint) ||
10408 (0x2010 == codePoint) ||
10409 (0x2013 <= codePoint && codePoint <= 0x2016) ||
10410 (0x2018 <= codePoint && codePoint <= 0x2019) ||
10411 (0x201C <= codePoint && codePoint <= 0x201D) ||
10412 (0x2020 <= codePoint && codePoint <= 0x2022) ||
10413 (0x2024 <= codePoint && codePoint <= 0x2027) ||
10414 (0x2030 == codePoint) ||
10415 (0x2032 <= codePoint && codePoint <= 0x2033) ||
10416 (0x2035 == codePoint) ||
10417 (0x203B == codePoint) ||
10418 (0x203E == codePoint) ||
10419 (0x2074 == codePoint) ||
10420 (0x207F == codePoint) ||
10421 (0x2081 <= codePoint && codePoint <= 0x2084) ||
10422 (0x20AC == codePoint) ||
10423 (0x2103 == codePoint) ||
10424 (0x2105 == codePoint) ||
10425 (0x2109 == codePoint) ||
10426 (0x2113 == codePoint) ||
10427 (0x2116 == codePoint) ||
10428 (0x2121 <= codePoint && codePoint <= 0x2122) ||
10429 (0x2126 == codePoint) ||
10430 (0x212B == codePoint) ||
10431 (0x2153 <= codePoint && codePoint <= 0x2154) ||
10432 (0x215B <= codePoint && codePoint <= 0x215E) ||
10433 (0x2160 <= codePoint && codePoint <= 0x216B) ||
10434 (0x2170 <= codePoint && codePoint <= 0x2179) ||
10435 (0x2189 == codePoint) ||
10436 (0x2190 <= codePoint && codePoint <= 0x2199) ||
10437 (0x21B8 <= codePoint && codePoint <= 0x21B9) ||
10438 (0x21D2 == codePoint) ||
10439 (0x21D4 == codePoint) ||
10440 (0x21E7 == codePoint) ||
10441 (0x2200 == codePoint) ||
10442 (0x2202 <= codePoint && codePoint <= 0x2203) ||
10443 (0x2207 <= codePoint && codePoint <= 0x2208) ||
10444 (0x220B == codePoint) ||
10445 (0x220F == codePoint) ||
10446 (0x2211 == codePoint) ||
10447 (0x2215 == codePoint) ||
10448 (0x221A == codePoint) ||
10449 (0x221D <= codePoint && codePoint <= 0x2220) ||
10450 (0x2223 == codePoint) ||
10451 (0x2225 == codePoint) ||
10452 (0x2227 <= codePoint && codePoint <= 0x222C) ||
10453 (0x222E == codePoint) ||
10454 (0x2234 <= codePoint && codePoint <= 0x2237) ||
10455 (0x223C <= codePoint && codePoint <= 0x223D) ||
10456 (0x2248 == codePoint) ||
10457 (0x224C == codePoint) ||
10458 (0x2252 == codePoint) ||
10459 (0x2260 <= codePoint && codePoint <= 0x2261) ||
10460 (0x2264 <= codePoint && codePoint <= 0x2267) ||
10461 (0x226A <= codePoint && codePoint <= 0x226B) ||
10462 (0x226E <= codePoint && codePoint <= 0x226F) ||
10463 (0x2282 <= codePoint && codePoint <= 0x2283) ||
10464 (0x2286 <= codePoint && codePoint <= 0x2287) ||
10465 (0x2295 == codePoint) ||
10466 (0x2299 == codePoint) ||
10467 (0x22A5 == codePoint) ||
10468 (0x22BF == codePoint) ||
10469 (0x2312 == codePoint) ||
10470 (0x2460 <= codePoint && codePoint <= 0x24E9) ||
10471 (0x24EB <= codePoint && codePoint <= 0x254B) ||
10472 (0x2550 <= codePoint && codePoint <= 0x2573) ||
10473 (0x2580 <= codePoint && codePoint <= 0x258F) ||
10474 (0x2592 <= codePoint && codePoint <= 0x2595) ||
10475 (0x25A0 <= codePoint && codePoint <= 0x25A1) ||
10476 (0x25A3 <= codePoint && codePoint <= 0x25A9) ||
10477 (0x25B2 <= codePoint && codePoint <= 0x25B3) ||
10478 (0x25B6 <= codePoint && codePoint <= 0x25B7) ||
10479 (0x25BC <= codePoint && codePoint <= 0x25BD) ||
10480 (0x25C0 <= codePoint && codePoint <= 0x25C1) ||
10481 (0x25C6 <= codePoint && codePoint <= 0x25C8) ||
10482 (0x25CB == codePoint) ||
10483 (0x25CE <= codePoint && codePoint <= 0x25D1) ||
10484 (0x25E2 <= codePoint && codePoint <= 0x25E5) ||
10485 (0x25EF == codePoint) ||
10486 (0x2605 <= codePoint && codePoint <= 0x2606) ||
10487 (0x2609 == codePoint) ||
10488 (0x260E <= codePoint && codePoint <= 0x260F) ||
10489 (0x2614 <= codePoint && codePoint <= 0x2615) ||
10490 (0x261C == codePoint) ||
10491 (0x261E == codePoint) ||
10492 (0x2640 == codePoint) ||
10493 (0x2642 == codePoint) ||
10494 (0x2660 <= codePoint && codePoint <= 0x2661) ||
10495 (0x2663 <= codePoint && codePoint <= 0x2665) ||
10496 (0x2667 <= codePoint && codePoint <= 0x266A) ||
10497 (0x266C <= codePoint && codePoint <= 0x266D) ||
10498 (0x266F == codePoint) ||
10499 (0x269E <= codePoint && codePoint <= 0x269F) ||
10500 (0x26BE <= codePoint && codePoint <= 0x26BF) ||
10501 (0x26C4 <= codePoint && codePoint <= 0x26CD) ||
10502 (0x26CF <= codePoint && codePoint <= 0x26E1) ||
10503 (0x26E3 == codePoint) ||
10504 (0x26E8 <= codePoint && codePoint <= 0x26FF) ||
10505 (0x273D == codePoint) ||
10506 (0x2757 == codePoint) ||
10507 (0x2776 <= codePoint && codePoint <= 0x277F) ||
10508 (0x2B55 <= codePoint && codePoint <= 0x2B59) ||
10509 (0x3248 <= codePoint && codePoint <= 0x324F) ||
10510 (0xE000 <= codePoint && codePoint <= 0xF8FF) ||
10511 (0xFE00 <= codePoint && codePoint <= 0xFE0F) ||
10512 (0xFFFD == codePoint) ||
10513 (0x1F100 <= codePoint && codePoint <= 0x1F10A) ||
10514 (0x1F110 <= codePoint && codePoint <= 0x1F12D) ||
10515 (0x1F130 <= codePoint && codePoint <= 0x1F169) ||
10516 (0x1F170 <= codePoint && codePoint <= 0x1F19A) ||
10517 (0xE0100 <= codePoint && codePoint <= 0xE01EF) ||
10518 (0xF0000 <= codePoint && codePoint <= 0xFFFFD) ||
10519 (0x100000 <= codePoint && codePoint <= 0x10FFFD)) {
10520 return 'A';
10521 }
10522
10523 return 'N';
10524};
10525
10526eaw.characterLength = function(character) {
10527 var code = this.eastAsianWidth(character);
10528 if (code == 'F' || code == 'W' || code == 'A') {
10529 return 2;
10530 } else {
10531 return 1;
10532 }
10533};
10534
10535eaw.length = function(string) {
10536 var len = 0;
10537 for (var i = 0; i < string.length; i++) {
10538 len = len + this.characterLength(string.charAt(i));
10539 }
10540 return len;
10541};
10542
10543},{}],53:[function(_dereq_,module,exports){
10544module.exports = _dereq_('./javascript/diff_match_patch_uncompressed.js').diff_match_patch;
10545
10546},{"./javascript/diff_match_patch_uncompressed.js":54}],54:[function(_dereq_,module,exports){
10547/**
10548 * Diff Match and Patch
10549 *
10550 * Copyright 2006 Google Inc.
10551 * http://code.google.com/p/google-diff-match-patch/
10552 *
10553 * Licensed under the Apache License, Version 2.0 (the "License");
10554 * you may not use this file except in compliance with the License.
10555 * You may obtain a copy of the License at
10556 *
10557 * http://www.apache.org/licenses/LICENSE-2.0
10558 *
10559 * Unless required by applicable law or agreed to in writing, software
10560 * distributed under the License is distributed on an "AS IS" BASIS,
10561 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10562 * See the License for the specific language governing permissions and
10563 * limitations under the License.
10564 */
10565
10566/**
10567 * @fileoverview Computes the difference between two texts to create a patch.
10568 * Applies the patch onto another text, allowing for errors.
10569 * @author fraser@google.com (Neil Fraser)
10570 */
10571
10572/**
10573 * Class containing the diff, match and patch methods.
10574 * @constructor
10575 */
10576function diff_match_patch() {
10577
10578 // Defaults.
10579 // Redefine these in your program to override the defaults.
10580
10581 // Number of seconds to map a diff before giving up (0 for infinity).
10582 this.Diff_Timeout = 1.0;
10583 // Cost of an empty edit operation in terms of edit characters.
10584 this.Diff_EditCost = 4;
10585 // At what point is no match declared (0.0 = perfection, 1.0 = very loose).
10586 this.Match_Threshold = 0.5;
10587 // How far to search for a match (0 = exact location, 1000+ = broad match).
10588 // A match this many characters away from the expected location will add
10589 // 1.0 to the score (0.0 is a perfect match).
10590 this.Match_Distance = 1000;
10591 // When deleting a large block of text (over ~64 characters), how close do
10592 // the contents have to be to match the expected contents. (0.0 = perfection,
10593 // 1.0 = very loose). Note that Match_Threshold controls how closely the
10594 // end points of a delete need to match.
10595 this.Patch_DeleteThreshold = 0.5;
10596 // Chunk size for context length.
10597 this.Patch_Margin = 4;
10598
10599 // The number of bits in an int.
10600 this.Match_MaxBits = 32;
10601}
10602
10603
10604// DIFF FUNCTIONS
10605
10606
10607/**
10608 * The data structure representing a diff is an array of tuples:
10609 * [[DIFF_DELETE, 'Hello'], [DIFF_INSERT, 'Goodbye'], [DIFF_EQUAL, ' world.']]
10610 * which means: delete 'Hello', add 'Goodbye' and keep ' world.'
10611 */
10612var DIFF_DELETE = -1;
10613var DIFF_INSERT = 1;
10614var DIFF_EQUAL = 0;
10615
10616/** @typedef {{0: number, 1: string}} */
10617diff_match_patch.Diff;
10618
10619
10620/**
10621 * Find the differences between two texts. Simplifies the problem by stripping
10622 * any common prefix or suffix off the texts before diffing.
10623 * @param {string} text1 Old string to be diffed.
10624 * @param {string} text2 New string to be diffed.
10625 * @param {boolean=} opt_checklines Optional speedup flag. If present and false,
10626 * then don't run a line-level diff first to identify the changed areas.
10627 * Defaults to true, which does a faster, slightly less optimal diff.
10628 * @param {number} opt_deadline Optional time when the diff should be complete
10629 * by. Used internally for recursive calls. Users should set DiffTimeout
10630 * instead.
10631 * @return {!Array.<!diff_match_patch.Diff>} Array of diff tuples.
10632 */
10633diff_match_patch.prototype.diff_main = function(text1, text2, opt_checklines,
10634 opt_deadline) {
10635 // Set a deadline by which time the diff must be complete.
10636 if (typeof opt_deadline == 'undefined') {
10637 if (this.Diff_Timeout <= 0) {
10638 opt_deadline = Number.MAX_VALUE;
10639 } else {
10640 opt_deadline = (new Date).getTime() + this.Diff_Timeout * 1000;
10641 }
10642 }
10643 var deadline = opt_deadline;
10644
10645 // Check for null inputs.
10646 if (text1 == null || text2 == null) {
10647 throw new Error('Null input. (diff_main)');
10648 }
10649
10650 // Check for equality (speedup).
10651 if (text1 == text2) {
10652 if (text1) {
10653 return [[DIFF_EQUAL, text1]];
10654 }
10655 return [];
10656 }
10657
10658 if (typeof opt_checklines == 'undefined') {
10659 opt_checklines = true;
10660 }
10661 var checklines = opt_checklines;
10662
10663 // Trim off common prefix (speedup).
10664 var commonlength = this.diff_commonPrefix(text1, text2);
10665 var commonprefix = text1.substring(0, commonlength);
10666 text1 = text1.substring(commonlength);
10667 text2 = text2.substring(commonlength);
10668
10669 // Trim off common suffix (speedup).
10670 commonlength = this.diff_commonSuffix(text1, text2);
10671 var commonsuffix = text1.substring(text1.length - commonlength);
10672 text1 = text1.substring(0, text1.length - commonlength);
10673 text2 = text2.substring(0, text2.length - commonlength);
10674
10675 // Compute the diff on the middle block.
10676 var diffs = this.diff_compute_(text1, text2, checklines, deadline);
10677
10678 // Restore the prefix and suffix.
10679 if (commonprefix) {
10680 diffs.unshift([DIFF_EQUAL, commonprefix]);
10681 }
10682 if (commonsuffix) {
10683 diffs.push([DIFF_EQUAL, commonsuffix]);
10684 }
10685 this.diff_cleanupMerge(diffs);
10686 return diffs;
10687};
10688
10689
10690/**
10691 * Find the differences between two texts. Assumes that the texts do not
10692 * have any common prefix or suffix.
10693 * @param {string} text1 Old string to be diffed.
10694 * @param {string} text2 New string to be diffed.
10695 * @param {boolean} checklines Speedup flag. If false, then don't run a
10696 * line-level diff first to identify the changed areas.
10697 * If true, then run a faster, slightly less optimal diff.
10698 * @param {number} deadline Time when the diff should be complete by.
10699 * @return {!Array.<!diff_match_patch.Diff>} Array of diff tuples.
10700 * @private
10701 */
10702diff_match_patch.prototype.diff_compute_ = function(text1, text2, checklines,
10703 deadline) {
10704 var diffs;
10705
10706 if (!text1) {
10707 // Just add some text (speedup).
10708 return [[DIFF_INSERT, text2]];
10709 }
10710
10711 if (!text2) {
10712 // Just delete some text (speedup).
10713 return [[DIFF_DELETE, text1]];
10714 }
10715
10716 var longtext = text1.length > text2.length ? text1 : text2;
10717 var shorttext = text1.length > text2.length ? text2 : text1;
10718 var i = longtext.indexOf(shorttext);
10719 if (i != -1) {
10720 // Shorter text is inside the longer text (speedup).
10721 diffs = [[DIFF_INSERT, longtext.substring(0, i)],
10722 [DIFF_EQUAL, shorttext],
10723 [DIFF_INSERT, longtext.substring(i + shorttext.length)]];
10724 // Swap insertions for deletions if diff is reversed.
10725 if (text1.length > text2.length) {
10726 diffs[0][0] = diffs[2][0] = DIFF_DELETE;
10727 }
10728 return diffs;
10729 }
10730
10731 if (shorttext.length == 1) {
10732 // Single character string.
10733 // After the previous speedup, the character can't be an equality.
10734 return [[DIFF_DELETE, text1], [DIFF_INSERT, text2]];
10735 }
10736
10737 // Check to see if the problem can be split in two.
10738 var hm = this.diff_halfMatch_(text1, text2);
10739 if (hm) {
10740 // A half-match was found, sort out the return data.
10741 var text1_a = hm[0];
10742 var text1_b = hm[1];
10743 var text2_a = hm[2];
10744 var text2_b = hm[3];
10745 var mid_common = hm[4];
10746 // Send both pairs off for separate processing.
10747 var diffs_a = this.diff_main(text1_a, text2_a, checklines, deadline);
10748 var diffs_b = this.diff_main(text1_b, text2_b, checklines, deadline);
10749 // Merge the results.
10750 return diffs_a.concat([[DIFF_EQUAL, mid_common]], diffs_b);
10751 }
10752
10753 if (checklines && text1.length > 100 && text2.length > 100) {
10754 return this.diff_lineMode_(text1, text2, deadline);
10755 }
10756
10757 return this.diff_bisect_(text1, text2, deadline);
10758};
10759
10760
10761/**
10762 * Do a quick line-level diff on both strings, then rediff the parts for
10763 * greater accuracy.
10764 * This speedup can produce non-minimal diffs.
10765 * @param {string} text1 Old string to be diffed.
10766 * @param {string} text2 New string to be diffed.
10767 * @param {number} deadline Time when the diff should be complete by.
10768 * @return {!Array.<!diff_match_patch.Diff>} Array of diff tuples.
10769 * @private
10770 */
10771diff_match_patch.prototype.diff_lineMode_ = function(text1, text2, deadline) {
10772 // Scan the text on a line-by-line basis first.
10773 var a = this.diff_linesToChars_(text1, text2);
10774 text1 = a.chars1;
10775 text2 = a.chars2;
10776 var linearray = a.lineArray;
10777
10778 var diffs = this.diff_main(text1, text2, false, deadline);
10779
10780 // Convert the diff back to original text.
10781 this.diff_charsToLines_(diffs, linearray);
10782 // Eliminate freak matches (e.g. blank lines)
10783 this.diff_cleanupSemantic(diffs);
10784
10785 // Rediff any replacement blocks, this time character-by-character.
10786 // Add a dummy entry at the end.
10787 diffs.push([DIFF_EQUAL, '']);
10788 var pointer = 0;
10789 var count_delete = 0;
10790 var count_insert = 0;
10791 var text_delete = '';
10792 var text_insert = '';
10793 while (pointer < diffs.length) {
10794 switch (diffs[pointer][0]) {
10795 case DIFF_INSERT:
10796 count_insert++;
10797 text_insert += diffs[pointer][1];
10798 break;
10799 case DIFF_DELETE:
10800 count_delete++;
10801 text_delete += diffs[pointer][1];
10802 break;
10803 case DIFF_EQUAL:
10804 // Upon reaching an equality, check for prior redundancies.
10805 if (count_delete >= 1 && count_insert >= 1) {
10806 // Delete the offending records and add the merged ones.
10807 diffs.splice(pointer - count_delete - count_insert,
10808 count_delete + count_insert);
10809 pointer = pointer - count_delete - count_insert;
10810 var a = this.diff_main(text_delete, text_insert, false, deadline);
10811 for (var j = a.length - 1; j >= 0; j--) {
10812 diffs.splice(pointer, 0, a[j]);
10813 }
10814 pointer = pointer + a.length;
10815 }
10816 count_insert = 0;
10817 count_delete = 0;
10818 text_delete = '';
10819 text_insert = '';
10820 break;
10821 }
10822 pointer++;
10823 }
10824 diffs.pop(); // Remove the dummy entry at the end.
10825
10826 return diffs;
10827};
10828
10829
10830/**
10831 * Find the 'middle snake' of a diff, split the problem in two
10832 * and return the recursively constructed diff.
10833 * See Myers 1986 paper: An O(ND) Difference Algorithm and Its Variations.
10834 * @param {string} text1 Old string to be diffed.
10835 * @param {string} text2 New string to be diffed.
10836 * @param {number} deadline Time at which to bail if not yet complete.
10837 * @return {!Array.<!diff_match_patch.Diff>} Array of diff tuples.
10838 * @private
10839 */
10840diff_match_patch.prototype.diff_bisect_ = function(text1, text2, deadline) {
10841 // Cache the text lengths to prevent multiple calls.
10842 var text1_length = text1.length;
10843 var text2_length = text2.length;
10844 var max_d = Math.ceil((text1_length + text2_length) / 2);
10845 var v_offset = max_d;
10846 var v_length = 2 * max_d;
10847 var v1 = new Array(v_length);
10848 var v2 = new Array(v_length);
10849 // Setting all elements to -1 is faster in Chrome & Firefox than mixing
10850 // integers and undefined.
10851 for (var x = 0; x < v_length; x++) {
10852 v1[x] = -1;
10853 v2[x] = -1;
10854 }
10855 v1[v_offset + 1] = 0;
10856 v2[v_offset + 1] = 0;
10857 var delta = text1_length - text2_length;
10858 // If the total number of characters is odd, then the front path will collide
10859 // with the reverse path.
10860 var front = (delta % 2 != 0);
10861 // Offsets for start and end of k loop.
10862 // Prevents mapping of space beyond the grid.
10863 var k1start = 0;
10864 var k1end = 0;
10865 var k2start = 0;
10866 var k2end = 0;
10867 for (var d = 0; d < max_d; d++) {
10868 // Bail out if deadline is reached.
10869 if ((new Date()).getTime() > deadline) {
10870 break;
10871 }
10872
10873 // Walk the front path one step.
10874 for (var k1 = -d + k1start; k1 <= d - k1end; k1 += 2) {
10875 var k1_offset = v_offset + k1;
10876 var x1;
10877 if (k1 == -d || (k1 != d && v1[k1_offset - 1] < v1[k1_offset + 1])) {
10878 x1 = v1[k1_offset + 1];
10879 } else {
10880 x1 = v1[k1_offset - 1] + 1;
10881 }
10882 var y1 = x1 - k1;
10883 while (x1 < text1_length && y1 < text2_length &&
10884 text1.charAt(x1) == text2.charAt(y1)) {
10885 x1++;
10886 y1++;
10887 }
10888 v1[k1_offset] = x1;
10889 if (x1 > text1_length) {
10890 // Ran off the right of the graph.
10891 k1end += 2;
10892 } else if (y1 > text2_length) {
10893 // Ran off the bottom of the graph.
10894 k1start += 2;
10895 } else if (front) {
10896 var k2_offset = v_offset + delta - k1;
10897 if (k2_offset >= 0 && k2_offset < v_length && v2[k2_offset] != -1) {
10898 // Mirror x2 onto top-left coordinate system.
10899 var x2 = text1_length - v2[k2_offset];
10900 if (x1 >= x2) {
10901 // Overlap detected.
10902 return this.diff_bisectSplit_(text1, text2, x1, y1, deadline);
10903 }
10904 }
10905 }
10906 }
10907
10908 // Walk the reverse path one step.
10909 for (var k2 = -d + k2start; k2 <= d - k2end; k2 += 2) {
10910 var k2_offset = v_offset + k2;
10911 var x2;
10912 if (k2 == -d || (k2 != d && v2[k2_offset - 1] < v2[k2_offset + 1])) {
10913 x2 = v2[k2_offset + 1];
10914 } else {
10915 x2 = v2[k2_offset - 1] + 1;
10916 }
10917 var y2 = x2 - k2;
10918 while (x2 < text1_length && y2 < text2_length &&
10919 text1.charAt(text1_length - x2 - 1) ==
10920 text2.charAt(text2_length - y2 - 1)) {
10921 x2++;
10922 y2++;
10923 }
10924 v2[k2_offset] = x2;
10925 if (x2 > text1_length) {
10926 // Ran off the left of the graph.
10927 k2end += 2;
10928 } else if (y2 > text2_length) {
10929 // Ran off the top of the graph.
10930 k2start += 2;
10931 } else if (!front) {
10932 var k1_offset = v_offset + delta - k2;
10933 if (k1_offset >= 0 && k1_offset < v_length && v1[k1_offset] != -1) {
10934 var x1 = v1[k1_offset];
10935 var y1 = v_offset + x1 - k1_offset;
10936 // Mirror x2 onto top-left coordinate system.
10937 x2 = text1_length - x2;
10938 if (x1 >= x2) {
10939 // Overlap detected.
10940 return this.diff_bisectSplit_(text1, text2, x1, y1, deadline);
10941 }
10942 }
10943 }
10944 }
10945 }
10946 // Diff took too long and hit the deadline or
10947 // number of diffs equals number of characters, no commonality at all.
10948 return [[DIFF_DELETE, text1], [DIFF_INSERT, text2]];
10949};
10950
10951
10952/**
10953 * Given the location of the 'middle snake', split the diff in two parts
10954 * and recurse.
10955 * @param {string} text1 Old string to be diffed.
10956 * @param {string} text2 New string to be diffed.
10957 * @param {number} x Index of split point in text1.
10958 * @param {number} y Index of split point in text2.
10959 * @param {number} deadline Time at which to bail if not yet complete.
10960 * @return {!Array.<!diff_match_patch.Diff>} Array of diff tuples.
10961 * @private
10962 */
10963diff_match_patch.prototype.diff_bisectSplit_ = function(text1, text2, x, y,
10964 deadline) {
10965 var text1a = text1.substring(0, x);
10966 var text2a = text2.substring(0, y);
10967 var text1b = text1.substring(x);
10968 var text2b = text2.substring(y);
10969
10970 // Compute both diffs serially.
10971 var diffs = this.diff_main(text1a, text2a, false, deadline);
10972 var diffsb = this.diff_main(text1b, text2b, false, deadline);
10973
10974 return diffs.concat(diffsb);
10975};
10976
10977
10978/**
10979 * Split two texts into an array of strings. Reduce the texts to a string of
10980 * hashes where each Unicode character represents one line.
10981 * @param {string} text1 First string.
10982 * @param {string} text2 Second string.
10983 * @return {{chars1: string, chars2: string, lineArray: !Array.<string>}}
10984 * An object containing the encoded text1, the encoded text2 and
10985 * the array of unique strings.
10986 * The zeroth element of the array of unique strings is intentionally blank.
10987 * @private
10988 */
10989diff_match_patch.prototype.diff_linesToChars_ = function(text1, text2) {
10990 var lineArray = []; // e.g. lineArray[4] == 'Hello\n'
10991 var lineHash = {}; // e.g. lineHash['Hello\n'] == 4
10992
10993 // '\x00' is a valid character, but various debuggers don't like it.
10994 // So we'll insert a junk entry to avoid generating a null character.
10995 lineArray[0] = '';
10996
10997 /**
10998 * Split a text into an array of strings. Reduce the texts to a string of
10999 * hashes where each Unicode character represents one line.
11000 * Modifies linearray and linehash through being a closure.
11001 * @param {string} text String to encode.
11002 * @return {string} Encoded string.
11003 * @private
11004 */
11005 function diff_linesToCharsMunge_(text) {
11006 var chars = '';
11007 // Walk the text, pulling out a substring for each line.
11008 // text.split('\n') would would temporarily double our memory footprint.
11009 // Modifying text would create many large strings to garbage collect.
11010 var lineStart = 0;
11011 var lineEnd = -1;
11012 // Keeping our own length variable is faster than looking it up.
11013 var lineArrayLength = lineArray.length;
11014 while (lineEnd < text.length - 1) {
11015 lineEnd = text.indexOf('\n', lineStart);
11016 if (lineEnd == -1) {
11017 lineEnd = text.length - 1;
11018 }
11019 var line = text.substring(lineStart, lineEnd + 1);
11020 lineStart = lineEnd + 1;
11021
11022 if (lineHash.hasOwnProperty ? lineHash.hasOwnProperty(line) :
11023 (lineHash[line] !== undefined)) {
11024 chars += String.fromCharCode(lineHash[line]);
11025 } else {
11026 chars += String.fromCharCode(lineArrayLength);
11027 lineHash[line] = lineArrayLength;
11028 lineArray[lineArrayLength++] = line;
11029 }
11030 }
11031 return chars;
11032 }
11033
11034 var chars1 = diff_linesToCharsMunge_(text1);
11035 var chars2 = diff_linesToCharsMunge_(text2);
11036 return {chars1: chars1, chars2: chars2, lineArray: lineArray};
11037};
11038
11039
11040/**
11041 * Rehydrate the text in a diff from a string of line hashes to real lines of
11042 * text.
11043 * @param {!Array.<!diff_match_patch.Diff>} diffs Array of diff tuples.
11044 * @param {!Array.<string>} lineArray Array of unique strings.
11045 * @private
11046 */
11047diff_match_patch.prototype.diff_charsToLines_ = function(diffs, lineArray) {
11048 for (var x = 0; x < diffs.length; x++) {
11049 var chars = diffs[x][1];
11050 var text = [];
11051 for (var y = 0; y < chars.length; y++) {
11052 text[y] = lineArray[chars.charCodeAt(y)];
11053 }
11054 diffs[x][1] = text.join('');
11055 }
11056};
11057
11058
11059/**
11060 * Determine the common prefix of two strings.
11061 * @param {string} text1 First string.
11062 * @param {string} text2 Second string.
11063 * @return {number} The number of characters common to the start of each
11064 * string.
11065 */
11066diff_match_patch.prototype.diff_commonPrefix = function(text1, text2) {
11067 // Quick check for common null cases.
11068 if (!text1 || !text2 || text1.charAt(0) != text2.charAt(0)) {
11069 return 0;
11070 }
11071 // Binary search.
11072 // Performance analysis: http://neil.fraser.name/news/2007/10/09/
11073 var pointermin = 0;
11074 var pointermax = Math.min(text1.length, text2.length);
11075 var pointermid = pointermax;
11076 var pointerstart = 0;
11077 while (pointermin < pointermid) {
11078 if (text1.substring(pointerstart, pointermid) ==
11079 text2.substring(pointerstart, pointermid)) {
11080 pointermin = pointermid;
11081 pointerstart = pointermin;
11082 } else {
11083 pointermax = pointermid;
11084 }
11085 pointermid = Math.floor((pointermax - pointermin) / 2 + pointermin);
11086 }
11087 return pointermid;
11088};
11089
11090
11091/**
11092 * Determine the common suffix of two strings.
11093 * @param {string} text1 First string.
11094 * @param {string} text2 Second string.
11095 * @return {number} The number of characters common to the end of each string.
11096 */
11097diff_match_patch.prototype.diff_commonSuffix = function(text1, text2) {
11098 // Quick check for common null cases.
11099 if (!text1 || !text2 ||
11100 text1.charAt(text1.length - 1) != text2.charAt(text2.length - 1)) {
11101 return 0;
11102 }
11103 // Binary search.
11104 // Performance analysis: http://neil.fraser.name/news/2007/10/09/
11105 var pointermin = 0;
11106 var pointermax = Math.min(text1.length, text2.length);
11107 var pointermid = pointermax;
11108 var pointerend = 0;
11109 while (pointermin < pointermid) {
11110 if (text1.substring(text1.length - pointermid, text1.length - pointerend) ==
11111 text2.substring(text2.length - pointermid, text2.length - pointerend)) {
11112 pointermin = pointermid;
11113 pointerend = pointermin;
11114 } else {
11115 pointermax = pointermid;
11116 }
11117 pointermid = Math.floor((pointermax - pointermin) / 2 + pointermin);
11118 }
11119 return pointermid;
11120};
11121
11122
11123/**
11124 * Determine if the suffix of one string is the prefix of another.
11125 * @param {string} text1 First string.
11126 * @param {string} text2 Second string.
11127 * @return {number} The number of characters common to the end of the first
11128 * string and the start of the second string.
11129 * @private
11130 */
11131diff_match_patch.prototype.diff_commonOverlap_ = function(text1, text2) {
11132 // Cache the text lengths to prevent multiple calls.
11133 var text1_length = text1.length;
11134 var text2_length = text2.length;
11135 // Eliminate the null case.
11136 if (text1_length == 0 || text2_length == 0) {
11137 return 0;
11138 }
11139 // Truncate the longer string.
11140 if (text1_length > text2_length) {
11141 text1 = text1.substring(text1_length - text2_length);
11142 } else if (text1_length < text2_length) {
11143 text2 = text2.substring(0, text1_length);
11144 }
11145 var text_length = Math.min(text1_length, text2_length);
11146 // Quick check for the worst case.
11147 if (text1 == text2) {
11148 return text_length;
11149 }
11150
11151 // Start by looking for a single character match
11152 // and increase length until no match is found.
11153 // Performance analysis: http://neil.fraser.name/news/2010/11/04/
11154 var best = 0;
11155 var length = 1;
11156 while (true) {
11157 var pattern = text1.substring(text_length - length);
11158 var found = text2.indexOf(pattern);
11159 if (found == -1) {
11160 return best;
11161 }
11162 length += found;
11163 if (found == 0 || text1.substring(text_length - length) ==
11164 text2.substring(0, length)) {
11165 best = length;
11166 length++;
11167 }
11168 }
11169};
11170
11171
11172/**
11173 * Do the two texts share a substring which is at least half the length of the
11174 * longer text?
11175 * This speedup can produce non-minimal diffs.
11176 * @param {string} text1 First string.
11177 * @param {string} text2 Second string.
11178 * @return {Array.<string>} Five element Array, containing the prefix of
11179 * text1, the suffix of text1, the prefix of text2, the suffix of
11180 * text2 and the common middle. Or null if there was no match.
11181 * @private
11182 */
11183diff_match_patch.prototype.diff_halfMatch_ = function(text1, text2) {
11184 if (this.Diff_Timeout <= 0) {
11185 // Don't risk returning a non-optimal diff if we have unlimited time.
11186 return null;
11187 }
11188 var longtext = text1.length > text2.length ? text1 : text2;
11189 var shorttext = text1.length > text2.length ? text2 : text1;
11190 if (longtext.length < 4 || shorttext.length * 2 < longtext.length) {
11191 return null; // Pointless.
11192 }
11193 var dmp = this; // 'this' becomes 'window' in a closure.
11194
11195 /**
11196 * Does a substring of shorttext exist within longtext such that the substring
11197 * is at least half the length of longtext?
11198 * Closure, but does not reference any external variables.
11199 * @param {string} longtext Longer string.
11200 * @param {string} shorttext Shorter string.
11201 * @param {number} i Start index of quarter length substring within longtext.
11202 * @return {Array.<string>} Five element Array, containing the prefix of
11203 * longtext, the suffix of longtext, the prefix of shorttext, the suffix
11204 * of shorttext and the common middle. Or null if there was no match.
11205 * @private
11206 */
11207 function diff_halfMatchI_(longtext, shorttext, i) {
11208 // Start with a 1/4 length substring at position i as a seed.
11209 var seed = longtext.substring(i, i + Math.floor(longtext.length / 4));
11210 var j = -1;
11211 var best_common = '';
11212 var best_longtext_a, best_longtext_b, best_shorttext_a, best_shorttext_b;
11213 while ((j = shorttext.indexOf(seed, j + 1)) != -1) {
11214 var prefixLength = dmp.diff_commonPrefix(longtext.substring(i),
11215 shorttext.substring(j));
11216 var suffixLength = dmp.diff_commonSuffix(longtext.substring(0, i),
11217 shorttext.substring(0, j));
11218 if (best_common.length < suffixLength + prefixLength) {
11219 best_common = shorttext.substring(j - suffixLength, j) +
11220 shorttext.substring(j, j + prefixLength);
11221 best_longtext_a = longtext.substring(0, i - suffixLength);
11222 best_longtext_b = longtext.substring(i + prefixLength);
11223 best_shorttext_a = shorttext.substring(0, j - suffixLength);
11224 best_shorttext_b = shorttext.substring(j + prefixLength);
11225 }
11226 }
11227 if (best_common.length * 2 >= longtext.length) {
11228 return [best_longtext_a, best_longtext_b,
11229 best_shorttext_a, best_shorttext_b, best_common];
11230 } else {
11231 return null;
11232 }
11233 }
11234
11235 // First check if the second quarter is the seed for a half-match.
11236 var hm1 = diff_halfMatchI_(longtext, shorttext,
11237 Math.ceil(longtext.length / 4));
11238 // Check again based on the third quarter.
11239 var hm2 = diff_halfMatchI_(longtext, shorttext,
11240 Math.ceil(longtext.length / 2));
11241 var hm;
11242 if (!hm1 && !hm2) {
11243 return null;
11244 } else if (!hm2) {
11245 hm = hm1;
11246 } else if (!hm1) {
11247 hm = hm2;
11248 } else {
11249 // Both matched. Select the longest.
11250 hm = hm1[4].length > hm2[4].length ? hm1 : hm2;
11251 }
11252
11253 // A half-match was found, sort out the return data.
11254 var text1_a, text1_b, text2_a, text2_b;
11255 if (text1.length > text2.length) {
11256 text1_a = hm[0];
11257 text1_b = hm[1];
11258 text2_a = hm[2];
11259 text2_b = hm[3];
11260 } else {
11261 text2_a = hm[0];
11262 text2_b = hm[1];
11263 text1_a = hm[2];
11264 text1_b = hm[3];
11265 }
11266 var mid_common = hm[4];
11267 return [text1_a, text1_b, text2_a, text2_b, mid_common];
11268};
11269
11270
11271/**
11272 * Reduce the number of edits by eliminating semantically trivial equalities.
11273 * @param {!Array.<!diff_match_patch.Diff>} diffs Array of diff tuples.
11274 */
11275diff_match_patch.prototype.diff_cleanupSemantic = function(diffs) {
11276 var changes = false;
11277 var equalities = []; // Stack of indices where equalities are found.
11278 var equalitiesLength = 0; // Keeping our own length var is faster in JS.
11279 /** @type {?string} */
11280 var lastequality = null;
11281 // Always equal to diffs[equalities[equalitiesLength - 1]][1]
11282 var pointer = 0; // Index of current position.
11283 // Number of characters that changed prior to the equality.
11284 var length_insertions1 = 0;
11285 var length_deletions1 = 0;
11286 // Number of characters that changed after the equality.
11287 var length_insertions2 = 0;
11288 var length_deletions2 = 0;
11289 while (pointer < diffs.length) {
11290 if (diffs[pointer][0] == DIFF_EQUAL) { // Equality found.
11291 equalities[equalitiesLength++] = pointer;
11292 length_insertions1 = length_insertions2;
11293 length_deletions1 = length_deletions2;
11294 length_insertions2 = 0;
11295 length_deletions2 = 0;
11296 lastequality = diffs[pointer][1];
11297 } else { // An insertion or deletion.
11298 if (diffs[pointer][0] == DIFF_INSERT) {
11299 length_insertions2 += diffs[pointer][1].length;
11300 } else {
11301 length_deletions2 += diffs[pointer][1].length;
11302 }
11303 // Eliminate an equality that is smaller or equal to the edits on both
11304 // sides of it.
11305 if (lastequality && (lastequality.length <=
11306 Math.max(length_insertions1, length_deletions1)) &&
11307 (lastequality.length <= Math.max(length_insertions2,
11308 length_deletions2))) {
11309 // Duplicate record.
11310 diffs.splice(equalities[equalitiesLength - 1], 0,
11311 [DIFF_DELETE, lastequality]);
11312 // Change second copy to insert.
11313 diffs[equalities[equalitiesLength - 1] + 1][0] = DIFF_INSERT;
11314 // Throw away the equality we just deleted.
11315 equalitiesLength--;
11316 // Throw away the previous equality (it needs to be reevaluated).
11317 equalitiesLength--;
11318 pointer = equalitiesLength > 0 ? equalities[equalitiesLength - 1] : -1;
11319 length_insertions1 = 0; // Reset the counters.
11320 length_deletions1 = 0;
11321 length_insertions2 = 0;
11322 length_deletions2 = 0;
11323 lastequality = null;
11324 changes = true;
11325 }
11326 }
11327 pointer++;
11328 }
11329
11330 // Normalize the diff.
11331 if (changes) {
11332 this.diff_cleanupMerge(diffs);
11333 }
11334 this.diff_cleanupSemanticLossless(diffs);
11335
11336 // Find any overlaps between deletions and insertions.
11337 // e.g: <del>abcxxx</del><ins>xxxdef</ins>
11338 // -> <del>abc</del>xxx<ins>def</ins>
11339 // e.g: <del>xxxabc</del><ins>defxxx</ins>
11340 // -> <ins>def</ins>xxx<del>abc</del>
11341 // Only extract an overlap if it is as big as the edit ahead or behind it.
11342 pointer = 1;
11343 while (pointer < diffs.length) {
11344 if (diffs[pointer - 1][0] == DIFF_DELETE &&
11345 diffs[pointer][0] == DIFF_INSERT) {
11346 var deletion = diffs[pointer - 1][1];
11347 var insertion = diffs[pointer][1];
11348 var overlap_length1 = this.diff_commonOverlap_(deletion, insertion);
11349 var overlap_length2 = this.diff_commonOverlap_(insertion, deletion);
11350 if (overlap_length1 >= overlap_length2) {
11351 if (overlap_length1 >= deletion.length / 2 ||
11352 overlap_length1 >= insertion.length / 2) {
11353 // Overlap found. Insert an equality and trim the surrounding edits.
11354 diffs.splice(pointer, 0,
11355 [DIFF_EQUAL, insertion.substring(0, overlap_length1)]);
11356 diffs[pointer - 1][1] =
11357 deletion.substring(0, deletion.length - overlap_length1);
11358 diffs[pointer + 1][1] = insertion.substring(overlap_length1);
11359 pointer++;
11360 }
11361 } else {
11362 if (overlap_length2 >= deletion.length / 2 ||
11363 overlap_length2 >= insertion.length / 2) {
11364 // Reverse overlap found.
11365 // Insert an equality and swap and trim the surrounding edits.
11366 diffs.splice(pointer, 0,
11367 [DIFF_EQUAL, deletion.substring(0, overlap_length2)]);
11368 diffs[pointer - 1][0] = DIFF_INSERT;
11369 diffs[pointer - 1][1] =
11370 insertion.substring(0, insertion.length - overlap_length2);
11371 diffs[pointer + 1][0] = DIFF_DELETE;
11372 diffs[pointer + 1][1] =
11373 deletion.substring(overlap_length2);
11374 pointer++;
11375 }
11376 }
11377 pointer++;
11378 }
11379 pointer++;
11380 }
11381};
11382
11383
11384/**
11385 * Look for single edits surrounded on both sides by equalities
11386 * which can be shifted sideways to align the edit to a word boundary.
11387 * e.g: The c<ins>at c</ins>ame. -> The <ins>cat </ins>came.
11388 * @param {!Array.<!diff_match_patch.Diff>} diffs Array of diff tuples.
11389 */
11390diff_match_patch.prototype.diff_cleanupSemanticLossless = function(diffs) {
11391 /**
11392 * Given two strings, compute a score representing whether the internal
11393 * boundary falls on logical boundaries.
11394 * Scores range from 6 (best) to 0 (worst).
11395 * Closure, but does not reference any external variables.
11396 * @param {string} one First string.
11397 * @param {string} two Second string.
11398 * @return {number} The score.
11399 * @private
11400 */
11401 function diff_cleanupSemanticScore_(one, two) {
11402 if (!one || !two) {
11403 // Edges are the best.
11404 return 6;
11405 }
11406
11407 // Each port of this function behaves slightly differently due to
11408 // subtle differences in each language's definition of things like
11409 // 'whitespace'. Since this function's purpose is largely cosmetic,
11410 // the choice has been made to use each language's native features
11411 // rather than force total conformity.
11412 var char1 = one.charAt(one.length - 1);
11413 var char2 = two.charAt(0);
11414 var nonAlphaNumeric1 = char1.match(diff_match_patch.nonAlphaNumericRegex_);
11415 var nonAlphaNumeric2 = char2.match(diff_match_patch.nonAlphaNumericRegex_);
11416 var whitespace1 = nonAlphaNumeric1 &&
11417 char1.match(diff_match_patch.whitespaceRegex_);
11418 var whitespace2 = nonAlphaNumeric2 &&
11419 char2.match(diff_match_patch.whitespaceRegex_);
11420 var lineBreak1 = whitespace1 &&
11421 char1.match(diff_match_patch.linebreakRegex_);
11422 var lineBreak2 = whitespace2 &&
11423 char2.match(diff_match_patch.linebreakRegex_);
11424 var blankLine1 = lineBreak1 &&
11425 one.match(diff_match_patch.blanklineEndRegex_);
11426 var blankLine2 = lineBreak2 &&
11427 two.match(diff_match_patch.blanklineStartRegex_);
11428
11429 if (blankLine1 || blankLine2) {
11430 // Five points for blank lines.
11431 return 5;
11432 } else if (lineBreak1 || lineBreak2) {
11433 // Four points for line breaks.
11434 return 4;
11435 } else if (nonAlphaNumeric1 && !whitespace1 && whitespace2) {
11436 // Three points for end of sentences.
11437 return 3;
11438 } else if (whitespace1 || whitespace2) {
11439 // Two points for whitespace.
11440 return 2;
11441 } else if (nonAlphaNumeric1 || nonAlphaNumeric2) {
11442 // One point for non-alphanumeric.
11443 return 1;
11444 }
11445 return 0;
11446 }
11447
11448 var pointer = 1;
11449 // Intentionally ignore the first and last element (don't need checking).
11450 while (pointer < diffs.length - 1) {
11451 if (diffs[pointer - 1][0] == DIFF_EQUAL &&
11452 diffs[pointer + 1][0] == DIFF_EQUAL) {
11453 // This is a single edit surrounded by equalities.
11454 var equality1 = diffs[pointer - 1][1];
11455 var edit = diffs[pointer][1];
11456 var equality2 = diffs[pointer + 1][1];
11457
11458 // First, shift the edit as far left as possible.
11459 var commonOffset = this.diff_commonSuffix(equality1, edit);
11460 if (commonOffset) {
11461 var commonString = edit.substring(edit.length - commonOffset);
11462 equality1 = equality1.substring(0, equality1.length - commonOffset);
11463 edit = commonString + edit.substring(0, edit.length - commonOffset);
11464 equality2 = commonString + equality2;
11465 }
11466
11467 // Second, step character by character right, looking for the best fit.
11468 var bestEquality1 = equality1;
11469 var bestEdit = edit;
11470 var bestEquality2 = equality2;
11471 var bestScore = diff_cleanupSemanticScore_(equality1, edit) +
11472 diff_cleanupSemanticScore_(edit, equality2);
11473 while (edit.charAt(0) === equality2.charAt(0)) {
11474 equality1 += edit.charAt(0);
11475 edit = edit.substring(1) + equality2.charAt(0);
11476 equality2 = equality2.substring(1);
11477 var score = diff_cleanupSemanticScore_(equality1, edit) +
11478 diff_cleanupSemanticScore_(edit, equality2);
11479 // The >= encourages trailing rather than leading whitespace on edits.
11480 if (score >= bestScore) {
11481 bestScore = score;
11482 bestEquality1 = equality1;
11483 bestEdit = edit;
11484 bestEquality2 = equality2;
11485 }
11486 }
11487
11488 if (diffs[pointer - 1][1] != bestEquality1) {
11489 // We have an improvement, save it back to the diff.
11490 if (bestEquality1) {
11491 diffs[pointer - 1][1] = bestEquality1;
11492 } else {
11493 diffs.splice(pointer - 1, 1);
11494 pointer--;
11495 }
11496 diffs[pointer][1] = bestEdit;
11497 if (bestEquality2) {
11498 diffs[pointer + 1][1] = bestEquality2;
11499 } else {
11500 diffs.splice(pointer + 1, 1);
11501 pointer--;
11502 }
11503 }
11504 }
11505 pointer++;
11506 }
11507};
11508
11509// Define some regex patterns for matching boundaries.
11510diff_match_patch.nonAlphaNumericRegex_ = /[^a-zA-Z0-9]/;
11511diff_match_patch.whitespaceRegex_ = /\s/;
11512diff_match_patch.linebreakRegex_ = /[\r\n]/;
11513diff_match_patch.blanklineEndRegex_ = /\n\r?\n$/;
11514diff_match_patch.blanklineStartRegex_ = /^\r?\n\r?\n/;
11515
11516/**
11517 * Reduce the number of edits by eliminating operationally trivial equalities.
11518 * @param {!Array.<!diff_match_patch.Diff>} diffs Array of diff tuples.
11519 */
11520diff_match_patch.prototype.diff_cleanupEfficiency = function(diffs) {
11521 var changes = false;
11522 var equalities = []; // Stack of indices where equalities are found.
11523 var equalitiesLength = 0; // Keeping our own length var is faster in JS.
11524 /** @type {?string} */
11525 var lastequality = null;
11526 // Always equal to diffs[equalities[equalitiesLength - 1]][1]
11527 var pointer = 0; // Index of current position.
11528 // Is there an insertion operation before the last equality.
11529 var pre_ins = false;
11530 // Is there a deletion operation before the last equality.
11531 var pre_del = false;
11532 // Is there an insertion operation after the last equality.
11533 var post_ins = false;
11534 // Is there a deletion operation after the last equality.
11535 var post_del = false;
11536 while (pointer < diffs.length) {
11537 if (diffs[pointer][0] == DIFF_EQUAL) { // Equality found.
11538 if (diffs[pointer][1].length < this.Diff_EditCost &&
11539 (post_ins || post_del)) {
11540 // Candidate found.
11541 equalities[equalitiesLength++] = pointer;
11542 pre_ins = post_ins;
11543 pre_del = post_del;
11544 lastequality = diffs[pointer][1];
11545 } else {
11546 // Not a candidate, and can never become one.
11547 equalitiesLength = 0;
11548 lastequality = null;
11549 }
11550 post_ins = post_del = false;
11551 } else { // An insertion or deletion.
11552 if (diffs[pointer][0] == DIFF_DELETE) {
11553 post_del = true;
11554 } else {
11555 post_ins = true;
11556 }
11557 /*
11558 * Five types to be split:
11559 * <ins>A</ins><del>B</del>XY<ins>C</ins><del>D</del>
11560 * <ins>A</ins>X<ins>C</ins><del>D</del>
11561 * <ins>A</ins><del>B</del>X<ins>C</ins>
11562 * <ins>A</del>X<ins>C</ins><del>D</del>
11563 * <ins>A</ins><del>B</del>X<del>C</del>
11564 */
11565 if (lastequality && ((pre_ins && pre_del && post_ins && post_del) ||
11566 ((lastequality.length < this.Diff_EditCost / 2) &&
11567 (pre_ins + pre_del + post_ins + post_del) == 3))) {
11568 // Duplicate record.
11569 diffs.splice(equalities[equalitiesLength - 1], 0,
11570 [DIFF_DELETE, lastequality]);
11571 // Change second copy to insert.
11572 diffs[equalities[equalitiesLength - 1] + 1][0] = DIFF_INSERT;
11573 equalitiesLength--; // Throw away the equality we just deleted;
11574 lastequality = null;
11575 if (pre_ins && pre_del) {
11576 // No changes made which could affect previous entry, keep going.
11577 post_ins = post_del = true;
11578 equalitiesLength = 0;
11579 } else {
11580 equalitiesLength--; // Throw away the previous equality.
11581 pointer = equalitiesLength > 0 ?
11582 equalities[equalitiesLength - 1] : -1;
11583 post_ins = post_del = false;
11584 }
11585 changes = true;
11586 }
11587 }
11588 pointer++;
11589 }
11590
11591 if (changes) {
11592 this.diff_cleanupMerge(diffs);
11593 }
11594};
11595
11596
11597/**
11598 * Reorder and merge like edit sections. Merge equalities.
11599 * Any edit section can move as long as it doesn't cross an equality.
11600 * @param {!Array.<!diff_match_patch.Diff>} diffs Array of diff tuples.
11601 */
11602diff_match_patch.prototype.diff_cleanupMerge = function(diffs) {
11603 diffs.push([DIFF_EQUAL, '']); // Add a dummy entry at the end.
11604 var pointer = 0;
11605 var count_delete = 0;
11606 var count_insert = 0;
11607 var text_delete = '';
11608 var text_insert = '';
11609 var commonlength;
11610 while (pointer < diffs.length) {
11611 switch (diffs[pointer][0]) {
11612 case DIFF_INSERT:
11613 count_insert++;
11614 text_insert += diffs[pointer][1];
11615 pointer++;
11616 break;
11617 case DIFF_DELETE:
11618 count_delete++;
11619 text_delete += diffs[pointer][1];
11620 pointer++;
11621 break;
11622 case DIFF_EQUAL:
11623 // Upon reaching an equality, check for prior redundancies.
11624 if (count_delete + count_insert > 1) {
11625 if (count_delete !== 0 && count_insert !== 0) {
11626 // Factor out any common prefixies.
11627 commonlength = this.diff_commonPrefix(text_insert, text_delete);
11628 if (commonlength !== 0) {
11629 if ((pointer - count_delete - count_insert) > 0 &&
11630 diffs[pointer - count_delete - count_insert - 1][0] ==
11631 DIFF_EQUAL) {
11632 diffs[pointer - count_delete - count_insert - 1][1] +=
11633 text_insert.substring(0, commonlength);
11634 } else {
11635 diffs.splice(0, 0, [DIFF_EQUAL,
11636 text_insert.substring(0, commonlength)]);
11637 pointer++;
11638 }
11639 text_insert = text_insert.substring(commonlength);
11640 text_delete = text_delete.substring(commonlength);
11641 }
11642 // Factor out any common suffixies.
11643 commonlength = this.diff_commonSuffix(text_insert, text_delete);
11644 if (commonlength !== 0) {
11645 diffs[pointer][1] = text_insert.substring(text_insert.length -
11646 commonlength) + diffs[pointer][1];
11647 text_insert = text_insert.substring(0, text_insert.length -
11648 commonlength);
11649 text_delete = text_delete.substring(0, text_delete.length -
11650 commonlength);
11651 }
11652 }
11653 // Delete the offending records and add the merged ones.
11654 if (count_delete === 0) {
11655 diffs.splice(pointer - count_insert,
11656 count_delete + count_insert, [DIFF_INSERT, text_insert]);
11657 } else if (count_insert === 0) {
11658 diffs.splice(pointer - count_delete,
11659 count_delete + count_insert, [DIFF_DELETE, text_delete]);
11660 } else {
11661 diffs.splice(pointer - count_delete - count_insert,
11662 count_delete + count_insert, [DIFF_DELETE, text_delete],
11663 [DIFF_INSERT, text_insert]);
11664 }
11665 pointer = pointer - count_delete - count_insert +
11666 (count_delete ? 1 : 0) + (count_insert ? 1 : 0) + 1;
11667 } else if (pointer !== 0 && diffs[pointer - 1][0] == DIFF_EQUAL) {
11668 // Merge this equality with the previous one.
11669 diffs[pointer - 1][1] += diffs[pointer][1];
11670 diffs.splice(pointer, 1);
11671 } else {
11672 pointer++;
11673 }
11674 count_insert = 0;
11675 count_delete = 0;
11676 text_delete = '';
11677 text_insert = '';
11678 break;
11679 }
11680 }
11681 if (diffs[diffs.length - 1][1] === '') {
11682 diffs.pop(); // Remove the dummy entry at the end.
11683 }
11684
11685 // Second pass: look for single edits surrounded on both sides by equalities
11686 // which can be shifted sideways to eliminate an equality.
11687 // e.g: A<ins>BA</ins>C -> <ins>AB</ins>AC
11688 var changes = false;
11689 pointer = 1;
11690 // Intentionally ignore the first and last element (don't need checking).
11691 while (pointer < diffs.length - 1) {
11692 if (diffs[pointer - 1][0] == DIFF_EQUAL &&
11693 diffs[pointer + 1][0] == DIFF_EQUAL) {
11694 // This is a single edit surrounded by equalities.
11695 if (diffs[pointer][1].substring(diffs[pointer][1].length -
11696 diffs[pointer - 1][1].length) == diffs[pointer - 1][1]) {
11697 // Shift the edit over the previous equality.
11698 diffs[pointer][1] = diffs[pointer - 1][1] +
11699 diffs[pointer][1].substring(0, diffs[pointer][1].length -
11700 diffs[pointer - 1][1].length);
11701 diffs[pointer + 1][1] = diffs[pointer - 1][1] + diffs[pointer + 1][1];
11702 diffs.splice(pointer - 1, 1);
11703 changes = true;
11704 } else if (diffs[pointer][1].substring(0, diffs[pointer + 1][1].length) ==
11705 diffs[pointer + 1][1]) {
11706 // Shift the edit over the next equality.
11707 diffs[pointer - 1][1] += diffs[pointer + 1][1];
11708 diffs[pointer][1] =
11709 diffs[pointer][1].substring(diffs[pointer + 1][1].length) +
11710 diffs[pointer + 1][1];
11711 diffs.splice(pointer + 1, 1);
11712 changes = true;
11713 }
11714 }
11715 pointer++;
11716 }
11717 // If shifts were made, the diff needs reordering and another shift sweep.
11718 if (changes) {
11719 this.diff_cleanupMerge(diffs);
11720 }
11721};
11722
11723
11724/**
11725 * loc is a location in text1, compute and return the equivalent location in
11726 * text2.
11727 * e.g. 'The cat' vs 'The big cat', 1->1, 5->8
11728 * @param {!Array.<!diff_match_patch.Diff>} diffs Array of diff tuples.
11729 * @param {number} loc Location within text1.
11730 * @return {number} Location within text2.
11731 */
11732diff_match_patch.prototype.diff_xIndex = function(diffs, loc) {
11733 var chars1 = 0;
11734 var chars2 = 0;
11735 var last_chars1 = 0;
11736 var last_chars2 = 0;
11737 var x;
11738 for (x = 0; x < diffs.length; x++) {
11739 if (diffs[x][0] !== DIFF_INSERT) { // Equality or deletion.
11740 chars1 += diffs[x][1].length;
11741 }
11742 if (diffs[x][0] !== DIFF_DELETE) { // Equality or insertion.
11743 chars2 += diffs[x][1].length;
11744 }
11745 if (chars1 > loc) { // Overshot the location.
11746 break;
11747 }
11748 last_chars1 = chars1;
11749 last_chars2 = chars2;
11750 }
11751 // Was the location was deleted?
11752 if (diffs.length != x && diffs[x][0] === DIFF_DELETE) {
11753 return last_chars2;
11754 }
11755 // Add the remaining character length.
11756 return last_chars2 + (loc - last_chars1);
11757};
11758
11759
11760/**
11761 * Convert a diff array into a pretty HTML report.
11762 * @param {!Array.<!diff_match_patch.Diff>} diffs Array of diff tuples.
11763 * @return {string} HTML representation.
11764 */
11765diff_match_patch.prototype.diff_prettyHtml = function(diffs) {
11766 var html = [];
11767 var pattern_amp = /&/g;
11768 var pattern_lt = /</g;
11769 var pattern_gt = />/g;
11770 var pattern_para = /\n/g;
11771 for (var x = 0; x < diffs.length; x++) {
11772 var op = diffs[x][0]; // Operation (insert, delete, equal)
11773 var data = diffs[x][1]; // Text of change.
11774 var text = data.replace(pattern_amp, '&amp;').replace(pattern_lt, '&lt;')
11775 .replace(pattern_gt, '&gt;').replace(pattern_para, '&para;<br>');
11776 switch (op) {
11777 case DIFF_INSERT:
11778 html[x] = '<ins style="background:#e6ffe6;">' + text + '</ins>';
11779 break;
11780 case DIFF_DELETE:
11781 html[x] = '<del style="background:#ffe6e6;">' + text + '</del>';
11782 break;
11783 case DIFF_EQUAL:
11784 html[x] = '<span>' + text + '</span>';
11785 break;
11786 }
11787 }
11788 return html.join('');
11789};
11790
11791
11792/**
11793 * Compute and return the source text (all equalities and deletions).
11794 * @param {!Array.<!diff_match_patch.Diff>} diffs Array of diff tuples.
11795 * @return {string} Source text.
11796 */
11797diff_match_patch.prototype.diff_text1 = function(diffs) {
11798 var text = [];
11799 for (var x = 0; x < diffs.length; x++) {
11800 if (diffs[x][0] !== DIFF_INSERT) {
11801 text[x] = diffs[x][1];
11802 }
11803 }
11804 return text.join('');
11805};
11806
11807
11808/**
11809 * Compute and return the destination text (all equalities and insertions).
11810 * @param {!Array.<!diff_match_patch.Diff>} diffs Array of diff tuples.
11811 * @return {string} Destination text.
11812 */
11813diff_match_patch.prototype.diff_text2 = function(diffs) {
11814 var text = [];
11815 for (var x = 0; x < diffs.length; x++) {
11816 if (diffs[x][0] !== DIFF_DELETE) {
11817 text[x] = diffs[x][1];
11818 }
11819 }
11820 return text.join('');
11821};
11822
11823
11824/**
11825 * Compute the Levenshtein distance; the number of inserted, deleted or
11826 * substituted characters.
11827 * @param {!Array.<!diff_match_patch.Diff>} diffs Array of diff tuples.
11828 * @return {number} Number of changes.
11829 */
11830diff_match_patch.prototype.diff_levenshtein = function(diffs) {
11831 var levenshtein = 0;
11832 var insertions = 0;
11833 var deletions = 0;
11834 for (var x = 0; x < diffs.length; x++) {
11835 var op = diffs[x][0];
11836 var data = diffs[x][1];
11837 switch (op) {
11838 case DIFF_INSERT:
11839 insertions += data.length;
11840 break;
11841 case DIFF_DELETE:
11842 deletions += data.length;
11843 break;
11844 case DIFF_EQUAL:
11845 // A deletion and an insertion is one substitution.
11846 levenshtein += Math.max(insertions, deletions);
11847 insertions = 0;
11848 deletions = 0;
11849 break;
11850 }
11851 }
11852 levenshtein += Math.max(insertions, deletions);
11853 return levenshtein;
11854};
11855
11856
11857/**
11858 * Crush the diff into an encoded string which describes the operations
11859 * required to transform text1 into text2.
11860 * E.g. =3\t-2\t+ing -> Keep 3 chars, delete 2 chars, insert 'ing'.
11861 * Operations are tab-separated. Inserted text is escaped using %xx notation.
11862 * @param {!Array.<!diff_match_patch.Diff>} diffs Array of diff tuples.
11863 * @return {string} Delta text.
11864 */
11865diff_match_patch.prototype.diff_toDelta = function(diffs) {
11866 var text = [];
11867 for (var x = 0; x < diffs.length; x++) {
11868 switch (diffs[x][0]) {
11869 case DIFF_INSERT:
11870 text[x] = '+' + encodeURI(diffs[x][1]);
11871 break;
11872 case DIFF_DELETE:
11873 text[x] = '-' + diffs[x][1].length;
11874 break;
11875 case DIFF_EQUAL:
11876 text[x] = '=' + diffs[x][1].length;
11877 break;
11878 }
11879 }
11880 return text.join('\t').replace(/%20/g, ' ');
11881};
11882
11883
11884/**
11885 * Given the original text1, and an encoded string which describes the
11886 * operations required to transform text1 into text2, compute the full diff.
11887 * @param {string} text1 Source string for the diff.
11888 * @param {string} delta Delta text.
11889 * @return {!Array.<!diff_match_patch.Diff>} Array of diff tuples.
11890 * @throws {!Error} If invalid input.
11891 */
11892diff_match_patch.prototype.diff_fromDelta = function(text1, delta) {
11893 var diffs = [];
11894 var diffsLength = 0; // Keeping our own length var is faster in JS.
11895 var pointer = 0; // Cursor in text1
11896 var tokens = delta.split(/\t/g);
11897 for (var x = 0; x < tokens.length; x++) {
11898 // Each token begins with a one character parameter which specifies the
11899 // operation of this token (delete, insert, equality).
11900 var param = tokens[x].substring(1);
11901 switch (tokens[x].charAt(0)) {
11902 case '+':
11903 try {
11904 diffs[diffsLength++] = [DIFF_INSERT, decodeURI(param)];
11905 } catch (ex) {
11906 // Malformed URI sequence.
11907 throw new Error('Illegal escape in diff_fromDelta: ' + param);
11908 }
11909 break;
11910 case '-':
11911 // Fall through.
11912 case '=':
11913 var n = parseInt(param, 10);
11914 if (isNaN(n) || n < 0) {
11915 throw new Error('Invalid number in diff_fromDelta: ' + param);
11916 }
11917 var text = text1.substring(pointer, pointer += n);
11918 if (tokens[x].charAt(0) == '=') {
11919 diffs[diffsLength++] = [DIFF_EQUAL, text];
11920 } else {
11921 diffs[diffsLength++] = [DIFF_DELETE, text];
11922 }
11923 break;
11924 default:
11925 // Blank tokens are ok (from a trailing \t).
11926 // Anything else is an error.
11927 if (tokens[x]) {
11928 throw new Error('Invalid diff operation in diff_fromDelta: ' +
11929 tokens[x]);
11930 }
11931 }
11932 }
11933 if (pointer != text1.length) {
11934 throw new Error('Delta length (' + pointer +
11935 ') does not equal source text length (' + text1.length + ').');
11936 }
11937 return diffs;
11938};
11939
11940
11941// MATCH FUNCTIONS
11942
11943
11944/**
11945 * Locate the best instance of 'pattern' in 'text' near 'loc'.
11946 * @param {string} text The text to search.
11947 * @param {string} pattern The pattern to search for.
11948 * @param {number} loc The location to search around.
11949 * @return {number} Best match index or -1.
11950 */
11951diff_match_patch.prototype.match_main = function(text, pattern, loc) {
11952 // Check for null inputs.
11953 if (text == null || pattern == null || loc == null) {
11954 throw new Error('Null input. (match_main)');
11955 }
11956
11957 loc = Math.max(0, Math.min(loc, text.length));
11958 if (text == pattern) {
11959 // Shortcut (potentially not guaranteed by the algorithm)
11960 return 0;
11961 } else if (!text.length) {
11962 // Nothing to match.
11963 return -1;
11964 } else if (text.substring(loc, loc + pattern.length) == pattern) {
11965 // Perfect match at the perfect spot! (Includes case of null pattern)
11966 return loc;
11967 } else {
11968 // Do a fuzzy compare.
11969 return this.match_bitap_(text, pattern, loc);
11970 }
11971};
11972
11973
11974/**
11975 * Locate the best instance of 'pattern' in 'text' near 'loc' using the
11976 * Bitap algorithm.
11977 * @param {string} text The text to search.
11978 * @param {string} pattern The pattern to search for.
11979 * @param {number} loc The location to search around.
11980 * @return {number} Best match index or -1.
11981 * @private
11982 */
11983diff_match_patch.prototype.match_bitap_ = function(text, pattern, loc) {
11984 if (pattern.length > this.Match_MaxBits) {
11985 throw new Error('Pattern too long for this browser.');
11986 }
11987
11988 // Initialise the alphabet.
11989 var s = this.match_alphabet_(pattern);
11990
11991 var dmp = this; // 'this' becomes 'window' in a closure.
11992
11993 /**
11994 * Compute and return the score for a match with e errors and x location.
11995 * Accesses loc and pattern through being a closure.
11996 * @param {number} e Number of errors in match.
11997 * @param {number} x Location of match.
11998 * @return {number} Overall score for match (0.0 = good, 1.0 = bad).
11999 * @private
12000 */
12001 function match_bitapScore_(e, x) {
12002 var accuracy = e / pattern.length;
12003 var proximity = Math.abs(loc - x);
12004 if (!dmp.Match_Distance) {
12005 // Dodge divide by zero error.
12006 return proximity ? 1.0 : accuracy;
12007 }
12008 return accuracy + (proximity / dmp.Match_Distance);
12009 }
12010
12011 // Highest score beyond which we give up.
12012 var score_threshold = this.Match_Threshold;
12013 // Is there a nearby exact match? (speedup)
12014 var best_loc = text.indexOf(pattern, loc);
12015 if (best_loc != -1) {
12016 score_threshold = Math.min(match_bitapScore_(0, best_loc), score_threshold);
12017 // What about in the other direction? (speedup)
12018 best_loc = text.lastIndexOf(pattern, loc + pattern.length);
12019 if (best_loc != -1) {
12020 score_threshold =
12021 Math.min(match_bitapScore_(0, best_loc), score_threshold);
12022 }
12023 }
12024
12025 // Initialise the bit arrays.
12026 var matchmask = 1 << (pattern.length - 1);
12027 best_loc = -1;
12028
12029 var bin_min, bin_mid;
12030 var bin_max = pattern.length + text.length;
12031 var last_rd;
12032 for (var d = 0; d < pattern.length; d++) {
12033 // Scan for the best match; each iteration allows for one more error.
12034 // Run a binary search to determine how far from 'loc' we can stray at this
12035 // error level.
12036 bin_min = 0;
12037 bin_mid = bin_max;
12038 while (bin_min < bin_mid) {
12039 if (match_bitapScore_(d, loc + bin_mid) <= score_threshold) {
12040 bin_min = bin_mid;
12041 } else {
12042 bin_max = bin_mid;
12043 }
12044 bin_mid = Math.floor((bin_max - bin_min) / 2 + bin_min);
12045 }
12046 // Use the result from this iteration as the maximum for the next.
12047 bin_max = bin_mid;
12048 var start = Math.max(1, loc - bin_mid + 1);
12049 var finish = Math.min(loc + bin_mid, text.length) + pattern.length;
12050
12051 var rd = Array(finish + 2);
12052 rd[finish + 1] = (1 << d) - 1;
12053 for (var j = finish; j >= start; j--) {
12054 // The alphabet (s) is a sparse hash, so the following line generates
12055 // warnings.
12056 var charMatch = s[text.charAt(j - 1)];
12057 if (d === 0) { // First pass: exact match.
12058 rd[j] = ((rd[j + 1] << 1) | 1) & charMatch;
12059 } else { // Subsequent passes: fuzzy match.
12060 rd[j] = (((rd[j + 1] << 1) | 1) & charMatch) |
12061 (((last_rd[j + 1] | last_rd[j]) << 1) | 1) |
12062 last_rd[j + 1];
12063 }
12064 if (rd[j] & matchmask) {
12065 var score = match_bitapScore_(d, j - 1);
12066 // This match will almost certainly be better than any existing match.
12067 // But check anyway.
12068 if (score <= score_threshold) {
12069 // Told you so.
12070 score_threshold = score;
12071 best_loc = j - 1;
12072 if (best_loc > loc) {
12073 // When passing loc, don't exceed our current distance from loc.
12074 start = Math.max(1, 2 * loc - best_loc);
12075 } else {
12076 // Already passed loc, downhill from here on in.
12077 break;
12078 }
12079 }
12080 }
12081 }
12082 // No hope for a (better) match at greater error levels.
12083 if (match_bitapScore_(d + 1, loc) > score_threshold) {
12084 break;
12085 }
12086 last_rd = rd;
12087 }
12088 return best_loc;
12089};
12090
12091
12092/**
12093 * Initialise the alphabet for the Bitap algorithm.
12094 * @param {string} pattern The text to encode.
12095 * @return {!Object} Hash of character locations.
12096 * @private
12097 */
12098diff_match_patch.prototype.match_alphabet_ = function(pattern) {
12099 var s = {};
12100 for (var i = 0; i < pattern.length; i++) {
12101 s[pattern.charAt(i)] = 0;
12102 }
12103 for (var i = 0; i < pattern.length; i++) {
12104 s[pattern.charAt(i)] |= 1 << (pattern.length - i - 1);
12105 }
12106 return s;
12107};
12108
12109
12110// PATCH FUNCTIONS
12111
12112
12113/**
12114 * Increase the context until it is unique,
12115 * but don't let the pattern expand beyond Match_MaxBits.
12116 * @param {!diff_match_patch.patch_obj} patch The patch to grow.
12117 * @param {string} text Source text.
12118 * @private
12119 */
12120diff_match_patch.prototype.patch_addContext_ = function(patch, text) {
12121 if (text.length == 0) {
12122 return;
12123 }
12124 var pattern = text.substring(patch.start2, patch.start2 + patch.length1);
12125 var padding = 0;
12126
12127 // Look for the first and last matches of pattern in text. If two different
12128 // matches are found, increase the pattern length.
12129 while (text.indexOf(pattern) != text.lastIndexOf(pattern) &&
12130 pattern.length < this.Match_MaxBits - this.Patch_Margin -
12131 this.Patch_Margin) {
12132 padding += this.Patch_Margin;
12133 pattern = text.substring(patch.start2 - padding,
12134 patch.start2 + patch.length1 + padding);
12135 }
12136 // Add one chunk for good luck.
12137 padding += this.Patch_Margin;
12138
12139 // Add the prefix.
12140 var prefix = text.substring(patch.start2 - padding, patch.start2);
12141 if (prefix) {
12142 patch.diffs.unshift([DIFF_EQUAL, prefix]);
12143 }
12144 // Add the suffix.
12145 var suffix = text.substring(patch.start2 + patch.length1,
12146 patch.start2 + patch.length1 + padding);
12147 if (suffix) {
12148 patch.diffs.push([DIFF_EQUAL, suffix]);
12149 }
12150
12151 // Roll back the start points.
12152 patch.start1 -= prefix.length;
12153 patch.start2 -= prefix.length;
12154 // Extend the lengths.
12155 patch.length1 += prefix.length + suffix.length;
12156 patch.length2 += prefix.length + suffix.length;
12157};
12158
12159
12160/**
12161 * Compute a list of patches to turn text1 into text2.
12162 * Use diffs if provided, otherwise compute it ourselves.
12163 * There are four ways to call this function, depending on what data is
12164 * available to the caller:
12165 * Method 1:
12166 * a = text1, b = text2
12167 * Method 2:
12168 * a = diffs
12169 * Method 3 (optimal):
12170 * a = text1, b = diffs
12171 * Method 4 (deprecated, use method 3):
12172 * a = text1, b = text2, c = diffs
12173 *
12174 * @param {string|!Array.<!diff_match_patch.Diff>} a text1 (methods 1,3,4) or
12175 * Array of diff tuples for text1 to text2 (method 2).
12176 * @param {string|!Array.<!diff_match_patch.Diff>} opt_b text2 (methods 1,4) or
12177 * Array of diff tuples for text1 to text2 (method 3) or undefined (method 2).
12178 * @param {string|!Array.<!diff_match_patch.Diff>} opt_c Array of diff tuples
12179 * for text1 to text2 (method 4) or undefined (methods 1,2,3).
12180 * @return {!Array.<!diff_match_patch.patch_obj>} Array of Patch objects.
12181 */
12182diff_match_patch.prototype.patch_make = function(a, opt_b, opt_c) {
12183 var text1, diffs;
12184 if (typeof a == 'string' && typeof opt_b == 'string' &&
12185 typeof opt_c == 'undefined') {
12186 // Method 1: text1, text2
12187 // Compute diffs from text1 and text2.
12188 text1 = /** @type {string} */(a);
12189 diffs = this.diff_main(text1, /** @type {string} */(opt_b), true);
12190 if (diffs.length > 2) {
12191 this.diff_cleanupSemantic(diffs);
12192 this.diff_cleanupEfficiency(diffs);
12193 }
12194 } else if (a && typeof a == 'object' && typeof opt_b == 'undefined' &&
12195 typeof opt_c == 'undefined') {
12196 // Method 2: diffs
12197 // Compute text1 from diffs.
12198 diffs = /** @type {!Array.<!diff_match_patch.Diff>} */(a);
12199 text1 = this.diff_text1(diffs);
12200 } else if (typeof a == 'string' && opt_b && typeof opt_b == 'object' &&
12201 typeof opt_c == 'undefined') {
12202 // Method 3: text1, diffs
12203 text1 = /** @type {string} */(a);
12204 diffs = /** @type {!Array.<!diff_match_patch.Diff>} */(opt_b);
12205 } else if (typeof a == 'string' && typeof opt_b == 'string' &&
12206 opt_c && typeof opt_c == 'object') {
12207 // Method 4: text1, text2, diffs
12208 // text2 is not used.
12209 text1 = /** @type {string} */(a);
12210 diffs = /** @type {!Array.<!diff_match_patch.Diff>} */(opt_c);
12211 } else {
12212 throw new Error('Unknown call format to patch_make.');
12213 }
12214
12215 if (diffs.length === 0) {
12216 return []; // Get rid of the null case.
12217 }
12218 var patches = [];
12219 var patch = new diff_match_patch.patch_obj();
12220 var patchDiffLength = 0; // Keeping our own length var is faster in JS.
12221 var char_count1 = 0; // Number of characters into the text1 string.
12222 var char_count2 = 0; // Number of characters into the text2 string.
12223 // Start with text1 (prepatch_text) and apply the diffs until we arrive at
12224 // text2 (postpatch_text). We recreate the patches one by one to determine
12225 // context info.
12226 var prepatch_text = text1;
12227 var postpatch_text = text1;
12228 for (var x = 0; x < diffs.length; x++) {
12229 var diff_type = diffs[x][0];
12230 var diff_text = diffs[x][1];
12231
12232 if (!patchDiffLength && diff_type !== DIFF_EQUAL) {
12233 // A new patch starts here.
12234 patch.start1 = char_count1;
12235 patch.start2 = char_count2;
12236 }
12237
12238 switch (diff_type) {
12239 case DIFF_INSERT:
12240 patch.diffs[patchDiffLength++] = diffs[x];
12241 patch.length2 += diff_text.length;
12242 postpatch_text = postpatch_text.substring(0, char_count2) + diff_text +
12243 postpatch_text.substring(char_count2);
12244 break;
12245 case DIFF_DELETE:
12246 patch.length1 += diff_text.length;
12247 patch.diffs[patchDiffLength++] = diffs[x];
12248 postpatch_text = postpatch_text.substring(0, char_count2) +
12249 postpatch_text.substring(char_count2 +
12250 diff_text.length);
12251 break;
12252 case DIFF_EQUAL:
12253 if (diff_text.length <= 2 * this.Patch_Margin &&
12254 patchDiffLength && diffs.length != x + 1) {
12255 // Small equality inside a patch.
12256 patch.diffs[patchDiffLength++] = diffs[x];
12257 patch.length1 += diff_text.length;
12258 patch.length2 += diff_text.length;
12259 } else if (diff_text.length >= 2 * this.Patch_Margin) {
12260 // Time for a new patch.
12261 if (patchDiffLength) {
12262 this.patch_addContext_(patch, prepatch_text);
12263 patches.push(patch);
12264 patch = new diff_match_patch.patch_obj();
12265 patchDiffLength = 0;
12266 // Unlike Unidiff, our patch lists have a rolling context.
12267 // http://code.google.com/p/google-diff-match-patch/wiki/Unidiff
12268 // Update prepatch text & pos to reflect the application of the
12269 // just completed patch.
12270 prepatch_text = postpatch_text;
12271 char_count1 = char_count2;
12272 }
12273 }
12274 break;
12275 }
12276
12277 // Update the current character count.
12278 if (diff_type !== DIFF_INSERT) {
12279 char_count1 += diff_text.length;
12280 }
12281 if (diff_type !== DIFF_DELETE) {
12282 char_count2 += diff_text.length;
12283 }
12284 }
12285 // Pick up the leftover patch if not empty.
12286 if (patchDiffLength) {
12287 this.patch_addContext_(patch, prepatch_text);
12288 patches.push(patch);
12289 }
12290
12291 return patches;
12292};
12293
12294
12295/**
12296 * Given an array of patches, return another array that is identical.
12297 * @param {!Array.<!diff_match_patch.patch_obj>} patches Array of Patch objects.
12298 * @return {!Array.<!diff_match_patch.patch_obj>} Array of Patch objects.
12299 */
12300diff_match_patch.prototype.patch_deepCopy = function(patches) {
12301 // Making deep copies is hard in JavaScript.
12302 var patchesCopy = [];
12303 for (var x = 0; x < patches.length; x++) {
12304 var patch = patches[x];
12305 var patchCopy = new diff_match_patch.patch_obj();
12306 patchCopy.diffs = [];
12307 for (var y = 0; y < patch.diffs.length; y++) {
12308 patchCopy.diffs[y] = patch.diffs[y].slice();
12309 }
12310 patchCopy.start1 = patch.start1;
12311 patchCopy.start2 = patch.start2;
12312 patchCopy.length1 = patch.length1;
12313 patchCopy.length2 = patch.length2;
12314 patchesCopy[x] = patchCopy;
12315 }
12316 return patchesCopy;
12317};
12318
12319
12320/**
12321 * Merge a set of patches onto the text. Return a patched text, as well
12322 * as a list of true/false values indicating which patches were applied.
12323 * @param {!Array.<!diff_match_patch.patch_obj>} patches Array of Patch objects.
12324 * @param {string} text Old text.
12325 * @return {!Array.<string|!Array.<boolean>>} Two element Array, containing the
12326 * new text and an array of boolean values.
12327 */
12328diff_match_patch.prototype.patch_apply = function(patches, text) {
12329 if (patches.length == 0) {
12330 return [text, []];
12331 }
12332
12333 // Deep copy the patches so that no changes are made to originals.
12334 patches = this.patch_deepCopy(patches);
12335
12336 var nullPadding = this.patch_addPadding(patches);
12337 text = nullPadding + text + nullPadding;
12338
12339 this.patch_splitMax(patches);
12340 // delta keeps track of the offset between the expected and actual location
12341 // of the previous patch. If there are patches expected at positions 10 and
12342 // 20, but the first patch was found at 12, delta is 2 and the second patch
12343 // has an effective expected position of 22.
12344 var delta = 0;
12345 var results = [];
12346 for (var x = 0; x < patches.length; x++) {
12347 var expected_loc = patches[x].start2 + delta;
12348 var text1 = this.diff_text1(patches[x].diffs);
12349 var start_loc;
12350 var end_loc = -1;
12351 if (text1.length > this.Match_MaxBits) {
12352 // patch_splitMax will only provide an oversized pattern in the case of
12353 // a monster delete.
12354 start_loc = this.match_main(text, text1.substring(0, this.Match_MaxBits),
12355 expected_loc);
12356 if (start_loc != -1) {
12357 end_loc = this.match_main(text,
12358 text1.substring(text1.length - this.Match_MaxBits),
12359 expected_loc + text1.length - this.Match_MaxBits);
12360 if (end_loc == -1 || start_loc >= end_loc) {
12361 // Can't find valid trailing context. Drop this patch.
12362 start_loc = -1;
12363 }
12364 }
12365 } else {
12366 start_loc = this.match_main(text, text1, expected_loc);
12367 }
12368 if (start_loc == -1) {
12369 // No match found. :(
12370 results[x] = false;
12371 // Subtract the delta for this failed patch from subsequent patches.
12372 delta -= patches[x].length2 - patches[x].length1;
12373 } else {
12374 // Found a match. :)
12375 results[x] = true;
12376 delta = start_loc - expected_loc;
12377 var text2;
12378 if (end_loc == -1) {
12379 text2 = text.substring(start_loc, start_loc + text1.length);
12380 } else {
12381 text2 = text.substring(start_loc, end_loc + this.Match_MaxBits);
12382 }
12383 if (text1 == text2) {
12384 // Perfect match, just shove the replacement text in.
12385 text = text.substring(0, start_loc) +
12386 this.diff_text2(patches[x].diffs) +
12387 text.substring(start_loc + text1.length);
12388 } else {
12389 // Imperfect match. Run a diff to get a framework of equivalent
12390 // indices.
12391 var diffs = this.diff_main(text1, text2, false);
12392 if (text1.length > this.Match_MaxBits &&
12393 this.diff_levenshtein(diffs) / text1.length >
12394 this.Patch_DeleteThreshold) {
12395 // The end points match, but the content is unacceptably bad.
12396 results[x] = false;
12397 } else {
12398 this.diff_cleanupSemanticLossless(diffs);
12399 var index1 = 0;
12400 var index2;
12401 for (var y = 0; y < patches[x].diffs.length; y++) {
12402 var mod = patches[x].diffs[y];
12403 if (mod[0] !== DIFF_EQUAL) {
12404 index2 = this.diff_xIndex(diffs, index1);
12405 }
12406 if (mod[0] === DIFF_INSERT) { // Insertion
12407 text = text.substring(0, start_loc + index2) + mod[1] +
12408 text.substring(start_loc + index2);
12409 } else if (mod[0] === DIFF_DELETE) { // Deletion
12410 text = text.substring(0, start_loc + index2) +
12411 text.substring(start_loc + this.diff_xIndex(diffs,
12412 index1 + mod[1].length));
12413 }
12414 if (mod[0] !== DIFF_DELETE) {
12415 index1 += mod[1].length;
12416 }
12417 }
12418 }
12419 }
12420 }
12421 }
12422 // Strip the padding off.
12423 text = text.substring(nullPadding.length, text.length - nullPadding.length);
12424 return [text, results];
12425};
12426
12427
12428/**
12429 * Add some padding on text start and end so that edges can match something.
12430 * Intended to be called only from within patch_apply.
12431 * @param {!Array.<!diff_match_patch.patch_obj>} patches Array of Patch objects.
12432 * @return {string} The padding string added to each side.
12433 */
12434diff_match_patch.prototype.patch_addPadding = function(patches) {
12435 var paddingLength = this.Patch_Margin;
12436 var nullPadding = '';
12437 for (var x = 1; x <= paddingLength; x++) {
12438 nullPadding += String.fromCharCode(x);
12439 }
12440
12441 // Bump all the patches forward.
12442 for (var x = 0; x < patches.length; x++) {
12443 patches[x].start1 += paddingLength;
12444 patches[x].start2 += paddingLength;
12445 }
12446
12447 // Add some padding on start of first diff.
12448 var patch = patches[0];
12449 var diffs = patch.diffs;
12450 if (diffs.length == 0 || diffs[0][0] != DIFF_EQUAL) {
12451 // Add nullPadding equality.
12452 diffs.unshift([DIFF_EQUAL, nullPadding]);
12453 patch.start1 -= paddingLength; // Should be 0.
12454 patch.start2 -= paddingLength; // Should be 0.
12455 patch.length1 += paddingLength;
12456 patch.length2 += paddingLength;
12457 } else if (paddingLength > diffs[0][1].length) {
12458 // Grow first equality.
12459 var extraLength = paddingLength - diffs[0][1].length;
12460 diffs[0][1] = nullPadding.substring(diffs[0][1].length) + diffs[0][1];
12461 patch.start1 -= extraLength;
12462 patch.start2 -= extraLength;
12463 patch.length1 += extraLength;
12464 patch.length2 += extraLength;
12465 }
12466
12467 // Add some padding on end of last diff.
12468 patch = patches[patches.length - 1];
12469 diffs = patch.diffs;
12470 if (diffs.length == 0 || diffs[diffs.length - 1][0] != DIFF_EQUAL) {
12471 // Add nullPadding equality.
12472 diffs.push([DIFF_EQUAL, nullPadding]);
12473 patch.length1 += paddingLength;
12474 patch.length2 += paddingLength;
12475 } else if (paddingLength > diffs[diffs.length - 1][1].length) {
12476 // Grow last equality.
12477 var extraLength = paddingLength - diffs[diffs.length - 1][1].length;
12478 diffs[diffs.length - 1][1] += nullPadding.substring(0, extraLength);
12479 patch.length1 += extraLength;
12480 patch.length2 += extraLength;
12481 }
12482
12483 return nullPadding;
12484};
12485
12486
12487/**
12488 * Look through the patches and break up any which are longer than the maximum
12489 * limit of the match algorithm.
12490 * Intended to be called only from within patch_apply.
12491 * @param {!Array.<!diff_match_patch.patch_obj>} patches Array of Patch objects.
12492 */
12493diff_match_patch.prototype.patch_splitMax = function(patches) {
12494 var patch_size = this.Match_MaxBits;
12495 for (var x = 0; x < patches.length; x++) {
12496 if (patches[x].length1 <= patch_size) {
12497 continue;
12498 }
12499 var bigpatch = patches[x];
12500 // Remove the big old patch.
12501 patches.splice(x--, 1);
12502 var start1 = bigpatch.start1;
12503 var start2 = bigpatch.start2;
12504 var precontext = '';
12505 while (bigpatch.diffs.length !== 0) {
12506 // Create one of several smaller patches.
12507 var patch = new diff_match_patch.patch_obj();
12508 var empty = true;
12509 patch.start1 = start1 - precontext.length;
12510 patch.start2 = start2 - precontext.length;
12511 if (precontext !== '') {
12512 patch.length1 = patch.length2 = precontext.length;
12513 patch.diffs.push([DIFF_EQUAL, precontext]);
12514 }
12515 while (bigpatch.diffs.length !== 0 &&
12516 patch.length1 < patch_size - this.Patch_Margin) {
12517 var diff_type = bigpatch.diffs[0][0];
12518 var diff_text = bigpatch.diffs[0][1];
12519 if (diff_type === DIFF_INSERT) {
12520 // Insertions are harmless.
12521 patch.length2 += diff_text.length;
12522 start2 += diff_text.length;
12523 patch.diffs.push(bigpatch.diffs.shift());
12524 empty = false;
12525 } else if (diff_type === DIFF_DELETE && patch.diffs.length == 1 &&
12526 patch.diffs[0][0] == DIFF_EQUAL &&
12527 diff_text.length > 2 * patch_size) {
12528 // This is a large deletion. Let it pass in one chunk.
12529 patch.length1 += diff_text.length;
12530 start1 += diff_text.length;
12531 empty = false;
12532 patch.diffs.push([diff_type, diff_text]);
12533 bigpatch.diffs.shift();
12534 } else {
12535 // Deletion or equality. Only take as much as we can stomach.
12536 diff_text = diff_text.substring(0,
12537 patch_size - patch.length1 - this.Patch_Margin);
12538 patch.length1 += diff_text.length;
12539 start1 += diff_text.length;
12540 if (diff_type === DIFF_EQUAL) {
12541 patch.length2 += diff_text.length;
12542 start2 += diff_text.length;
12543 } else {
12544 empty = false;
12545 }
12546 patch.diffs.push([diff_type, diff_text]);
12547 if (diff_text == bigpatch.diffs[0][1]) {
12548 bigpatch.diffs.shift();
12549 } else {
12550 bigpatch.diffs[0][1] =
12551 bigpatch.diffs[0][1].substring(diff_text.length);
12552 }
12553 }
12554 }
12555 // Compute the head context for the next patch.
12556 precontext = this.diff_text2(patch.diffs);
12557 precontext =
12558 precontext.substring(precontext.length - this.Patch_Margin);
12559 // Append the end context for this patch.
12560 var postcontext = this.diff_text1(bigpatch.diffs)
12561 .substring(0, this.Patch_Margin);
12562 if (postcontext !== '') {
12563 patch.length1 += postcontext.length;
12564 patch.length2 += postcontext.length;
12565 if (patch.diffs.length !== 0 &&
12566 patch.diffs[patch.diffs.length - 1][0] === DIFF_EQUAL) {
12567 patch.diffs[patch.diffs.length - 1][1] += postcontext;
12568 } else {
12569 patch.diffs.push([DIFF_EQUAL, postcontext]);
12570 }
12571 }
12572 if (!empty) {
12573 patches.splice(++x, 0, patch);
12574 }
12575 }
12576 }
12577};
12578
12579
12580/**
12581 * Take a list of patches and return a textual representation.
12582 * @param {!Array.<!diff_match_patch.patch_obj>} patches Array of Patch objects.
12583 * @return {string} Text representation of patches.
12584 */
12585diff_match_patch.prototype.patch_toText = function(patches) {
12586 var text = [];
12587 for (var x = 0; x < patches.length; x++) {
12588 text[x] = patches[x];
12589 }
12590 return text.join('');
12591};
12592
12593
12594/**
12595 * Parse a textual representation of patches and return a list of Patch objects.
12596 * @param {string} textline Text representation of patches.
12597 * @return {!Array.<!diff_match_patch.patch_obj>} Array of Patch objects.
12598 * @throws {!Error} If invalid input.
12599 */
12600diff_match_patch.prototype.patch_fromText = function(textline) {
12601 var patches = [];
12602 if (!textline) {
12603 return patches;
12604 }
12605 var text = textline.split('\n');
12606 var textPointer = 0;
12607 var patchHeader = /^@@ -(\d+),?(\d*) \+(\d+),?(\d*) @@$/;
12608 while (textPointer < text.length) {
12609 var m = text[textPointer].match(patchHeader);
12610 if (!m) {
12611 throw new Error('Invalid patch string: ' + text[textPointer]);
12612 }
12613 var patch = new diff_match_patch.patch_obj();
12614 patches.push(patch);
12615 patch.start1 = parseInt(m[1], 10);
12616 if (m[2] === '') {
12617 patch.start1--;
12618 patch.length1 = 1;
12619 } else if (m[2] == '0') {
12620 patch.length1 = 0;
12621 } else {
12622 patch.start1--;
12623 patch.length1 = parseInt(m[2], 10);
12624 }
12625
12626 patch.start2 = parseInt(m[3], 10);
12627 if (m[4] === '') {
12628 patch.start2--;
12629 patch.length2 = 1;
12630 } else if (m[4] == '0') {
12631 patch.length2 = 0;
12632 } else {
12633 patch.start2--;
12634 patch.length2 = parseInt(m[4], 10);
12635 }
12636 textPointer++;
12637
12638 while (textPointer < text.length) {
12639 var sign = text[textPointer].charAt(0);
12640 try {
12641 var line = decodeURI(text[textPointer].substring(1));
12642 } catch (ex) {
12643 // Malformed URI sequence.
12644 throw new Error('Illegal escape in patch_fromText: ' + line);
12645 }
12646 if (sign == '-') {
12647 // Deletion.
12648 patch.diffs.push([DIFF_DELETE, line]);
12649 } else if (sign == '+') {
12650 // Insertion.
12651 patch.diffs.push([DIFF_INSERT, line]);
12652 } else if (sign == ' ') {
12653 // Minor equality.
12654 patch.diffs.push([DIFF_EQUAL, line]);
12655 } else if (sign == '@') {
12656 // Start of next patch.
12657 break;
12658 } else if (sign === '') {
12659 // Blank line? Whatever.
12660 } else {
12661 // WTF?
12662 throw new Error('Invalid patch mode "' + sign + '" in: ' + line);
12663 }
12664 textPointer++;
12665 }
12666 }
12667 return patches;
12668};
12669
12670
12671/**
12672 * Class representing one patch operation.
12673 * @constructor
12674 */
12675diff_match_patch.patch_obj = function() {
12676 /** @type {!Array.<!diff_match_patch.Diff>} */
12677 this.diffs = [];
12678 /** @type {?number} */
12679 this.start1 = null;
12680 /** @type {?number} */
12681 this.start2 = null;
12682 /** @type {number} */
12683 this.length1 = 0;
12684 /** @type {number} */
12685 this.length2 = 0;
12686};
12687
12688
12689/**
12690 * Emmulate GNU diff's format.
12691 * Header: @@ -382,8 +481,9 @@
12692 * Indicies are printed as 1-based, not 0-based.
12693 * @return {string} The GNU diff string.
12694 */
12695diff_match_patch.patch_obj.prototype.toString = function() {
12696 var coords1, coords2;
12697 if (this.length1 === 0) {
12698 coords1 = this.start1 + ',0';
12699 } else if (this.length1 == 1) {
12700 coords1 = this.start1 + 1;
12701 } else {
12702 coords1 = (this.start1 + 1) + ',' + this.length1;
12703 }
12704 if (this.length2 === 0) {
12705 coords2 = this.start2 + ',0';
12706 } else if (this.length2 == 1) {
12707 coords2 = this.start2 + 1;
12708 } else {
12709 coords2 = (this.start2 + 1) + ',' + this.length2;
12710 }
12711 var text = ['@@ -' + coords1 + ' +' + coords2 + ' @@\n'];
12712 var op;
12713 // Escape the body of the patch with %xx notation.
12714 for (var x = 0; x < this.diffs.length; x++) {
12715 switch (this.diffs[x][0]) {
12716 case DIFF_INSERT:
12717 op = '+';
12718 break;
12719 case DIFF_DELETE:
12720 op = '-';
12721 break;
12722 case DIFF_EQUAL:
12723 op = ' ';
12724 break;
12725 }
12726 text[x + 1] = op + encodeURI(this.diffs[x][1]) + '\n';
12727 }
12728 return text.join('').replace(/%20/g, ' ');
12729};
12730
12731
12732// Export these global variables so that they survive Google's JS compiler.
12733// In a browser, 'this' will be 'window'.
12734// Users of node.js should 'require' the uncompressed version since Google's
12735// JS compiler may break the following exports for non-browser environments.
12736this['diff_match_patch'] = diff_match_patch;
12737this['DIFF_DELETE'] = DIFF_DELETE;
12738this['DIFF_INSERT'] = DIFF_INSERT;
12739this['DIFF_EQUAL'] = DIFF_EQUAL;
12740
12741},{}],55:[function(_dereq_,module,exports){
12742/**
12743 * stringifier
12744 *
12745 * https://github.com/twada/stringifier
12746 *
12747 * Copyright (c) 2014-2015 Takuto Wada
12748 * Licensed under the MIT license.
12749 * http://twada.mit-license.org/2014-2015
12750 */
12751'use strict';
12752
12753var traverse = _dereq_('traverse'),
12754 typeName = _dereq_('type-name'),
12755 extend = _dereq_('xtend'),
12756 s = _dereq_('./strategies');
12757
12758function defaultHandlers () {
12759 return {
12760 'null': s.always('null'),
12761 'undefined': s.always('undefined'),
12762 'function': s.prune(),
12763 'string': s.json(),
12764 'boolean': s.json(),
12765 'number': s.number(),
12766 'symbol': s.toStr(),
12767 'RegExp': s.toStr(),
12768 'String': s.newLike(),
12769 'Boolean': s.newLike(),
12770 'Number': s.newLike(),
12771 'Date': s.newLike(),
12772 'Array': s.array(),
12773 'Object': s.object(),
12774 '@default': s.object()
12775 };
12776}
12777
12778function defaultOptions () {
12779 return {
12780 maxDepth: null,
12781 indent: null,
12782 anonymous: '@Anonymous',
12783 circular: '#@Circular#',
12784 snip: '..(snip)',
12785 lineSeparator: '\n',
12786 typeFun: typeName
12787 };
12788}
12789
12790function createStringifier (customOptions) {
12791 var options = extend(defaultOptions(), customOptions),
12792 handlers = extend(defaultHandlers(), options.handlers);
12793 return function stringifyAny (push, x) {
12794 var context = this,
12795 handler = handlerFor(context.node, options, handlers),
12796 currentPath = '/' + context.path.join('/'),
12797 customization = handlers[currentPath],
12798 acc = {
12799 context: context,
12800 options: options,
12801 handlers: handlers,
12802 push: push
12803 };
12804 if (typeName(customization) === 'function') {
12805 handler = customization;
12806 } else if (typeName(customization) === 'number') {
12807 handler = s.flow.compose(s.filters.truncate(customization),handler);
12808 }
12809 handler(acc, x);
12810 return push;
12811 };
12812}
12813
12814function handlerFor (val, options, handlers) {
12815 var tname = options.typeFun(val);
12816 if (typeName(handlers[tname]) === 'function') {
12817 return handlers[tname];
12818 }
12819 return handlers['@default'];
12820}
12821
12822function walk (val, reducer) {
12823 var buffer = [],
12824 push = function (str) {
12825 buffer.push(str);
12826 };
12827 traverse(val).reduce(reducer, push);
12828 return buffer.join('');
12829}
12830
12831function stringify (val, options) {
12832 return walk(val, createStringifier(options));
12833}
12834
12835function stringifier (options) {
12836 return function (val) {
12837 return walk(val, createStringifier(options));
12838 };
12839}
12840
12841stringifier.stringify = stringify;
12842stringifier.strategies = s;
12843stringifier.defaultOptions = defaultOptions;
12844stringifier.defaultHandlers = defaultHandlers;
12845module.exports = stringifier;
12846
12847},{"./strategies":58,"traverse":57,"type-name":59,"xtend":60}],56:[function(_dereq_,module,exports){
12848/**
12849 * array-reduce-right
12850 * Array#reduceRight ponyfill for older browsers
12851 * (Ponyfill: A polyfill that doesn't overwrite the native method)
12852 *
12853 * https://github.com/twada/array-reduce-right
12854 *
12855 * Copyright (c) 2015 Takuto Wada
12856 * Licensed under the MIT license.
12857 * http://twada.mit-license.org/
12858 */
12859'use strict';
12860
12861var slice = Array.prototype.slice;
12862
12863module.exports = function reduceRight (ary, callback /*, initialValue*/) {
12864 if (ary.reduceRight) {
12865 return ary.reduceRight.apply(ary, slice.apply(arguments).slice(1));
12866 }
12867 if ('function' !== typeof callback) {
12868 throw new TypeError(callback + ' is not a function');
12869 }
12870 var t = Object(ary), len = t.length >>> 0, k = len - 1, value;
12871 if (arguments.length >= 3) {
12872 value = arguments[2];
12873 } else {
12874 while (k >= 0 && !(k in t)) {
12875 k--;
12876 }
12877 if (k < 0) {
12878 throw new TypeError('Reduce of empty array with no initial value');
12879 }
12880 value = t[k--];
12881 }
12882 for (; k >= 0; k--) {
12883 if (k in t) {
12884 value = callback(value, t[k], k, t);
12885 }
12886 }
12887 return value;
12888};
12889
12890},{}],57:[function(_dereq_,module,exports){
12891var traverse = module.exports = function (obj) {
12892 return new Traverse(obj);
12893};
12894
12895function Traverse (obj) {
12896 this.value = obj;
12897}
12898
12899Traverse.prototype.get = function (ps) {
12900 var node = this.value;
12901 for (var i = 0; i < ps.length; i ++) {
12902 var key = ps[i];
12903 if (!node || !hasOwnProperty.call(node, key)) {
12904 node = undefined;
12905 break;
12906 }
12907 node = node[key];
12908 }
12909 return node;
12910};
12911
12912Traverse.prototype.has = function (ps) {
12913 var node = this.value;
12914 for (var i = 0; i < ps.length; i ++) {
12915 var key = ps[i];
12916 if (!node || !hasOwnProperty.call(node, key)) {
12917 return false;
12918 }
12919 node = node[key];
12920 }
12921 return true;
12922};
12923
12924Traverse.prototype.set = function (ps, value) {
12925 var node = this.value;
12926 for (var i = 0; i < ps.length - 1; i ++) {
12927 var key = ps[i];
12928 if (!hasOwnProperty.call(node, key)) node[key] = {};
12929 node = node[key];
12930 }
12931 node[ps[i]] = value;
12932 return value;
12933};
12934
12935Traverse.prototype.map = function (cb) {
12936 return walk(this.value, cb, true);
12937};
12938
12939Traverse.prototype.forEach = function (cb) {
12940 this.value = walk(this.value, cb, false);
12941 return this.value;
12942};
12943
12944Traverse.prototype.reduce = function (cb, init) {
12945 var skip = arguments.length === 1;
12946 var acc = skip ? this.value : init;
12947 this.forEach(function (x) {
12948 if (!this.isRoot || !skip) {
12949 acc = cb.call(this, acc, x);
12950 }
12951 });
12952 return acc;
12953};
12954
12955Traverse.prototype.paths = function () {
12956 var acc = [];
12957 this.forEach(function (x) {
12958 acc.push(this.path);
12959 });
12960 return acc;
12961};
12962
12963Traverse.prototype.nodes = function () {
12964 var acc = [];
12965 this.forEach(function (x) {
12966 acc.push(this.node);
12967 });
12968 return acc;
12969};
12970
12971Traverse.prototype.clone = function () {
12972 var parents = [], nodes = [];
12973
12974 return (function clone (src) {
12975 for (var i = 0; i < parents.length; i++) {
12976 if (parents[i] === src) {
12977 return nodes[i];
12978 }
12979 }
12980
12981 if (typeof src === 'object' && src !== null) {
12982 var dst = copy(src);
12983
12984 parents.push(src);
12985 nodes.push(dst);
12986
12987 forEach(objectKeys(src), function (key) {
12988 dst[key] = clone(src[key]);
12989 });
12990
12991 parents.pop();
12992 nodes.pop();
12993 return dst;
12994 }
12995 else {
12996 return src;
12997 }
12998 })(this.value);
12999};
13000
13001function walk (root, cb, immutable) {
13002 var path = [];
13003 var parents = [];
13004 var alive = true;
13005
13006 return (function walker (node_) {
13007 var node = immutable ? copy(node_) : node_;
13008 var modifiers = {};
13009
13010 var keepGoing = true;
13011
13012 var state = {
13013 node : node,
13014 node_ : node_,
13015 path : [].concat(path),
13016 parent : parents[parents.length - 1],
13017 parents : parents,
13018 key : path.slice(-1)[0],
13019 isRoot : path.length === 0,
13020 level : path.length,
13021 circular : null,
13022 update : function (x, stopHere) {
13023 if (!state.isRoot) {
13024 state.parent.node[state.key] = x;
13025 }
13026 state.node = x;
13027 if (stopHere) keepGoing = false;
13028 },
13029 'delete' : function (stopHere) {
13030 delete state.parent.node[state.key];
13031 if (stopHere) keepGoing = false;
13032 },
13033 remove : function (stopHere) {
13034 if (isArray(state.parent.node)) {
13035 state.parent.node.splice(state.key, 1);
13036 }
13037 else {
13038 delete state.parent.node[state.key];
13039 }
13040 if (stopHere) keepGoing = false;
13041 },
13042 keys : null,
13043 before : function (f) { modifiers.before = f },
13044 after : function (f) { modifiers.after = f },
13045 pre : function (f) { modifiers.pre = f },
13046 post : function (f) { modifiers.post = f },
13047 stop : function () { alive = false },
13048 block : function () { keepGoing = false }
13049 };
13050
13051 if (!alive) return state;
13052
13053 function updateState() {
13054 if (typeof state.node === 'object' && state.node !== null) {
13055 if (!state.keys || state.node_ !== state.node) {
13056 state.keys = objectKeys(state.node)
13057 }
13058
13059 state.isLeaf = state.keys.length == 0;
13060
13061 for (var i = 0; i < parents.length; i++) {
13062 if (parents[i].node_ === node_) {
13063 state.circular = parents[i];
13064 break;
13065 }
13066 }
13067 }
13068 else {
13069 state.isLeaf = true;
13070 state.keys = null;
13071 }
13072
13073 state.notLeaf = !state.isLeaf;
13074 state.notRoot = !state.isRoot;
13075 }
13076
13077 updateState();
13078
13079 // use return values to update if defined
13080 var ret = cb.call(state, state.node);
13081 if (ret !== undefined && state.update) state.update(ret);
13082
13083 if (modifiers.before) modifiers.before.call(state, state.node);
13084
13085 if (!keepGoing) return state;
13086
13087 if (typeof state.node == 'object'
13088 && state.node !== null && !state.circular) {
13089 parents.push(state);
13090
13091 updateState();
13092
13093 forEach(state.keys, function (key, i) {
13094 path.push(key);
13095
13096 if (modifiers.pre) modifiers.pre.call(state, state.node[key], key);
13097
13098 var child = walker(state.node[key]);
13099 if (immutable && hasOwnProperty.call(state.node, key)) {
13100 state.node[key] = child.node;
13101 }
13102
13103 child.isLast = i == state.keys.length - 1;
13104 child.isFirst = i == 0;
13105
13106 if (modifiers.post) modifiers.post.call(state, child);
13107
13108 path.pop();
13109 });
13110 parents.pop();
13111 }
13112
13113 if (modifiers.after) modifiers.after.call(state, state.node);
13114
13115 return state;
13116 })(root).node;
13117}
13118
13119function copy (src) {
13120 if (typeof src === 'object' && src !== null) {
13121 var dst;
13122
13123 if (isArray(src)) {
13124 dst = [];
13125 }
13126 else if (isDate(src)) {
13127 dst = new Date(src.getTime ? src.getTime() : src);
13128 }
13129 else if (isRegExp(src)) {
13130 dst = new RegExp(src);
13131 }
13132 else if (isError(src)) {
13133 dst = { message: src.message };
13134 }
13135 else if (isBoolean(src)) {
13136 dst = new Boolean(src);
13137 }
13138 else if (isNumber(src)) {
13139 dst = new Number(src);
13140 }
13141 else if (isString(src)) {
13142 dst = new String(src);
13143 }
13144 else if (Object.create && Object.getPrototypeOf) {
13145 dst = Object.create(Object.getPrototypeOf(src));
13146 }
13147 else if (src.constructor === Object) {
13148 dst = {};
13149 }
13150 else {
13151 var proto =
13152 (src.constructor && src.constructor.prototype)
13153 || src.__proto__
13154 || {}
13155 ;
13156 var T = function () {};
13157 T.prototype = proto;
13158 dst = new T;
13159 }
13160
13161 forEach(objectKeys(src), function (key) {
13162 dst[key] = src[key];
13163 });
13164 return dst;
13165 }
13166 else return src;
13167}
13168
13169var objectKeys = Object.keys || function keys (obj) {
13170 var res = [];
13171 for (var key in obj) res.push(key)
13172 return res;
13173};
13174
13175function toS (obj) { return Object.prototype.toString.call(obj) }
13176function isDate (obj) { return toS(obj) === '[object Date]' }
13177function isRegExp (obj) { return toS(obj) === '[object RegExp]' }
13178function isError (obj) { return toS(obj) === '[object Error]' }
13179function isBoolean (obj) { return toS(obj) === '[object Boolean]' }
13180function isNumber (obj) { return toS(obj) === '[object Number]' }
13181function isString (obj) { return toS(obj) === '[object String]' }
13182
13183var isArray = Array.isArray || function isArray (xs) {
13184 return Object.prototype.toString.call(xs) === '[object Array]';
13185};
13186
13187var forEach = function (xs, fn) {
13188 if (xs.forEach) return xs.forEach(fn)
13189 else for (var i = 0; i < xs.length; i++) {
13190 fn(xs[i], i, xs);
13191 }
13192};
13193
13194forEach(objectKeys(Traverse.prototype), function (key) {
13195 traverse[key] = function (obj) {
13196 var args = [].slice.call(arguments, 1);
13197 var t = new Traverse(obj);
13198 return t[key].apply(t, args);
13199 };
13200});
13201
13202var hasOwnProperty = Object.hasOwnProperty || function (obj, key) {
13203 return key in obj;
13204};
13205
13206},{}],58:[function(_dereq_,module,exports){
13207'use strict';
13208
13209var typeName = _dereq_('type-name'),
13210 forEach = _dereq_('array-foreach'),
13211 arrayFilter = _dereq_('array-filter'),
13212 reduceRight = _dereq_('array-reduce-right'),
13213 indexOf = _dereq_('indexof'),
13214 slice = Array.prototype.slice,
13215 END = {},
13216 ITERATE = {};
13217
13218// arguments should end with end or iterate
13219function compose () {
13220 var filters = slice.apply(arguments);
13221 return reduceRight(filters, function(right, left) {
13222 return left(right);
13223 });
13224}
13225
13226// skip children
13227function end () {
13228 return function (acc, x) {
13229 acc.context.keys = [];
13230 return END;
13231 };
13232}
13233
13234// iterate children
13235function iterate () {
13236 return function (acc, x) {
13237 return ITERATE;
13238 };
13239}
13240
13241function filter (predicate) {
13242 return function (next) {
13243 return function (acc, x) {
13244 var toBeIterated,
13245 isIteratingArray = (typeName(x) === 'Array');
13246 if (typeName(predicate) === 'function') {
13247 toBeIterated = [];
13248 forEach(acc.context.keys, function (key) {
13249 var indexOrKey = isIteratingArray ? parseInt(key, 10) : key,
13250 kvp = {
13251 key: indexOrKey,
13252 value: x[key]
13253 },
13254 decision = predicate(kvp);
13255 if (decision) {
13256 toBeIterated.push(key);
13257 }
13258 if (typeName(decision) === 'number') {
13259 truncateByKey(decision, key, acc);
13260 }
13261 if (typeName(decision) === 'function') {
13262 customizeStrategyForKey(decision, key, acc);
13263 }
13264 });
13265 acc.context.keys = toBeIterated;
13266 }
13267 return next(acc, x);
13268 };
13269 };
13270}
13271
13272function customizeStrategyForKey (strategy, key, acc) {
13273 acc.handlers[currentPath(key, acc)] = strategy;
13274}
13275
13276function truncateByKey (size, key, acc) {
13277 acc.handlers[currentPath(key, acc)] = size;
13278}
13279
13280function currentPath (key, acc) {
13281 var pathToCurrentNode = [''].concat(acc.context.path);
13282 if (typeName(key) !== 'undefined') {
13283 pathToCurrentNode.push(key);
13284 }
13285 return pathToCurrentNode.join('/');
13286}
13287
13288function allowedKeys (orderedWhiteList) {
13289 return function (next) {
13290 return function (acc, x) {
13291 var isIteratingArray = (typeName(x) === 'Array');
13292 if (!isIteratingArray && typeName(orderedWhiteList) === 'Array') {
13293 acc.context.keys = arrayFilter(orderedWhiteList, function (propKey) {
13294 return indexOf(acc.context.keys, propKey) !== -1;
13295 });
13296 }
13297 return next(acc, x);
13298 };
13299 };
13300}
13301
13302function safeKeys () {
13303 return function (next) {
13304 return function (acc, x) {
13305 if (typeName(x) !== 'Array') {
13306 acc.context.keys = arrayFilter(acc.context.keys, function (propKey) {
13307 // Error handling for unsafe property access.
13308 // For example, on PhantomJS,
13309 // accessing HTMLInputElement.selectionEnd causes TypeError
13310 try {
13311 var val = x[propKey];
13312 return true;
13313 } catch (e) {
13314 // skip unsafe key
13315 return false;
13316 }
13317 });
13318 }
13319 return next(acc, x);
13320 };
13321 };
13322}
13323
13324function when (guard, then) {
13325 return function (next) {
13326 return function (acc, x) {
13327 var kvp = {
13328 key: acc.context.key,
13329 value: x
13330 };
13331 if (guard(kvp, acc)) {
13332 return then(acc, x);
13333 }
13334 return next(acc, x);
13335 };
13336 };
13337}
13338
13339function truncate (size) {
13340 return function (next) {
13341 return function (acc, x) {
13342 var orig = acc.push, ret;
13343 acc.push = function (str) {
13344 var savings = str.length - size,
13345 truncated;
13346 if (savings <= size) {
13347 orig.call(acc, str);
13348 } else {
13349 truncated = str.substring(0, size);
13350 orig.call(acc, truncated + acc.options.snip);
13351 }
13352 };
13353 ret = next(acc, x);
13354 acc.push = orig;
13355 return ret;
13356 };
13357 };
13358}
13359
13360function constructorName () {
13361 return function (next) {
13362 return function (acc, x) {
13363 var name = acc.options.typeFun(x);
13364 if (name === '') {
13365 name = acc.options.anonymous;
13366 }
13367 acc.push(name);
13368 return next(acc, x);
13369 };
13370 };
13371}
13372
13373function always (str) {
13374 return function (next) {
13375 return function (acc, x) {
13376 acc.push(str);
13377 return next(acc, x);
13378 };
13379 };
13380}
13381
13382function optionValue (key) {
13383 return function (next) {
13384 return function (acc, x) {
13385 acc.push(acc.options[key]);
13386 return next(acc, x);
13387 };
13388 };
13389}
13390
13391function json (replacer) {
13392 return function (next) {
13393 return function (acc, x) {
13394 acc.push(JSON.stringify(x, replacer));
13395 return next(acc, x);
13396 };
13397 };
13398}
13399
13400function toStr () {
13401 return function (next) {
13402 return function (acc, x) {
13403 acc.push(x.toString());
13404 return next(acc, x);
13405 };
13406 };
13407}
13408
13409function decorateArray () {
13410 return function (next) {
13411 return function (acc, x) {
13412 acc.context.before(function (node) {
13413 acc.push('[');
13414 });
13415 acc.context.after(function (node) {
13416 afterAllChildren(this, acc.push, acc.options);
13417 acc.push(']');
13418 });
13419 acc.context.pre(function (val, key) {
13420 beforeEachChild(this, acc.push, acc.options);
13421 });
13422 acc.context.post(function (childContext) {
13423 afterEachChild(childContext, acc.push);
13424 });
13425 return next(acc, x);
13426 };
13427 };
13428}
13429
13430function decorateObject () {
13431 return function (next) {
13432 return function (acc, x) {
13433 acc.context.before(function (node) {
13434 acc.push('{');
13435 });
13436 acc.context.after(function (node) {
13437 afterAllChildren(this, acc.push, acc.options);
13438 acc.push('}');
13439 });
13440 acc.context.pre(function (val, key) {
13441 beforeEachChild(this, acc.push, acc.options);
13442 acc.push(sanitizeKey(key) + (acc.options.indent ? ': ' : ':'));
13443 });
13444 acc.context.post(function (childContext) {
13445 afterEachChild(childContext, acc.push);
13446 });
13447 return next(acc, x);
13448 };
13449 };
13450}
13451
13452function sanitizeKey (key) {
13453 return /^[A-Za-z_]+$/.test(key) ? key : JSON.stringify(key);
13454}
13455
13456function afterAllChildren (context, push, options) {
13457 if (options.indent && 0 < context.keys.length) {
13458 push(options.lineSeparator);
13459 for(var i = 0; i < context.level; i += 1) { // indent level - 1
13460 push(options.indent);
13461 }
13462 }
13463}
13464
13465function beforeEachChild (context, push, options) {
13466 if (options.indent) {
13467 push(options.lineSeparator);
13468 for(var i = 0; i <= context.level; i += 1) {
13469 push(options.indent);
13470 }
13471 }
13472}
13473
13474function afterEachChild (childContext, push) {
13475 if (!childContext.isLast) {
13476 push(',');
13477 }
13478}
13479
13480function nan (kvp, acc) {
13481 return kvp.value !== kvp.value;
13482}
13483
13484function positiveInfinity (kvp, acc) {
13485 return !isFinite(kvp.value) && kvp.value === Infinity;
13486}
13487
13488function negativeInfinity (kvp, acc) {
13489 return !isFinite(kvp.value) && kvp.value !== Infinity;
13490}
13491
13492function circular (kvp, acc) {
13493 return acc.context.circular;
13494}
13495
13496function maxDepth (kvp, acc) {
13497 return (acc.options.maxDepth && acc.options.maxDepth <= acc.context.level);
13498}
13499
13500var prune = compose(
13501 always('#'),
13502 constructorName(),
13503 always('#'),
13504 end()
13505);
13506var omitNaN = when(nan, compose(
13507 always('NaN'),
13508 end()
13509));
13510var omitPositiveInfinity = when(positiveInfinity, compose(
13511 always('Infinity'),
13512 end()
13513));
13514var omitNegativeInfinity = when(negativeInfinity, compose(
13515 always('-Infinity'),
13516 end()
13517));
13518var omitCircular = when(circular, compose(
13519 optionValue('circular'),
13520 end()
13521));
13522var omitMaxDepth = when(maxDepth, prune);
13523
13524module.exports = {
13525 filters: {
13526 always: always,
13527 constructorName: constructorName,
13528 json: json,
13529 toStr: toStr,
13530 prune: prune,
13531 truncate: truncate,
13532 decorateArray: decorateArray,
13533 decorateObject: decorateObject
13534 },
13535 flow: {
13536 compose: compose,
13537 when: when,
13538 allowedKeys: allowedKeys,
13539 safeKeys: safeKeys,
13540 filter: filter,
13541 iterate: iterate,
13542 end: end
13543 },
13544 symbols: {
13545 END: END,
13546 ITERATE: ITERATE
13547 },
13548 always: function (str) {
13549 return compose(always(str), end());
13550 },
13551 json: function () {
13552 return compose(json(), end());
13553 },
13554 toStr: function () {
13555 return compose(toStr(), end());
13556 },
13557 prune: function () {
13558 return prune;
13559 },
13560 number: function () {
13561 return compose(
13562 omitNaN,
13563 omitPositiveInfinity,
13564 omitNegativeInfinity,
13565 json(),
13566 end()
13567 );
13568 },
13569 newLike: function () {
13570 return compose(
13571 always('new '),
13572 constructorName(),
13573 always('('),
13574 json(),
13575 always(')'),
13576 end()
13577 );
13578 },
13579 array: function (predicate) {
13580 return compose(
13581 omitCircular,
13582 omitMaxDepth,
13583 decorateArray(),
13584 filter(predicate),
13585 iterate()
13586 );
13587 },
13588 object: function (predicate, orderedWhiteList) {
13589 return compose(
13590 omitCircular,
13591 omitMaxDepth,
13592 constructorName(),
13593 decorateObject(),
13594 allowedKeys(orderedWhiteList),
13595 safeKeys(),
13596 filter(predicate),
13597 iterate()
13598 );
13599 }
13600};
13601
13602},{"array-filter":8,"array-foreach":9,"array-reduce-right":56,"indexof":36,"type-name":59}],59:[function(_dereq_,module,exports){
13603/**
13604 * type-name - Just a reasonable typeof
13605 *
13606 * https://github.com/twada/type-name
13607 *
13608 * Copyright (c) 2014 Takuto Wada
13609 * Licensed under the MIT license.
13610 * http://twada.mit-license.org/
13611 */
13612'use strict';
13613
13614var toStr = Object.prototype.toString;
13615
13616function funcName (f) {
13617 return f.name ? f.name : /^\s*function\s*([^\(]*)/im.exec(f.toString())[1];
13618}
13619
13620function ctorName (obj) {
13621 var strName = toStr.call(obj).slice(8, -1);
13622 if (strName === 'Object' && obj.constructor) {
13623 return funcName(obj.constructor);
13624 }
13625 return strName;
13626}
13627
13628function typeName (val) {
13629 var type;
13630 if (val === null) {
13631 return 'null';
13632 }
13633 type = typeof(val);
13634 if (type === 'object') {
13635 return ctorName(val);
13636 }
13637 return type;
13638}
13639
13640module.exports = typeName;
13641
13642},{}],60:[function(_dereq_,module,exports){
13643module.exports = extend
13644
13645function extend() {
13646 var target = {}
13647
13648 for (var i = 0; i < arguments.length; i++) {
13649 var source = arguments[i]
13650
13651 for (var key in source) {
13652 if (source.hasOwnProperty(key)) {
13653 target[key] = source[key]
13654 }
13655 }
13656 }
13657
13658 return target
13659}
13660
13661},{}],61:[function(_dereq_,module,exports){
13662module.exports = extend
13663
13664function extend(target) {
13665 for (var i = 1; i < arguments.length; i++) {
13666 var source = arguments[i]
13667
13668 for (var key in source) {
13669 if (source.hasOwnProperty(key)) {
13670 target[key] = source[key]
13671 }
13672 }
13673 }
13674
13675 return target
13676}
13677
13678},{}]},{},[1])(1)
13679});
13680