UNPKG

268 kBJavaScriptView Raw
1(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.jade = 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(require,module,exports){
2(function (process){
3'use strict';
4
5/*!
6 * Jade
7 * Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
8 * MIT Licensed
9 */
10
11/**
12 * Module dependencies.
13 */
14
15var Parser = require('./parser')
16 , Lexer = require('./lexer')
17 , Compiler = require('./compiler')
18 , runtime = require('./runtime')
19 , addWith = require('with')
20 , fs = require('fs')
21 , utils = require('./utils');
22
23/**
24 * Expose self closing tags.
25 */
26
27// FIXME: either stop exporting selfClosing in v2 or export the new object
28// form
29exports.selfClosing = Object.keys(require('void-elements'));
30
31/**
32 * Default supported doctypes.
33 */
34
35exports.doctypes = require('./doctypes');
36
37/**
38 * Text filters.
39 */
40
41exports.filters = require('./filters');
42
43/**
44 * Utilities.
45 */
46
47exports.utils = utils;
48
49/**
50 * Expose `Compiler`.
51 */
52
53exports.Compiler = Compiler;
54
55/**
56 * Expose `Parser`.
57 */
58
59exports.Parser = Parser;
60
61/**
62 * Expose `Lexer`.
63 */
64
65exports.Lexer = Lexer;
66
67/**
68 * Nodes.
69 */
70
71exports.nodes = require('./nodes');
72
73/**
74 * Jade runtime helpers.
75 */
76
77exports.runtime = runtime;
78
79/**
80 * Template function cache.
81 */
82
83exports.cache = {};
84
85/**
86 * Parse the given `str` of jade and return a function body.
87 *
88 * @param {String} str
89 * @param {Object} options
90 * @return {Object}
91 * @api private
92 */
93
94function parse(str, options){
95
96 if (options.lexer) {
97 console.warn('Using `lexer` as a local in render() is deprecated and '
98 + 'will be interpreted as an option in Jade 2.0.0');
99 }
100
101 // Parse
102 var parser = new (options.parser || Parser)(str, options.filename, options);
103 var tokens;
104 try {
105 // Parse
106 tokens = parser.parse();
107 } catch (err) {
108 parser = parser.context();
109 runtime.rethrow(err, parser.filename, parser.lexer.lineno, parser.input);
110 }
111
112 // Compile
113 var compiler = new (options.compiler || Compiler)(tokens, options);
114 var js;
115 try {
116 js = compiler.compile();
117 } catch (err) {
118 if (err.line && (err.filename || !options.filename)) {
119 runtime.rethrow(err, err.filename, err.line, parser.input);
120 } else {
121 if (err instanceof Error) {
122 err.message += '\n\nPlease report this entire error and stack trace to https://github.com/jadejs/jade/issues';
123 }
124 throw err;
125 }
126 }
127
128 // Debug compiler
129 if (options.debug) {
130 console.error('\nCompiled Function:\n\n\u001b[90m%s\u001b[0m', js.replace(/^/gm, ' '));
131 }
132
133 var globals = [];
134
135 if (options.globals) {
136 globals = options.globals.slice();
137 }
138
139 globals.push('jade');
140 globals.push('jade_mixins');
141 globals.push('jade_interp');
142 globals.push('jade_debug');
143 globals.push('buf');
144
145 var body = ''
146 + 'var buf = [];\n'
147 + 'var jade_mixins = {};\n'
148 + 'var jade_interp;\n'
149 + (options.self
150 ? 'var self = locals || {};\n' + js
151 : addWith('locals || {}', '\n' + js, globals)) + ';'
152 + 'return buf.join("");';
153 return {body: body, dependencies: parser.dependencies};
154}
155
156/**
157 * Get the template from a string or a file, either compiled on-the-fly or
158 * read from cache (if enabled), and cache the template if needed.
159 *
160 * If `str` is not set, the file specified in `options.filename` will be read.
161 *
162 * If `options.cache` is true, this function reads the file from
163 * `options.filename` so it must be set prior to calling this function.
164 *
165 * @param {Object} options
166 * @param {String=} str
167 * @return {Function}
168 * @api private
169 */
170function handleTemplateCache (options, str) {
171 var key = options.filename;
172 if (options.cache && exports.cache[key]) {
173 return exports.cache[key];
174 } else {
175 if (str === undefined) str = fs.readFileSync(options.filename, 'utf8');
176 var templ = exports.compile(str, options);
177 if (options.cache) exports.cache[key] = templ;
178 return templ;
179 }
180}
181
182/**
183 * Compile a `Function` representation of the given jade `str`.
184 *
185 * Options:
186 *
187 * - `compileDebug` when `false` debugging code is stripped from the compiled
188 template, when it is explicitly `true`, the source code is included in
189 the compiled template for better accuracy.
190 * - `filename` used to improve errors when `compileDebug` is not `false` and to resolve imports/extends
191 *
192 * @param {String} str
193 * @param {Options} options
194 * @return {Function}
195 * @api public
196 */
197
198exports.compile = function(str, options){
199 var options = options || {}
200 , filename = options.filename
201 ? utils.stringify(options.filename)
202 : 'undefined'
203 , fn;
204
205 str = String(str);
206
207 var parsed = parse(str, options);
208 if (options.compileDebug !== false) {
209 fn = [
210 'var jade_debug = [ new jade.DebugItem( 1, ' + filename + ' ) ];'
211 , 'try {'
212 , parsed.body
213 , '} catch (err) {'
214 , ' jade.rethrow(err, jade_debug[0].filename, jade_debug[0].lineno' + (options.compileDebug === true ? ',' + utils.stringify(str) : '') + ');'
215 , '}'
216 ].join('\n');
217 } else {
218 fn = parsed.body;
219 }
220 fn = new Function('locals, jade', fn)
221 var res = function(locals){ return fn(locals, Object.create(runtime)) };
222 if (options.client) {
223 res.toString = function () {
224 var err = new Error('The `client` option is deprecated, use the `jade.compileClient` method instead');
225 err.name = 'Warning';
226 console.error(err.stack || /* istanbul ignore next */ err.message);
227 return exports.compileClient(str, options);
228 };
229 }
230 res.dependencies = parsed.dependencies;
231 return res;
232};
233
234/**
235 * Compile a JavaScript source representation of the given jade `str`.
236 *
237 * Options:
238 *
239 * - `compileDebug` When it is `true`, the source code is included in
240 * the compiled template for better error messages.
241 * - `filename` used to improve errors when `compileDebug` is not `true` and to resolve imports/extends
242 * - `name` the name of the resulting function (defaults to "template")
243 *
244 * @param {String} str
245 * @param {Options} options
246 * @return {Object}
247 * @api public
248 */
249
250exports.compileClientWithDependenciesTracked = function(str, options){
251 var options = options || {};
252 var name = options.name || 'template';
253 var filename = options.filename ? utils.stringify(options.filename) : 'undefined';
254 var fn;
255
256 str = String(str);
257 options.compileDebug = options.compileDebug ? true : false;
258 var parsed = parse(str, options);
259 if (options.compileDebug) {
260 fn = [
261 'var jade_debug = [ new jade.DebugItem( 1, ' + filename + ' ) ];'
262 , 'try {'
263 , parsed.body
264 , '} catch (err) {'
265 , ' jade.rethrow(err, jade_debug[0].filename, jade_debug[0].lineno, ' + utils.stringify(str) + ');'
266 , '}'
267 ].join('\n');
268 } else {
269 fn = parsed.body;
270 }
271
272 return {body: 'function ' + name + '(locals) {\n' + fn + '\n}', dependencies: parsed.dependencies};
273};
274
275/**
276 * Compile a JavaScript source representation of the given jade `str`.
277 *
278 * Options:
279 *
280 * - `compileDebug` When it is `true`, the source code is included in
281 * the compiled template for better error messages.
282 * - `filename` used to improve errors when `compileDebug` is not `true` and to resolve imports/extends
283 * - `name` the name of the resulting function (defaults to "template")
284 *
285 * @param {String} str
286 * @param {Options} options
287 * @return {String}
288 * @api public
289 */
290exports.compileClient = function (str, options) {
291 return exports.compileClientWithDependenciesTracked(str, options).body;
292};
293
294/**
295 * Compile a `Function` representation of the given jade file.
296 *
297 * Options:
298 *
299 * - `compileDebug` when `false` debugging code is stripped from the compiled
300 template, when it is explicitly `true`, the source code is included in
301 the compiled template for better accuracy.
302 *
303 * @param {String} path
304 * @param {Options} options
305 * @return {Function}
306 * @api public
307 */
308exports.compileFile = function (path, options) {
309 options = options || {};
310 options.filename = path;
311 return handleTemplateCache(options);
312};
313
314/**
315 * Render the given `str` of jade.
316 *
317 * Options:
318 *
319 * - `cache` enable template caching
320 * - `filename` filename required for `include` / `extends` and caching
321 *
322 * @param {String} str
323 * @param {Object|Function} options or fn
324 * @param {Function|undefined} fn
325 * @returns {String}
326 * @api public
327 */
328
329exports.render = function(str, options, fn){
330 // support callback API
331 if ('function' == typeof options) {
332 fn = options, options = undefined;
333 }
334 if (typeof fn === 'function') {
335 var res
336 try {
337 res = exports.render(str, options);
338 } catch (ex) {
339 return fn(ex);
340 }
341 return fn(null, res);
342 }
343
344 options = options || {};
345
346 // cache requires .filename
347 if (options.cache && !options.filename) {
348 throw new Error('the "filename" option is required for caching');
349 }
350
351 return handleTemplateCache(options, str)(options);
352};
353
354/**
355 * Render a Jade file at the given `path`.
356 *
357 * @param {String} path
358 * @param {Object|Function} options or callback
359 * @param {Function|undefined} fn
360 * @returns {String}
361 * @api public
362 */
363
364exports.renderFile = function(path, options, fn){
365 // support callback API
366 if ('function' == typeof options) {
367 fn = options, options = undefined;
368 }
369 if (typeof fn === 'function') {
370 var res
371 try {
372 res = exports.renderFile(path, options);
373 } catch (ex) {
374 return fn(ex);
375 }
376 return fn(null, res);
377 }
378
379 options = options || {};
380
381 options.filename = path;
382 return handleTemplateCache(options)(options);
383};
384
385
386/**
387 * Compile a Jade file at the given `path` for use on the client.
388 *
389 * @param {String} path
390 * @param {Object} options
391 * @returns {String}
392 * @api public
393 */
394
395exports.compileFileClient = function(path, options){
396 var key = path + ':client';
397 options = options || {};
398
399 options.filename = path;
400
401 if (options.cache && exports.cache[key]) {
402 return exports.cache[key];
403 }
404
405 var str = fs.readFileSync(options.filename, 'utf8');
406 var out = exports.compileClient(str, options);
407 if (options.cache) exports.cache[key] = out;
408 return out;
409};
410
411/**
412 * Express support.
413 */
414
415exports.__express = function(path, options, fn) {
416 if(options.compileDebug == undefined && process.env.NODE_ENV === 'production') {
417 options.compileDebug = false;
418 }
419 exports.renderFile(path, options, fn);
420}
421
422}).call(this,require('_process'))
423},{"./compiler":2,"./doctypes":3,"./filters":4,"./lexer":6,"./nodes":16,"./parser":23,"./runtime":24,"./utils":25,"_process":28,"fs":26,"void-elements":34,"with":35}],2:[function(require,module,exports){
424'use strict';
425
426var nodes = require('./nodes');
427var filters = require('./filters');
428var doctypes = require('./doctypes');
429var runtime = require('./runtime');
430var utils = require('./utils');
431var selfClosing = require('void-elements');
432var parseJSExpression = require('character-parser').parseMax;
433var constantinople = require('constantinople');
434
435function isConstant(src) {
436 return constantinople(src, {jade: runtime, 'jade_interp': undefined});
437}
438function toConstant(src) {
439 return constantinople.toConstant(src, {jade: runtime, 'jade_interp': undefined});
440}
441function errorAtNode(node, error) {
442 error.line = node.line;
443 error.filename = node.filename;
444 return error;
445}
446
447/**
448 * Initialize `Compiler` with the given `node`.
449 *
450 * @param {Node} node
451 * @param {Object} options
452 * @api public
453 */
454
455var Compiler = module.exports = function Compiler(node, options) {
456 this.options = options = options || {};
457 this.node = node;
458 this.hasCompiledDoctype = false;
459 this.hasCompiledTag = false;
460 this.pp = options.pretty || false;
461 if (this.pp && typeof this.pp !== 'string') {
462 this.pp = ' ';
463 }
464 this.debug = false !== options.compileDebug;
465 this.indents = 0;
466 this.parentIndents = 0;
467 this.terse = false;
468 this.mixins = {};
469 this.dynamicMixins = false;
470 if (options.doctype) this.setDoctype(options.doctype);
471};
472
473/**
474 * Compiler prototype.
475 */
476
477Compiler.prototype = {
478
479 /**
480 * Compile parse tree to JavaScript.
481 *
482 * @api public
483 */
484
485 compile: function(){
486 this.buf = [];
487 if (this.pp) this.buf.push("var jade_indent = [];");
488 this.lastBufferedIdx = -1;
489 this.visit(this.node);
490 if (!this.dynamicMixins) {
491 // if there are no dynamic mixins we can remove any un-used mixins
492 var mixinNames = Object.keys(this.mixins);
493 for (var i = 0; i < mixinNames.length; i++) {
494 var mixin = this.mixins[mixinNames[i]];
495 if (!mixin.used) {
496 for (var x = 0; x < mixin.instances.length; x++) {
497 for (var y = mixin.instances[x].start; y < mixin.instances[x].end; y++) {
498 this.buf[y] = '';
499 }
500 }
501 }
502 }
503 }
504 return this.buf.join('\n');
505 },
506
507 /**
508 * Sets the default doctype `name`. Sets terse mode to `true` when
509 * html 5 is used, causing self-closing tags to end with ">" vs "/>",
510 * and boolean attributes are not mirrored.
511 *
512 * @param {string} name
513 * @api public
514 */
515
516 setDoctype: function(name){
517 this.doctype = doctypes[name.toLowerCase()] || '<!DOCTYPE ' + name + '>';
518 this.terse = this.doctype.toLowerCase() == '<!doctype html>';
519 this.xml = 0 == this.doctype.indexOf('<?xml');
520 },
521
522 /**
523 * Buffer the given `str` exactly as is or with interpolation
524 *
525 * @param {String} str
526 * @param {Boolean} interpolate
527 * @api public
528 */
529
530 buffer: function (str, interpolate) {
531 var self = this;
532 if (interpolate) {
533 var match = /(\\)?([#!]){((?:.|\n)*)$/.exec(str);
534 if (match) {
535 this.buffer(str.substr(0, match.index), false);
536 if (match[1]) { // escape
537 this.buffer(match[2] + '{', false);
538 this.buffer(match[3], true);
539 return;
540 } else {
541 var rest = match[3];
542 var range = parseJSExpression(rest);
543 var code = ('!' == match[2] ? '' : 'jade.escape') + "((jade_interp = " + range.src + ") == null ? '' : jade_interp)";
544 this.bufferExpression(code);
545 this.buffer(rest.substr(range.end + 1), true);
546 return;
547 }
548 }
549 }
550
551 str = utils.stringify(str);
552 str = str.substr(1, str.length - 2);
553
554 if (this.lastBufferedIdx == this.buf.length) {
555 if (this.lastBufferedType === 'code') this.lastBuffered += ' + "';
556 this.lastBufferedType = 'text';
557 this.lastBuffered += str;
558 this.buf[this.lastBufferedIdx - 1] = 'buf.push(' + this.bufferStartChar + this.lastBuffered + '");'
559 } else {
560 this.buf.push('buf.push("' + str + '");');
561 this.lastBufferedType = 'text';
562 this.bufferStartChar = '"';
563 this.lastBuffered = str;
564 this.lastBufferedIdx = this.buf.length;
565 }
566 },
567
568 /**
569 * Buffer the given `src` so it is evaluated at run time
570 *
571 * @param {String} src
572 * @api public
573 */
574
575 bufferExpression: function (src) {
576 if (isConstant(src)) {
577 return this.buffer(toConstant(src) + '', false)
578 }
579 if (this.lastBufferedIdx == this.buf.length) {
580 if (this.lastBufferedType === 'text') this.lastBuffered += '"';
581 this.lastBufferedType = 'code';
582 this.lastBuffered += ' + (' + src + ')';
583 this.buf[this.lastBufferedIdx - 1] = 'buf.push(' + this.bufferStartChar + this.lastBuffered + ');'
584 } else {
585 this.buf.push('buf.push(' + src + ');');
586 this.lastBufferedType = 'code';
587 this.bufferStartChar = '';
588 this.lastBuffered = '(' + src + ')';
589 this.lastBufferedIdx = this.buf.length;
590 }
591 },
592
593 /**
594 * Buffer an indent based on the current `indent`
595 * property and an additional `offset`.
596 *
597 * @param {Number} offset
598 * @param {Boolean} newline
599 * @api public
600 */
601
602 prettyIndent: function(offset, newline){
603 offset = offset || 0;
604 newline = newline ? '\n' : '';
605 this.buffer(newline + Array(this.indents + offset).join(this.pp));
606 if (this.parentIndents)
607 this.buf.push("buf.push.apply(buf, jade_indent);");
608 },
609
610 /**
611 * Visit `node`.
612 *
613 * @param {Node} node
614 * @api public
615 */
616
617 visit: function(node){
618 var debug = this.debug;
619
620 if (debug) {
621 this.buf.push('jade_debug.unshift(new jade.DebugItem( ' + node.line
622 + ', ' + (node.filename
623 ? utils.stringify(node.filename)
624 : 'jade_debug[0].filename')
625 + ' ));');
626 }
627
628 // Massive hack to fix our context
629 // stack for - else[ if] etc
630 if (false === node.debug && this.debug) {
631 this.buf.pop();
632 this.buf.pop();
633 }
634
635 this.visitNode(node);
636
637 if (debug) this.buf.push('jade_debug.shift();');
638 },
639
640 /**
641 * Visit `node`.
642 *
643 * @param {Node} node
644 * @api public
645 */
646
647 visitNode: function(node){
648 return this['visit' + node.type](node);
649 },
650
651 /**
652 * Visit case `node`.
653 *
654 * @param {Literal} node
655 * @api public
656 */
657
658 visitCase: function(node){
659 var _ = this.withinCase;
660 this.withinCase = true;
661 this.buf.push('switch (' + node.expr + '){');
662 this.visit(node.block);
663 this.buf.push('}');
664 this.withinCase = _;
665 },
666
667 /**
668 * Visit when `node`.
669 *
670 * @param {Literal} node
671 * @api public
672 */
673
674 visitWhen: function(node){
675 if ('default' == node.expr) {
676 this.buf.push('default:');
677 } else {
678 this.buf.push('case ' + node.expr + ':');
679 }
680 if (node.block) {
681 this.visit(node.block);
682 this.buf.push(' break;');
683 }
684 },
685
686 /**
687 * Visit literal `node`.
688 *
689 * @param {Literal} node
690 * @api public
691 */
692
693 visitLiteral: function(node){
694 this.buffer(node.str);
695 },
696
697 /**
698 * Visit all nodes in `block`.
699 *
700 * @param {Block} block
701 * @api public
702 */
703
704 visitBlock: function(block){
705 var len = block.nodes.length
706 , escape = this.escape
707 , pp = this.pp
708
709 // Pretty print multi-line text
710 if (pp && len > 1 && !escape && block.nodes[0].isText && block.nodes[1].isText)
711 this.prettyIndent(1, true);
712
713 for (var i = 0; i < len; ++i) {
714 // Pretty print text
715 if (pp && i > 0 && !escape && block.nodes[i].isText && block.nodes[i-1].isText)
716 this.prettyIndent(1, false);
717
718 this.visit(block.nodes[i]);
719 // Multiple text nodes are separated by newlines
720 if (block.nodes[i+1] && block.nodes[i].isText && block.nodes[i+1].isText)
721 this.buffer('\n');
722 }
723 },
724
725 /**
726 * Visit a mixin's `block` keyword.
727 *
728 * @param {MixinBlock} block
729 * @api public
730 */
731
732 visitMixinBlock: function(block){
733 if (this.pp) this.buf.push("jade_indent.push('" + Array(this.indents + 1).join(this.pp) + "');");
734 this.buf.push('block && block();');
735 if (this.pp) this.buf.push("jade_indent.pop();");
736 },
737
738 /**
739 * Visit `doctype`. Sets terse mode to `true` when html 5
740 * is used, causing self-closing tags to end with ">" vs "/>",
741 * and boolean attributes are not mirrored.
742 *
743 * @param {Doctype} doctype
744 * @api public
745 */
746
747 visitDoctype: function(doctype){
748 if (doctype && (doctype.val || !this.doctype)) {
749 this.setDoctype(doctype.val || 'default');
750 }
751
752 if (this.doctype) this.buffer(this.doctype);
753 this.hasCompiledDoctype = true;
754 },
755
756 /**
757 * Visit `mixin`, generating a function that
758 * may be called within the template.
759 *
760 * @param {Mixin} mixin
761 * @api public
762 */
763
764 visitMixin: function(mixin){
765 var name = 'jade_mixins[';
766 var args = mixin.args || '';
767 var block = mixin.block;
768 var attrs = mixin.attrs;
769 var attrsBlocks = mixin.attributeBlocks.slice();
770 var pp = this.pp;
771 var dynamic = mixin.name[0]==='#';
772 var key = mixin.name;
773 if (dynamic) this.dynamicMixins = true;
774 name += (dynamic ? mixin.name.substr(2,mixin.name.length-3):'"'+mixin.name+'"')+']';
775
776 this.mixins[key] = this.mixins[key] || {used: false, instances: []};
777 if (mixin.call) {
778 this.mixins[key].used = true;
779 if (pp) this.buf.push("jade_indent.push('" + Array(this.indents + 1).join(pp) + "');")
780 if (block || attrs.length || attrsBlocks.length) {
781
782 this.buf.push(name + '.call({');
783
784 if (block) {
785 this.buf.push('block: function(){');
786
787 // Render block with no indents, dynamically added when rendered
788 this.parentIndents++;
789 var _indents = this.indents;
790 this.indents = 0;
791 this.visit(mixin.block);
792 this.indents = _indents;
793 this.parentIndents--;
794
795 if (attrs.length || attrsBlocks.length) {
796 this.buf.push('},');
797 } else {
798 this.buf.push('}');
799 }
800 }
801
802 if (attrsBlocks.length) {
803 if (attrs.length) {
804 var val = this.attrs(attrs);
805 attrsBlocks.unshift(val);
806 }
807 this.buf.push('attributes: jade.merge([' + attrsBlocks.join(',') + '])');
808 } else if (attrs.length) {
809 var val = this.attrs(attrs);
810 this.buf.push('attributes: ' + val);
811 }
812
813 if (args) {
814 this.buf.push('}, ' + args + ');');
815 } else {
816 this.buf.push('});');
817 }
818
819 } else {
820 this.buf.push(name + '(' + args + ');');
821 }
822 if (pp) this.buf.push("jade_indent.pop();")
823 } else {
824 var mixin_start = this.buf.length;
825 args = args ? args.split(',') : [];
826 var rest;
827 if (args.length && /^\.\.\./.test(args[args.length - 1].trim())) {
828 rest = args.pop().trim().replace(/^\.\.\./, '');
829 }
830 // we need use jade_interp here for v8: https://code.google.com/p/v8/issues/detail?id=4165
831 // once fixed, use this: this.buf.push(name + ' = function(' + args.join(',') + '){');
832 this.buf.push(name + ' = jade_interp = function(' + args.join(',') + '){');
833 this.buf.push('var block = (this && this.block), attributes = (this && this.attributes) || {};');
834 if (rest) {
835 this.buf.push('var ' + rest + ' = [];');
836 this.buf.push('for (jade_interp = ' + args.length + '; jade_interp < arguments.length; jade_interp++) {');
837 this.buf.push(' ' + rest + '.push(arguments[jade_interp]);');
838 this.buf.push('}');
839 }
840 this.parentIndents++;
841 this.visit(block);
842 this.parentIndents--;
843 this.buf.push('};');
844 var mixin_end = this.buf.length;
845 this.mixins[key].instances.push({start: mixin_start, end: mixin_end});
846 }
847 },
848
849 /**
850 * Visit `tag` buffering tag markup, generating
851 * attributes, visiting the `tag`'s code and block.
852 *
853 * @param {Tag} tag
854 * @api public
855 */
856
857 visitTag: function(tag){
858 this.indents++;
859 var name = tag.name
860 , pp = this.pp
861 , self = this;
862
863 function bufferName() {
864 if (tag.buffer) self.bufferExpression(name);
865 else self.buffer(name);
866 }
867
868 if ('pre' == tag.name) this.escape = true;
869
870 if (!this.hasCompiledTag) {
871 if (!this.hasCompiledDoctype && 'html' == name) {
872 this.visitDoctype();
873 }
874 this.hasCompiledTag = true;
875 }
876
877 // pretty print
878 if (pp && !tag.isInline())
879 this.prettyIndent(0, true);
880
881 if (tag.selfClosing || (!this.xml && selfClosing[tag.name])) {
882 this.buffer('<');
883 bufferName();
884 this.visitAttributes(tag.attrs, tag.attributeBlocks.slice());
885 this.terse
886 ? this.buffer('>')
887 : this.buffer('/>');
888 // if it is non-empty throw an error
889 if (tag.block &&
890 !(tag.block.type === 'Block' && tag.block.nodes.length === 0) &&
891 tag.block.nodes.some(function (tag) {
892 return tag.type !== 'Text' || !/^\s*$/.test(tag.val)
893 })) {
894 throw errorAtNode(tag, new Error(name + ' is self closing and should not have content.'));
895 }
896 } else {
897 // Optimize attributes buffering
898 this.buffer('<');
899 bufferName();
900 this.visitAttributes(tag.attrs, tag.attributeBlocks.slice());
901 this.buffer('>');
902 if (tag.code) this.visitCode(tag.code);
903 this.visit(tag.block);
904
905 // pretty print
906 if (pp && !tag.isInline() && 'pre' != tag.name && !tag.canInline())
907 this.prettyIndent(0, true);
908
909 this.buffer('</');
910 bufferName();
911 this.buffer('>');
912 }
913
914 if ('pre' == tag.name) this.escape = false;
915
916 this.indents--;
917 },
918
919 /**
920 * Visit `filter`, throwing when the filter does not exist.
921 *
922 * @param {Filter} filter
923 * @api public
924 */
925
926 visitFilter: function(filter){
927 var text = filter.block.nodes.map(
928 function(node){ return node.val; }
929 ).join('\n');
930 filter.attrs.filename = this.options.filename;
931 try {
932 this.buffer(filters(filter.name, text, filter.attrs), true);
933 } catch (err) {
934 throw errorAtNode(filter, err);
935 }
936 },
937
938 /**
939 * Visit `text` node.
940 *
941 * @param {Text} text
942 * @api public
943 */
944
945 visitText: function(text){
946 this.buffer(text.val, true);
947 },
948
949 /**
950 * Visit a `comment`, only buffering when the buffer flag is set.
951 *
952 * @param {Comment} comment
953 * @api public
954 */
955
956 visitComment: function(comment){
957 if (!comment.buffer) return;
958 if (this.pp) this.prettyIndent(1, true);
959 this.buffer('<!--' + comment.val + '-->');
960 },
961
962 /**
963 * Visit a `BlockComment`.
964 *
965 * @param {Comment} comment
966 * @api public
967 */
968
969 visitBlockComment: function(comment){
970 if (!comment.buffer) return;
971 if (this.pp) this.prettyIndent(1, true);
972 this.buffer('<!--' + comment.val);
973 this.visit(comment.block);
974 if (this.pp) this.prettyIndent(1, true);
975 this.buffer('-->');
976 },
977
978 /**
979 * Visit `code`, respecting buffer / escape flags.
980 * If the code is followed by a block, wrap it in
981 * a self-calling function.
982 *
983 * @param {Code} code
984 * @api public
985 */
986
987 visitCode: function(code){
988 // Wrap code blocks with {}.
989 // we only wrap unbuffered code blocks ATM
990 // since they are usually flow control
991
992 // Buffer code
993 if (code.buffer) {
994 var val = code.val.trim();
995 val = 'null == (jade_interp = '+val+') ? "" : jade_interp';
996 if (code.escape) val = 'jade.escape(' + val + ')';
997 this.bufferExpression(val);
998 } else {
999 this.buf.push(code.val);
1000 }
1001
1002 // Block support
1003 if (code.block) {
1004 if (!code.buffer) this.buf.push('{');
1005 this.visit(code.block);
1006 if (!code.buffer) this.buf.push('}');
1007 }
1008 },
1009
1010 /**
1011 * Visit `each` block.
1012 *
1013 * @param {Each} each
1014 * @api public
1015 */
1016
1017 visitEach: function(each){
1018 this.buf.push(''
1019 + '// iterate ' + each.obj + '\n'
1020 + ';(function(){\n'
1021 + ' var $$obj = ' + each.obj + ';\n'
1022 + ' if (\'number\' == typeof $$obj.length) {\n');
1023
1024 if (each.alternative) {
1025 this.buf.push(' if ($$obj.length) {');
1026 }
1027
1028 this.buf.push(''
1029 + ' for (var ' + each.key + ' = 0, $$l = $$obj.length; ' + each.key + ' < $$l; ' + each.key + '++) {\n'
1030 + ' var ' + each.val + ' = $$obj[' + each.key + '];\n');
1031
1032 this.visit(each.block);
1033
1034 this.buf.push(' }\n');
1035
1036 if (each.alternative) {
1037 this.buf.push(' } else {');
1038 this.visit(each.alternative);
1039 this.buf.push(' }');
1040 }
1041
1042 this.buf.push(''
1043 + ' } else {\n'
1044 + ' var $$l = 0;\n'
1045 + ' for (var ' + each.key + ' in $$obj) {\n'
1046 + ' $$l++;'
1047 + ' var ' + each.val + ' = $$obj[' + each.key + '];\n');
1048
1049 this.visit(each.block);
1050
1051 this.buf.push(' }\n');
1052 if (each.alternative) {
1053 this.buf.push(' if ($$l === 0) {');
1054 this.visit(each.alternative);
1055 this.buf.push(' }');
1056 }
1057 this.buf.push(' }\n}).call(this);\n');
1058 },
1059
1060 /**
1061 * Visit `attrs`.
1062 *
1063 * @param {Array} attrs
1064 * @api public
1065 */
1066
1067 visitAttributes: function(attrs, attributeBlocks){
1068 if (attributeBlocks.length) {
1069 if (attrs.length) {
1070 var val = this.attrs(attrs);
1071 attributeBlocks.unshift(val);
1072 }
1073 this.bufferExpression('jade.attrs(jade.merge([' + attributeBlocks.join(',') + ']), ' + utils.stringify(this.terse) + ')');
1074 } else if (attrs.length) {
1075 this.attrs(attrs, true);
1076 }
1077 },
1078
1079 /**
1080 * Compile attributes.
1081 */
1082
1083 attrs: function(attrs, buffer){
1084 var buf = [];
1085 var classes = [];
1086 var classEscaping = [];
1087
1088 attrs.forEach(function(attr){
1089 var key = attr.name;
1090 var escaped = attr.escaped;
1091
1092 if (key === 'class') {
1093 classes.push(attr.val);
1094 classEscaping.push(attr.escaped);
1095 } else if (isConstant(attr.val)) {
1096 if (buffer) {
1097 this.buffer(runtime.attr(key, toConstant(attr.val), escaped, this.terse));
1098 } else {
1099 var val = toConstant(attr.val);
1100 if (key === 'style') val = runtime.style(val);
1101 if (escaped && !(key.indexOf('data') === 0 && typeof val !== 'string')) {
1102 val = runtime.escape(val);
1103 }
1104 buf.push(utils.stringify(key) + ': ' + utils.stringify(val));
1105 }
1106 } else {
1107 if (buffer) {
1108 this.bufferExpression('jade.attr("' + key + '", ' + attr.val + ', ' + utils.stringify(escaped) + ', ' + utils.stringify(this.terse) + ')');
1109 } else {
1110 var val = attr.val;
1111 if (key === 'style') {
1112 val = 'jade.style(' + val + ')';
1113 }
1114 if (escaped && !(key.indexOf('data') === 0)) {
1115 val = 'jade.escape(' + val + ')';
1116 } else if (escaped) {
1117 val = '(typeof (jade_interp = ' + val + ') == "string" ? jade.escape(jade_interp) : jade_interp)';
1118 }
1119 buf.push(utils.stringify(key) + ': ' + val);
1120 }
1121 }
1122 }.bind(this));
1123 if (buffer) {
1124 if (classes.every(isConstant)) {
1125 this.buffer(runtime.cls(classes.map(toConstant), classEscaping));
1126 } else {
1127 this.bufferExpression('jade.cls([' + classes.join(',') + '], ' + utils.stringify(classEscaping) + ')');
1128 }
1129 } else if (classes.length) {
1130 if (classes.every(isConstant)) {
1131 classes = utils.stringify(runtime.joinClasses(classes.map(toConstant).map(runtime.joinClasses).map(function (cls, i) {
1132 return classEscaping[i] ? runtime.escape(cls) : cls;
1133 })));
1134 } else {
1135 classes = '(jade_interp = ' + utils.stringify(classEscaping) + ',' +
1136 ' jade.joinClasses([' + classes.join(',') + '].map(jade.joinClasses).map(function (cls, i) {' +
1137 ' return jade_interp[i] ? jade.escape(cls) : cls' +
1138 ' }))' +
1139 ')';
1140 }
1141 if (classes.length)
1142 buf.push('"class": ' + classes);
1143 }
1144 return '{' + buf.join(',') + '}';
1145 }
1146};
1147
1148},{"./doctypes":3,"./filters":4,"./nodes":16,"./runtime":24,"./utils":25,"character-parser":29,"constantinople":30,"void-elements":34}],3:[function(require,module,exports){
1149'use strict';
1150
1151module.exports = {
1152 'default': '<!DOCTYPE html>'
1153 , 'xml': '<?xml version="1.0" encoding="utf-8" ?>'
1154 , 'transitional': '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">'
1155 , 'strict': '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">'
1156 , 'frameset': '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">'
1157 , '1.1': '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">'
1158 , 'basic': '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN" "http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd">'
1159 , 'mobile': '<!DOCTYPE html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.2//EN" "http://www.openmobilealliance.org/tech/DTD/xhtml-mobile12.dtd">'
1160};
1161},{}],4:[function(require,module,exports){
1162'use strict';
1163
1164module.exports = filter;
1165function filter(name, str, options) {
1166 if (typeof filter[name] === 'function') {
1167 return filter[name](str, options);
1168 } else {
1169 throw new Error('unknown filter ":' + name + '"');
1170 }
1171}
1172
1173},{}],5:[function(require,module,exports){
1174'use strict';
1175
1176module.exports = [
1177 'a'
1178 , 'abbr'
1179 , 'acronym'
1180 , 'b'
1181 , 'br'
1182 , 'code'
1183 , 'em'
1184 , 'font'
1185 , 'i'
1186 , 'img'
1187 , 'ins'
1188 , 'kbd'
1189 , 'map'
1190 , 'samp'
1191 , 'small'
1192 , 'span'
1193 , 'strong'
1194 , 'sub'
1195 , 'sup'
1196];
1197},{}],6:[function(require,module,exports){
1198'use strict';
1199
1200var utils = require('./utils');
1201var characterParser = require('character-parser');
1202
1203
1204/**
1205 * Initialize `Lexer` with the given `str`.
1206 *
1207 * @param {String} str
1208 * @param {String} filename
1209 * @api private
1210 */
1211
1212var Lexer = module.exports = function Lexer(str, filename) {
1213 this.input = str.replace(/\r\n|\r/g, '\n');
1214 this.filename = filename;
1215 this.deferredTokens = [];
1216 this.lastIndents = 0;
1217 this.lineno = 1;
1218 this.stash = [];
1219 this.indentStack = [];
1220 this.indentRe = null;
1221 this.pipeless = false;
1222};
1223
1224
1225function assertExpression(exp) {
1226 //this verifies that a JavaScript expression is valid
1227 Function('', 'return (' + exp + ')');
1228}
1229function assertNestingCorrect(exp) {
1230 //this verifies that code is properly nested, but allows
1231 //invalid JavaScript such as the contents of `attributes`
1232 var res = characterParser(exp)
1233 if (res.isNesting()) {
1234 throw new Error('Nesting must match on expression `' + exp + '`')
1235 }
1236}
1237
1238/**
1239 * Lexer prototype.
1240 */
1241
1242Lexer.prototype = {
1243
1244 /**
1245 * Construct a token with the given `type` and `val`.
1246 *
1247 * @param {String} type
1248 * @param {String} val
1249 * @return {Object}
1250 * @api private
1251 */
1252
1253 tok: function(type, val){
1254 return {
1255 type: type
1256 , line: this.lineno
1257 , val: val
1258 }
1259 },
1260
1261 /**
1262 * Consume the given `len` of input.
1263 *
1264 * @param {Number} len
1265 * @api private
1266 */
1267
1268 consume: function(len){
1269 this.input = this.input.substr(len);
1270 },
1271
1272 /**
1273 * Scan for `type` with the given `regexp`.
1274 *
1275 * @param {String} type
1276 * @param {RegExp} regexp
1277 * @return {Object}
1278 * @api private
1279 */
1280
1281 scan: function(regexp, type){
1282 var captures;
1283 if (captures = regexp.exec(this.input)) {
1284 this.consume(captures[0].length);
1285 return this.tok(type, captures[1]);
1286 }
1287 },
1288
1289 /**
1290 * Defer the given `tok`.
1291 *
1292 * @param {Object} tok
1293 * @api private
1294 */
1295
1296 defer: function(tok){
1297 this.deferredTokens.push(tok);
1298 },
1299
1300 /**
1301 * Lookahead `n` tokens.
1302 *
1303 * @param {Number} n
1304 * @return {Object}
1305 * @api private
1306 */
1307
1308 lookahead: function(n){
1309 var fetch = n - this.stash.length;
1310 while (fetch-- > 0) this.stash.push(this.next());
1311 return this.stash[--n];
1312 },
1313
1314 /**
1315 * Return the indexOf `(` or `{` or `[` / `)` or `}` or `]` delimiters.
1316 *
1317 * @return {Number}
1318 * @api private
1319 */
1320
1321 bracketExpression: function(skip){
1322 skip = skip || 0;
1323 var start = this.input[skip];
1324 if (start != '(' && start != '{' && start != '[') throw new Error('unrecognized start character');
1325 var end = ({'(': ')', '{': '}', '[': ']'})[start];
1326 var range = characterParser.parseMax(this.input, {start: skip + 1});
1327 if (this.input[range.end] !== end) throw new Error('start character ' + start + ' does not match end character ' + this.input[range.end]);
1328 return range;
1329 },
1330
1331 /**
1332 * Stashed token.
1333 */
1334
1335 stashed: function() {
1336 return this.stash.length
1337 && this.stash.shift();
1338 },
1339
1340 /**
1341 * Deferred token.
1342 */
1343
1344 deferred: function() {
1345 return this.deferredTokens.length
1346 && this.deferredTokens.shift();
1347 },
1348
1349 /**
1350 * end-of-source.
1351 */
1352
1353 eos: function() {
1354 if (this.input.length) return;
1355 if (this.indentStack.length) {
1356 this.indentStack.shift();
1357 return this.tok('outdent');
1358 } else {
1359 return this.tok('eos');
1360 }
1361 },
1362
1363 /**
1364 * Blank line.
1365 */
1366
1367 blank: function() {
1368 var captures;
1369 if (captures = /^\n *\n/.exec(this.input)) {
1370 this.consume(captures[0].length - 1);
1371 ++this.lineno;
1372 if (this.pipeless) return this.tok('text', '');
1373 return this.next();
1374 }
1375 },
1376
1377 /**
1378 * Comment.
1379 */
1380
1381 comment: function() {
1382 var captures;
1383 if (captures = /^\/\/(-)?([^\n]*)/.exec(this.input)) {
1384 this.consume(captures[0].length);
1385 var tok = this.tok('comment', captures[2]);
1386 tok.buffer = '-' != captures[1];
1387 this.pipeless = true;
1388 return tok;
1389 }
1390 },
1391
1392 /**
1393 * Interpolated tag.
1394 */
1395
1396 interpolation: function() {
1397 if (/^#\{/.test(this.input)) {
1398 var match = this.bracketExpression(1);
1399
1400 this.consume(match.end + 1);
1401 return this.tok('interpolation', match.src);
1402 }
1403 },
1404
1405 /**
1406 * Tag.
1407 */
1408
1409 tag: function() {
1410 var captures;
1411 if (captures = /^(\w[-:\w]*)(\/?)/.exec(this.input)) {
1412 this.consume(captures[0].length);
1413 var tok, name = captures[1];
1414 if (':' == name[name.length - 1]) {
1415 name = name.slice(0, -1);
1416 tok = this.tok('tag', name);
1417 this.defer(this.tok(':'));
1418 if (this.input[0] !== ' ') {
1419 console.warn('Warning: space required after `:` on line ' + this.lineno +
1420 ' of jade file "' + this.filename + '"');
1421 }
1422 while (' ' == this.input[0]) this.input = this.input.substr(1);
1423 } else {
1424 tok = this.tok('tag', name);
1425 }
1426 tok.selfClosing = !!captures[2];
1427 return tok;
1428 }
1429 },
1430
1431 /**
1432 * Filter.
1433 */
1434
1435 filter: function() {
1436 var tok = this.scan(/^:([\w\-]+)/, 'filter');
1437 if (tok) {
1438 this.pipeless = true;
1439 return tok;
1440 }
1441 },
1442
1443 /**
1444 * Doctype.
1445 */
1446
1447 doctype: function() {
1448 if (this.scan(/^!!! *([^\n]+)?/, 'doctype')) {
1449 throw new Error('`!!!` is deprecated, you must now use `doctype`');
1450 }
1451 var node = this.scan(/^(?:doctype) *([^\n]+)?/, 'doctype');
1452 if (node && node.val && node.val.trim() === '5') {
1453 throw new Error('`doctype 5` is deprecated, you must now use `doctype html`');
1454 }
1455 return node;
1456 },
1457
1458 /**
1459 * Id.
1460 */
1461
1462 id: function() {
1463 return this.scan(/^#([\w-]+)/, 'id');
1464 },
1465
1466 /**
1467 * Class.
1468 */
1469
1470 className: function() {
1471 return this.scan(/^\.([\w-]+)/, 'class');
1472 },
1473
1474 /**
1475 * Text.
1476 */
1477
1478 text: function() {
1479 return this.scan(/^(?:\| ?| )([^\n]+)/, 'text') ||
1480 this.scan(/^\|?( )/, 'text') ||
1481 this.scan(/^(<[^\n]*)/, 'text');
1482 },
1483
1484 textFail: function () {
1485 var tok;
1486 if (tok = this.scan(/^([^\.\n][^\n]+)/, 'text')) {
1487 console.warn('Warning: missing space before text for line ' + this.lineno +
1488 ' of jade file "' + this.filename + '"');
1489 return tok;
1490 }
1491 },
1492
1493 /**
1494 * Dot.
1495 */
1496
1497 dot: function() {
1498 var match;
1499 if (match = this.scan(/^\./, 'dot')) {
1500 this.pipeless = true;
1501 return match;
1502 }
1503 },
1504
1505 /**
1506 * Extends.
1507 */
1508
1509 "extends": function() {
1510 return this.scan(/^extends? +([^\n]+)/, 'extends');
1511 },
1512
1513 /**
1514 * Block prepend.
1515 */
1516
1517 prepend: function() {
1518 var captures;
1519 if (captures = /^prepend +([^\n]+)/.exec(this.input)) {
1520 this.consume(captures[0].length);
1521 var mode = 'prepend'
1522 , name = captures[1]
1523 , tok = this.tok('block', name);
1524 tok.mode = mode;
1525 return tok;
1526 }
1527 },
1528
1529 /**
1530 * Block append.
1531 */
1532
1533 append: function() {
1534 var captures;
1535 if (captures = /^append +([^\n]+)/.exec(this.input)) {
1536 this.consume(captures[0].length);
1537 var mode = 'append'
1538 , name = captures[1]
1539 , tok = this.tok('block', name);
1540 tok.mode = mode;
1541 return tok;
1542 }
1543 },
1544
1545 /**
1546 * Block.
1547 */
1548
1549 block: function() {
1550 var captures;
1551 if (captures = /^block\b *(?:(prepend|append) +)?([^\n]+)/.exec(this.input)) {
1552 this.consume(captures[0].length);
1553 var mode = captures[1] || 'replace'
1554 , name = captures[2]
1555 , tok = this.tok('block', name);
1556
1557 tok.mode = mode;
1558 return tok;
1559 }
1560 },
1561
1562 /**
1563 * Mixin Block.
1564 */
1565
1566 mixinBlock: function() {
1567 var captures;
1568 if (captures = /^block[ \t]*(\n|$)/.exec(this.input)) {
1569 this.consume(captures[0].length - captures[1].length);
1570 return this.tok('mixin-block');
1571 }
1572 },
1573
1574 /**
1575 * Yield.
1576 */
1577
1578 'yield': function() {
1579 return this.scan(/^yield */, 'yield');
1580 },
1581
1582 /**
1583 * Include.
1584 */
1585
1586 include: function() {
1587 return this.scan(/^include +([^\n]+)/, 'include');
1588 },
1589
1590 /**
1591 * Include with filter
1592 */
1593
1594 includeFiltered: function() {
1595 var captures;
1596 if (captures = /^include:([\w\-]+)([\( ])/.exec(this.input)) {
1597 this.consume(captures[0].length - 1);
1598 var filter = captures[1];
1599 var attrs = captures[2] === '(' ? this.attrs() : null;
1600 if (!(captures[2] === ' ' || this.input[0] === ' ')) {
1601 throw new Error('expected space after include:filter but got ' + utils.stringify(this.input[0]));
1602 }
1603 captures = /^ *([^\n]+)/.exec(this.input);
1604 if (!captures || captures[1].trim() === '') {
1605 throw new Error('missing path for include:filter');
1606 }
1607 this.consume(captures[0].length);
1608 var path = captures[1];
1609 var tok = this.tok('include', path);
1610 tok.filter = filter;
1611 tok.attrs = attrs;
1612 return tok;
1613 }
1614 },
1615
1616 /**
1617 * Case.
1618 */
1619
1620 "case": function() {
1621 return this.scan(/^case +([^\n]+)/, 'case');
1622 },
1623
1624 /**
1625 * When.
1626 */
1627
1628 when: function() {
1629 return this.scan(/^when +([^:\n]+)/, 'when');
1630 },
1631
1632 /**
1633 * Default.
1634 */
1635
1636 "default": function() {
1637 return this.scan(/^default */, 'default');
1638 },
1639
1640 /**
1641 * Call mixin.
1642 */
1643
1644 call: function(){
1645
1646 var tok, captures;
1647 if (captures = /^\+(\s*)(([-\w]+)|(#\{))/.exec(this.input)) {
1648 // try to consume simple or interpolated call
1649 if (captures[3]) {
1650 // simple call
1651 this.consume(captures[0].length);
1652 tok = this.tok('call', captures[3]);
1653 } else {
1654 // interpolated call
1655 var match = this.bracketExpression(2 + captures[1].length);
1656 this.consume(match.end + 1);
1657 assertExpression(match.src);
1658 tok = this.tok('call', '#{'+match.src+'}');
1659 }
1660
1661 // Check for args (not attributes)
1662 if (captures = /^ *\(/.exec(this.input)) {
1663 var range = this.bracketExpression(captures[0].length - 1);
1664 if (!/^\s*[-\w]+ *=/.test(range.src)) { // not attributes
1665 this.consume(range.end + 1);
1666 tok.args = range.src;
1667 }
1668 if (tok.args) {
1669 assertExpression('[' + tok.args + ']');
1670 }
1671 }
1672
1673 return tok;
1674 }
1675 },
1676
1677 /**
1678 * Mixin.
1679 */
1680
1681 mixin: function(){
1682 var captures;
1683 if (captures = /^mixin +([-\w]+)(?: *\((.*)\))? */.exec(this.input)) {
1684 this.consume(captures[0].length);
1685 var tok = this.tok('mixin', captures[1]);
1686 tok.args = captures[2];
1687 return tok;
1688 }
1689 },
1690
1691 /**
1692 * Conditional.
1693 */
1694
1695 conditional: function() {
1696 var captures;
1697 if (captures = /^(if|unless|else if|else)\b([^\n]*)/.exec(this.input)) {
1698 this.consume(captures[0].length);
1699 var type = captures[1]
1700 var js = captures[2];
1701 var isIf = false;
1702 var isElse = false;
1703
1704 switch (type) {
1705 case 'if':
1706 assertExpression(js)
1707 js = 'if (' + js + ')';
1708 isIf = true;
1709 break;
1710 case 'unless':
1711 assertExpression(js)
1712 js = 'if (!(' + js + '))';
1713 isIf = true;
1714 break;
1715 case 'else if':
1716 assertExpression(js)
1717 js = 'else if (' + js + ')';
1718 isIf = true;
1719 isElse = true;
1720 break;
1721 case 'else':
1722 if (js && js.trim()) {
1723 throw new Error('`else` cannot have a condition, perhaps you meant `else if`');
1724 }
1725 js = 'else';
1726 isElse = true;
1727 break;
1728 }
1729 var tok = this.tok('code', js);
1730 tok.isElse = isElse;
1731 tok.isIf = isIf;
1732 tok.requiresBlock = true;
1733 return tok;
1734 }
1735 },
1736
1737 /**
1738 * While.
1739 */
1740
1741 "while": function() {
1742 var captures;
1743 if (captures = /^while +([^\n]+)/.exec(this.input)) {
1744 this.consume(captures[0].length);
1745 assertExpression(captures[1])
1746 var tok = this.tok('code', 'while (' + captures[1] + ')');
1747 tok.requiresBlock = true;
1748 return tok;
1749 }
1750 },
1751
1752 /**
1753 * Each.
1754 */
1755
1756 each: function() {
1757 var captures;
1758 if (captures = /^(?:- *)?(?:each|for) +([a-zA-Z_$][\w$]*)(?: *, *([a-zA-Z_$][\w$]*))? * in *([^\n]+)/.exec(this.input)) {
1759 this.consume(captures[0].length);
1760 var tok = this.tok('each', captures[1]);
1761 tok.key = captures[2] || '$index';
1762 assertExpression(captures[3])
1763 tok.code = captures[3];
1764 return tok;
1765 }
1766 },
1767
1768 /**
1769 * Code.
1770 */
1771
1772 code: function() {
1773 var captures;
1774 if (captures = /^(!?=|-)[ \t]*([^\n]+)/.exec(this.input)) {
1775 this.consume(captures[0].length);
1776 var flags = captures[1];
1777 captures[1] = captures[2];
1778 var tok = this.tok('code', captures[1]);
1779 tok.escape = flags.charAt(0) === '=';
1780 tok.buffer = flags.charAt(0) === '=' || flags.charAt(1) === '=';
1781 if (tok.buffer) assertExpression(captures[1])
1782 return tok;
1783 }
1784 },
1785
1786
1787 /**
1788 * Block code.
1789 */
1790
1791 blockCode: function() {
1792 var captures;
1793 if (captures = /^-\n/.exec(this.input)) {
1794 this.consume(captures[0].length - 1);
1795 var tok = this.tok('blockCode');
1796 this.pipeless = true;
1797 return tok;
1798 }
1799 },
1800
1801 /**
1802 * Attributes.
1803 */
1804
1805 attrs: function() {
1806 if ('(' == this.input.charAt(0)) {
1807 var index = this.bracketExpression().end
1808 , str = this.input.substr(1, index-1)
1809 , tok = this.tok('attrs');
1810
1811 assertNestingCorrect(str);
1812
1813 var quote = '';
1814 var interpolate = function (attr) {
1815 return attr.replace(/(\\)?#\{(.+)/g, function(_, escape, expr){
1816 if (escape) return _;
1817 try {
1818 var range = characterParser.parseMax(expr);
1819 if (expr[range.end] !== '}') return _.substr(0, 2) + interpolate(_.substr(2));
1820 assertExpression(range.src)
1821 return quote + " + (" + range.src + ") + " + quote + interpolate(expr.substr(range.end + 1));
1822 } catch (ex) {
1823 return _.substr(0, 2) + interpolate(_.substr(2));
1824 }
1825 });
1826 }
1827
1828 this.consume(index + 1);
1829 tok.attrs = [];
1830
1831 var escapedAttr = true
1832 var key = '';
1833 var val = '';
1834 var interpolatable = '';
1835 var state = characterParser.defaultState();
1836 var loc = 'key';
1837 var isEndOfAttribute = function (i) {
1838 if (key.trim() === '') return false;
1839 if (i === str.length) return true;
1840 if (loc === 'key') {
1841 if (str[i] === ' ' || str[i] === '\n') {
1842 for (var x = i; x < str.length; x++) {
1843 if (str[x] != ' ' && str[x] != '\n') {
1844 if (str[x] === '=' || str[x] === '!' || str[x] === ',') return false;
1845 else return true;
1846 }
1847 }
1848 }
1849 return str[i] === ','
1850 } else if (loc === 'value' && !state.isNesting()) {
1851 try {
1852 assertExpression(val);
1853 if (str[i] === ' ' || str[i] === '\n') {
1854 for (var x = i; x < str.length; x++) {
1855 if (str[x] != ' ' && str[x] != '\n') {
1856 if (characterParser.isPunctuator(str[x]) && str[x] != '"' && str[x] != "'") return false;
1857 else return true;
1858 }
1859 }
1860 }
1861 return str[i] === ',';
1862 } catch (ex) {
1863 return false;
1864 }
1865 }
1866 }
1867
1868 this.lineno += str.split("\n").length - 1;
1869
1870 for (var i = 0; i <= str.length; i++) {
1871 if (isEndOfAttribute(i)) {
1872 val = val.trim();
1873 if (val) assertExpression(val)
1874 key = key.trim();
1875 key = key.replace(/^['"]|['"]$/g, '');
1876 tok.attrs.push({
1877 name: key,
1878 val: '' == val ? true : val,
1879 escaped: escapedAttr
1880 });
1881 key = val = '';
1882 loc = 'key';
1883 escapedAttr = false;
1884 } else {
1885 switch (loc) {
1886 case 'key-char':
1887 if (str[i] === quote) {
1888 loc = 'key';
1889 if (i + 1 < str.length && [' ', ',', '!', '=', '\n'].indexOf(str[i + 1]) === -1)
1890 throw new Error('Unexpected character ' + str[i + 1] + ' expected ` `, `\\n`, `,`, `!` or `=`');
1891 } else {
1892 key += str[i];
1893 }
1894 break;
1895 case 'key':
1896 if (key === '' && (str[i] === '"' || str[i] === "'")) {
1897 loc = 'key-char';
1898 quote = str[i];
1899 } else if (str[i] === '!' || str[i] === '=') {
1900 escapedAttr = str[i] !== '!';
1901 if (str[i] === '!') i++;
1902 if (str[i] !== '=') throw new Error('Unexpected character ' + str[i] + ' expected `=`');
1903 loc = 'value';
1904 state = characterParser.defaultState();
1905 } else {
1906 key += str[i]
1907 }
1908 break;
1909 case 'value':
1910 state = characterParser.parseChar(str[i], state);
1911 if (state.isString()) {
1912 loc = 'string';
1913 quote = str[i];
1914 interpolatable = str[i];
1915 } else {
1916 val += str[i];
1917 }
1918 break;
1919 case 'string':
1920 state = characterParser.parseChar(str[i], state);
1921 interpolatable += str[i];
1922 if (!state.isString()) {
1923 loc = 'value';
1924 val += interpolate(interpolatable);
1925 }
1926 break;
1927 }
1928 }
1929 }
1930
1931 if ('/' == this.input.charAt(0)) {
1932 this.consume(1);
1933 tok.selfClosing = true;
1934 }
1935
1936 return tok;
1937 }
1938 },
1939
1940 /**
1941 * &attributes block
1942 */
1943 attributesBlock: function () {
1944 var captures;
1945 if (/^&attributes\b/.test(this.input)) {
1946 this.consume(11);
1947 var args = this.bracketExpression();
1948 this.consume(args.end + 1);
1949 return this.tok('&attributes', args.src);
1950 }
1951 },
1952
1953 /**
1954 * Indent | Outdent | Newline.
1955 */
1956
1957 indent: function() {
1958 var captures, re;
1959
1960 // established regexp
1961 if (this.indentRe) {
1962 captures = this.indentRe.exec(this.input);
1963 // determine regexp
1964 } else {
1965 // tabs
1966 re = /^\n(\t*) */;
1967 captures = re.exec(this.input);
1968
1969 // spaces
1970 if (captures && !captures[1].length) {
1971 re = /^\n( *)/;
1972 captures = re.exec(this.input);
1973 }
1974
1975 // established
1976 if (captures && captures[1].length) this.indentRe = re;
1977 }
1978
1979 if (captures) {
1980 var tok
1981 , indents = captures[1].length;
1982
1983 ++this.lineno;
1984 this.consume(indents + 1);
1985
1986 if (' ' == this.input[0] || '\t' == this.input[0]) {
1987 throw new Error('Invalid indentation, you can use tabs or spaces but not both');
1988 }
1989
1990 // blank line
1991 if ('\n' == this.input[0]) {
1992 this.pipeless = false;
1993 return this.tok('newline');
1994 }
1995
1996 // outdent
1997 if (this.indentStack.length && indents < this.indentStack[0]) {
1998 while (this.indentStack.length && this.indentStack[0] > indents) {
1999 this.stash.push(this.tok('outdent'));
2000 this.indentStack.shift();
2001 }
2002 tok = this.stash.pop();
2003 // indent
2004 } else if (indents && indents != this.indentStack[0]) {
2005 this.indentStack.unshift(indents);
2006 tok = this.tok('indent', indents);
2007 // newline
2008 } else {
2009 tok = this.tok('newline');
2010 }
2011
2012 this.pipeless = false;
2013 return tok;
2014 }
2015 },
2016
2017 /**
2018 * Pipe-less text consumed only when
2019 * pipeless is true;
2020 */
2021
2022 pipelessText: function() {
2023 if (!this.pipeless) return;
2024 var captures, re;
2025
2026 // established regexp
2027 if (this.indentRe) {
2028 captures = this.indentRe.exec(this.input);
2029 // determine regexp
2030 } else {
2031 // tabs
2032 re = /^\n(\t*) */;
2033 captures = re.exec(this.input);
2034
2035 // spaces
2036 if (captures && !captures[1].length) {
2037 re = /^\n( *)/;
2038 captures = re.exec(this.input);
2039 }
2040
2041 // established
2042 if (captures && captures[1].length) this.indentRe = re;
2043 }
2044
2045 var indents = captures && captures[1].length;
2046 if (indents && (this.indentStack.length === 0 || indents > this.indentStack[0])) {
2047 var indent = captures[1];
2048 var line;
2049 var tokens = [];
2050 var isMatch;
2051 do {
2052 // text has `\n` as a prefix
2053 var i = this.input.substr(1).indexOf('\n');
2054 if (-1 == i) i = this.input.length - 1;
2055 var str = this.input.substr(1, i);
2056 isMatch = str.substr(0, indent.length) === indent || !str.trim();
2057 if (isMatch) {
2058 // consume test along with `\n` prefix if match
2059 this.consume(str.length + 1);
2060 ++this.lineno;
2061 tokens.push(str.substr(indent.length));
2062 }
2063 } while(this.input.length && isMatch);
2064 while (this.input.length === 0 && tokens[tokens.length - 1] === '') tokens.pop();
2065 return this.tok('pipeless-text', tokens);
2066 }
2067 },
2068
2069 /**
2070 * ':'
2071 */
2072
2073 colon: function() {
2074 var good = /^: +/.test(this.input);
2075 var res = this.scan(/^: */, ':');
2076 if (res && !good) {
2077 console.warn('Warning: space required after `:` on line ' + this.lineno +
2078 ' of jade file "' + this.filename + '"');
2079 }
2080 return res;
2081 },
2082
2083 fail: function () {
2084 throw new Error('unexpected text ' + this.input.substr(0, 5));
2085 },
2086
2087 /**
2088 * Return the next token object, or those
2089 * previously stashed by lookahead.
2090 *
2091 * @return {Object}
2092 * @api private
2093 */
2094
2095 advance: function(){
2096 return this.stashed()
2097 || this.next();
2098 },
2099
2100 /**
2101 * Return the next token object.
2102 *
2103 * @return {Object}
2104 * @api private
2105 */
2106
2107 next: function() {
2108 return this.deferred()
2109 || this.blank()
2110 || this.eos()
2111 || this.pipelessText()
2112 || this.yield()
2113 || this.doctype()
2114 || this.interpolation()
2115 || this["case"]()
2116 || this.when()
2117 || this["default"]()
2118 || this["extends"]()
2119 || this.append()
2120 || this.prepend()
2121 || this.block()
2122 || this.mixinBlock()
2123 || this.include()
2124 || this.includeFiltered()
2125 || this.mixin()
2126 || this.call()
2127 || this.conditional()
2128 || this.each()
2129 || this["while"]()
2130 || this.tag()
2131 || this.filter()
2132 || this.blockCode()
2133 || this.code()
2134 || this.id()
2135 || this.className()
2136 || this.attrs()
2137 || this.attributesBlock()
2138 || this.indent()
2139 || this.text()
2140 || this.comment()
2141 || this.colon()
2142 || this.dot()
2143 || this.textFail()
2144 || this.fail();
2145 }
2146};
2147
2148},{"./utils":25,"character-parser":29}],7:[function(require,module,exports){
2149'use strict';
2150
2151var Node = require('./node');
2152
2153/**
2154 * Initialize a `Attrs` node.
2155 *
2156 * @api public
2157 */
2158
2159var Attrs = module.exports = function Attrs() {
2160 this.attributeNames = [];
2161 this.attrs = [];
2162 this.attributeBlocks = [];
2163};
2164
2165// Inherit from `Node`.
2166Attrs.prototype = Object.create(Node.prototype);
2167Attrs.prototype.constructor = Attrs;
2168
2169Attrs.prototype.type = 'Attrs';
2170
2171/**
2172 * Set attribute `name` to `val`, keep in mind these become
2173 * part of a raw js object literal, so to quote a value you must
2174 * '"quote me"', otherwise or example 'user.name' is literal JavaScript.
2175 *
2176 * @param {String} name
2177 * @param {String} val
2178 * @param {Boolean} escaped
2179 * @return {Tag} for chaining
2180 * @api public
2181 */
2182
2183Attrs.prototype.setAttribute = function(name, val, escaped){
2184 if (name !== 'class' && this.attributeNames.indexOf(name) !== -1) {
2185 throw new Error('Duplicate attribute "' + name + '" is not allowed.');
2186 }
2187 this.attributeNames.push(name);
2188 this.attrs.push({ name: name, val: val, escaped: escaped });
2189 return this;
2190};
2191
2192/**
2193 * Remove attribute `name` when present.
2194 *
2195 * @param {String} name
2196 * @api public
2197 */
2198
2199Attrs.prototype.removeAttribute = function(name){
2200 var err = new Error('attrs.removeAttribute is deprecated and will be removed in v2.0.0');
2201 console.warn(err.stack);
2202
2203 for (var i = 0, len = this.attrs.length; i < len; ++i) {
2204 if (this.attrs[i] && this.attrs[i].name == name) {
2205 delete this.attrs[i];
2206 }
2207 }
2208};
2209
2210/**
2211 * Get attribute value by `name`.
2212 *
2213 * @param {String} name
2214 * @return {String}
2215 * @api public
2216 */
2217
2218Attrs.prototype.getAttribute = function(name){
2219 var err = new Error('attrs.getAttribute is deprecated and will be removed in v2.0.0');
2220 console.warn(err.stack);
2221
2222 for (var i = 0, len = this.attrs.length; i < len; ++i) {
2223 if (this.attrs[i] && this.attrs[i].name == name) {
2224 return this.attrs[i].val;
2225 }
2226 }
2227};
2228
2229Attrs.prototype.addAttributes = function (src) {
2230 this.attributeBlocks.push(src);
2231};
2232
2233},{"./node":20}],8:[function(require,module,exports){
2234'use strict';
2235
2236var Node = require('./node');
2237
2238/**
2239 * Initialize a `BlockComment` with the given `block`.
2240 *
2241 * @param {String} val
2242 * @param {Block} block
2243 * @param {Boolean} buffer
2244 * @api public
2245 */
2246
2247var BlockComment = module.exports = function BlockComment(val, block, buffer) {
2248 this.block = block;
2249 this.val = val;
2250 this.buffer = buffer;
2251};
2252
2253// Inherit from `Node`.
2254BlockComment.prototype = Object.create(Node.prototype);
2255BlockComment.prototype.constructor = BlockComment;
2256
2257BlockComment.prototype.type = 'BlockComment';
2258
2259},{"./node":20}],9:[function(require,module,exports){
2260'use strict';
2261
2262var Node = require('./node');
2263
2264/**
2265 * Initialize a new `Block` with an optional `node`.
2266 *
2267 * @param {Node} node
2268 * @api public
2269 */
2270
2271var Block = module.exports = function Block(node){
2272 this.nodes = [];
2273 if (node) this.push(node);
2274};
2275
2276// Inherit from `Node`.
2277Block.prototype = Object.create(Node.prototype);
2278Block.prototype.constructor = Block;
2279
2280Block.prototype.type = 'Block';
2281
2282/**
2283 * Block flag.
2284 */
2285
2286Block.prototype.isBlock = true;
2287
2288/**
2289 * Replace the nodes in `other` with the nodes
2290 * in `this` block.
2291 *
2292 * @param {Block} other
2293 * @api private
2294 */
2295
2296Block.prototype.replace = function(other){
2297 var err = new Error('block.replace is deprecated and will be removed in v2.0.0');
2298 console.warn(err.stack);
2299
2300 other.nodes = this.nodes;
2301};
2302
2303/**
2304 * Push the given `node`.
2305 *
2306 * @param {Node} node
2307 * @return {Number}
2308 * @api public
2309 */
2310
2311Block.prototype.push = function(node){
2312 return this.nodes.push(node);
2313};
2314
2315/**
2316 * Check if this block is empty.
2317 *
2318 * @return {Boolean}
2319 * @api public
2320 */
2321
2322Block.prototype.isEmpty = function(){
2323 return 0 == this.nodes.length;
2324};
2325
2326/**
2327 * Unshift the given `node`.
2328 *
2329 * @param {Node} node
2330 * @return {Number}
2331 * @api public
2332 */
2333
2334Block.prototype.unshift = function(node){
2335 return this.nodes.unshift(node);
2336};
2337
2338/**
2339 * Return the "last" block, or the first `yield` node.
2340 *
2341 * @return {Block}
2342 * @api private
2343 */
2344
2345Block.prototype.includeBlock = function(){
2346 var ret = this
2347 , node;
2348
2349 for (var i = 0, len = this.nodes.length; i < len; ++i) {
2350 node = this.nodes[i];
2351 if (node.yield) return node;
2352 else if (node.textOnly) continue;
2353 else if (node.includeBlock) ret = node.includeBlock();
2354 else if (node.block && !node.block.isEmpty()) ret = node.block.includeBlock();
2355 if (ret.yield) return ret;
2356 }
2357
2358 return ret;
2359};
2360
2361/**
2362 * Return a clone of this block.
2363 *
2364 * @return {Block}
2365 * @api private
2366 */
2367
2368Block.prototype.clone = function(){
2369 var err = new Error('block.clone is deprecated and will be removed in v2.0.0');
2370 console.warn(err.stack);
2371
2372 var clone = new Block;
2373 for (var i = 0, len = this.nodes.length; i < len; ++i) {
2374 clone.push(this.nodes[i].clone());
2375 }
2376 return clone;
2377};
2378
2379},{"./node":20}],10:[function(require,module,exports){
2380'use strict';
2381
2382var Node = require('./node');
2383
2384/**
2385 * Initialize a new `Case` with `expr`.
2386 *
2387 * @param {String} expr
2388 * @api public
2389 */
2390
2391var Case = exports = module.exports = function Case(expr, block){
2392 this.expr = expr;
2393 this.block = block;
2394};
2395
2396// Inherit from `Node`.
2397Case.prototype = Object.create(Node.prototype);
2398Case.prototype.constructor = Case;
2399
2400Case.prototype.type = 'Case';
2401
2402var When = exports.When = function When(expr, block){
2403 this.expr = expr;
2404 this.block = block;
2405 this.debug = false;
2406};
2407
2408// Inherit from `Node`.
2409When.prototype = Object.create(Node.prototype);
2410When.prototype.constructor = When;
2411
2412When.prototype.type = 'When';
2413
2414},{"./node":20}],11:[function(require,module,exports){
2415'use strict';
2416
2417var Node = require('./node');
2418
2419/**
2420 * Initialize a `Code` node with the given code `val`.
2421 * Code may also be optionally buffered and escaped.
2422 *
2423 * @param {String} val
2424 * @param {Boolean} buffer
2425 * @param {Boolean} escape
2426 * @api public
2427 */
2428
2429var Code = module.exports = function Code(val, buffer, escape) {
2430 this.val = val;
2431 this.buffer = buffer;
2432 this.escape = escape;
2433 if (val.match(/^ *else/)) this.debug = false;
2434};
2435
2436// Inherit from `Node`.
2437Code.prototype = Object.create(Node.prototype);
2438Code.prototype.constructor = Code;
2439
2440Code.prototype.type = 'Code'; // prevent the minifiers removing this
2441},{"./node":20}],12:[function(require,module,exports){
2442'use strict';
2443
2444var Node = require('./node');
2445
2446/**
2447 * Initialize a `Comment` with the given `val`, optionally `buffer`,
2448 * otherwise the comment may render in the output.
2449 *
2450 * @param {String} val
2451 * @param {Boolean} buffer
2452 * @api public
2453 */
2454
2455var Comment = module.exports = function Comment(val, buffer) {
2456 this.val = val;
2457 this.buffer = buffer;
2458};
2459
2460// Inherit from `Node`.
2461Comment.prototype = Object.create(Node.prototype);
2462Comment.prototype.constructor = Comment;
2463
2464Comment.prototype.type = 'Comment';
2465
2466},{"./node":20}],13:[function(require,module,exports){
2467'use strict';
2468
2469var Node = require('./node');
2470
2471/**
2472 * Initialize a `Doctype` with the given `val`.
2473 *
2474 * @param {String} val
2475 * @api public
2476 */
2477
2478var Doctype = module.exports = function Doctype(val) {
2479 this.val = val;
2480};
2481
2482// Inherit from `Node`.
2483Doctype.prototype = Object.create(Node.prototype);
2484Doctype.prototype.constructor = Doctype;
2485
2486Doctype.prototype.type = 'Doctype';
2487
2488},{"./node":20}],14:[function(require,module,exports){
2489'use strict';
2490
2491var Node = require('./node');
2492
2493/**
2494 * Initialize an `Each` node, representing iteration
2495 *
2496 * @param {String} obj
2497 * @param {String} val
2498 * @param {String} key
2499 * @param {Block} block
2500 * @api public
2501 */
2502
2503var Each = module.exports = function Each(obj, val, key, block) {
2504 this.obj = obj;
2505 this.val = val;
2506 this.key = key;
2507 this.block = block;
2508};
2509
2510// Inherit from `Node`.
2511Each.prototype = Object.create(Node.prototype);
2512Each.prototype.constructor = Each;
2513
2514Each.prototype.type = 'Each';
2515
2516},{"./node":20}],15:[function(require,module,exports){
2517'use strict';
2518
2519var Node = require('./node');
2520
2521/**
2522 * Initialize a `Filter` node with the given
2523 * filter `name` and `block`.
2524 *
2525 * @param {String} name
2526 * @param {Block|Node} block
2527 * @api public
2528 */
2529
2530var Filter = module.exports = function Filter(name, block, attrs) {
2531 this.name = name;
2532 this.block = block;
2533 this.attrs = attrs;
2534};
2535
2536// Inherit from `Node`.
2537Filter.prototype = Object.create(Node.prototype);
2538Filter.prototype.constructor = Filter;
2539
2540Filter.prototype.type = 'Filter';
2541
2542},{"./node":20}],16:[function(require,module,exports){
2543'use strict';
2544
2545exports.Node = require('./node');
2546exports.Tag = require('./tag');
2547exports.Code = require('./code');
2548exports.Each = require('./each');
2549exports.Case = require('./case');
2550exports.Text = require('./text');
2551exports.Block = require('./block');
2552exports.MixinBlock = require('./mixin-block');
2553exports.Mixin = require('./mixin');
2554exports.Filter = require('./filter');
2555exports.Comment = require('./comment');
2556exports.Literal = require('./literal');
2557exports.BlockComment = require('./block-comment');
2558exports.Doctype = require('./doctype');
2559
2560},{"./block":9,"./block-comment":8,"./case":10,"./code":11,"./comment":12,"./doctype":13,"./each":14,"./filter":15,"./literal":17,"./mixin":19,"./mixin-block":18,"./node":20,"./tag":21,"./text":22}],17:[function(require,module,exports){
2561'use strict';
2562
2563var Node = require('./node');
2564
2565/**
2566 * Initialize a `Literal` node with the given `str.
2567 *
2568 * @param {String} str
2569 * @api public
2570 */
2571
2572var Literal = module.exports = function Literal(str) {
2573 this.str = str;
2574};
2575
2576// Inherit from `Node`.
2577Literal.prototype = Object.create(Node.prototype);
2578Literal.prototype.constructor = Literal;
2579
2580Literal.prototype.type = 'Literal';
2581
2582},{"./node":20}],18:[function(require,module,exports){
2583'use strict';
2584
2585var Node = require('./node');
2586
2587/**
2588 * Initialize a new `Block` with an optional `node`.
2589 *
2590 * @param {Node} node
2591 * @api public
2592 */
2593
2594var MixinBlock = module.exports = function MixinBlock(){};
2595
2596// Inherit from `Node`.
2597MixinBlock.prototype = Object.create(Node.prototype);
2598MixinBlock.prototype.constructor = MixinBlock;
2599
2600MixinBlock.prototype.type = 'MixinBlock';
2601
2602},{"./node":20}],19:[function(require,module,exports){
2603'use strict';
2604
2605var Attrs = require('./attrs');
2606
2607/**
2608 * Initialize a new `Mixin` with `name` and `block`.
2609 *
2610 * @param {String} name
2611 * @param {String} args
2612 * @param {Block} block
2613 * @api public
2614 */
2615
2616var Mixin = module.exports = function Mixin(name, args, block, call){
2617 Attrs.call(this);
2618 this.name = name;
2619 this.args = args;
2620 this.block = block;
2621 this.call = call;
2622};
2623
2624// Inherit from `Attrs`.
2625Mixin.prototype = Object.create(Attrs.prototype);
2626Mixin.prototype.constructor = Mixin;
2627
2628Mixin.prototype.type = 'Mixin';
2629
2630},{"./attrs":7}],20:[function(require,module,exports){
2631'use strict';
2632
2633var Node = module.exports = function Node(){};
2634
2635/**
2636 * Clone this node (return itself)
2637 *
2638 * @return {Node}
2639 * @api private
2640 */
2641
2642Node.prototype.clone = function(){
2643 var err = new Error('node.clone is deprecated and will be removed in v2.0.0');
2644 console.warn(err.stack);
2645 return this;
2646};
2647
2648Node.prototype.type = '';
2649
2650},{}],21:[function(require,module,exports){
2651'use strict';
2652
2653var Attrs = require('./attrs');
2654var Block = require('./block');
2655var inlineTags = require('../inline-tags');
2656
2657/**
2658 * Initialize a `Tag` node with the given tag `name` and optional `block`.
2659 *
2660 * @param {String} name
2661 * @param {Block} block
2662 * @api public
2663 */
2664
2665var Tag = module.exports = function Tag(name, block) {
2666 Attrs.call(this);
2667 this.name = name;
2668 this.block = block || new Block;
2669};
2670
2671// Inherit from `Attrs`.
2672Tag.prototype = Object.create(Attrs.prototype);
2673Tag.prototype.constructor = Tag;
2674
2675Tag.prototype.type = 'Tag';
2676
2677/**
2678 * Clone this tag.
2679 *
2680 * @return {Tag}
2681 * @api private
2682 */
2683
2684Tag.prototype.clone = function(){
2685 var err = new Error('tag.clone is deprecated and will be removed in v2.0.0');
2686 console.warn(err.stack);
2687
2688 var clone = new Tag(this.name, this.block.clone());
2689 clone.line = this.line;
2690 clone.attrs = this.attrs;
2691 clone.textOnly = this.textOnly;
2692 return clone;
2693};
2694
2695/**
2696 * Check if this tag is an inline tag.
2697 *
2698 * @return {Boolean}
2699 * @api private
2700 */
2701
2702Tag.prototype.isInline = function(){
2703 return ~inlineTags.indexOf(this.name);
2704};
2705
2706/**
2707 * Check if this tag's contents can be inlined. Used for pretty printing.
2708 *
2709 * @return {Boolean}
2710 * @api private
2711 */
2712
2713Tag.prototype.canInline = function(){
2714 var nodes = this.block.nodes;
2715
2716 function isInline(node){
2717 // Recurse if the node is a block
2718 if (node.isBlock) return node.nodes.every(isInline);
2719 return node.isText || (node.isInline && node.isInline());
2720 }
2721
2722 // Empty tag
2723 if (!nodes.length) return true;
2724
2725 // Text-only or inline-only tag
2726 if (1 == nodes.length) return isInline(nodes[0]);
2727
2728 // Multi-line inline-only tag
2729 if (this.block.nodes.every(isInline)) {
2730 for (var i = 1, len = nodes.length; i < len; ++i) {
2731 if (nodes[i-1].isText && nodes[i].isText)
2732 return false;
2733 }
2734 return true;
2735 }
2736
2737 // Mixed tag
2738 return false;
2739};
2740
2741},{"../inline-tags":5,"./attrs":7,"./block":9}],22:[function(require,module,exports){
2742'use strict';
2743
2744var Node = require('./node');
2745
2746/**
2747 * Initialize a `Text` node with optional `line`.
2748 *
2749 * @param {String} line
2750 * @api public
2751 */
2752
2753var Text = module.exports = function Text(line) {
2754 this.val = line;
2755};
2756
2757// Inherit from `Node`.
2758Text.prototype = Object.create(Node.prototype);
2759Text.prototype.constructor = Text;
2760
2761Text.prototype.type = 'Text';
2762
2763/**
2764 * Flag as text.
2765 */
2766
2767Text.prototype.isText = true;
2768},{"./node":20}],23:[function(require,module,exports){
2769'use strict';
2770
2771var Lexer = require('./lexer');
2772var nodes = require('./nodes');
2773var utils = require('./utils');
2774var filters = require('./filters');
2775var path = require('path');
2776var constantinople = require('constantinople');
2777var parseJSExpression = require('character-parser').parseMax;
2778var extname = path.extname;
2779
2780/**
2781 * Initialize `Parser` with the given input `str` and `filename`.
2782 *
2783 * @param {String} str
2784 * @param {String} filename
2785 * @param {Object} options
2786 * @api public
2787 */
2788
2789var Parser = exports = module.exports = function Parser(str, filename, options){
2790 //Strip any UTF-8 BOM off of the start of `str`, if it exists.
2791 this.input = str.replace(/^\uFEFF/, '');
2792 this.lexer = new Lexer(this.input, filename);
2793 this.filename = filename;
2794 this.blocks = {};
2795 this.mixins = {};
2796 this.options = options;
2797 this.contexts = [this];
2798 this.inMixin = 0;
2799 this.dependencies = [];
2800 this.inBlock = 0;
2801};
2802
2803/**
2804 * Parser prototype.
2805 */
2806
2807Parser.prototype = {
2808
2809 /**
2810 * Save original constructor
2811 */
2812
2813 constructor: Parser,
2814
2815 /**
2816 * Push `parser` onto the context stack,
2817 * or pop and return a `Parser`.
2818 */
2819
2820 context: function(parser){
2821 if (parser) {
2822 this.contexts.push(parser);
2823 } else {
2824 return this.contexts.pop();
2825 }
2826 },
2827
2828 /**
2829 * Return the next token object.
2830 *
2831 * @return {Object}
2832 * @api private
2833 */
2834
2835 advance: function(){
2836 return this.lexer.advance();
2837 },
2838
2839 /**
2840 * Single token lookahead.
2841 *
2842 * @return {Object}
2843 * @api private
2844 */
2845
2846 peek: function() {
2847 return this.lookahead(1);
2848 },
2849
2850 /**
2851 * Return lexer lineno.
2852 *
2853 * @return {Number}
2854 * @api private
2855 */
2856
2857 line: function() {
2858 return this.lexer.lineno;
2859 },
2860
2861 /**
2862 * `n` token lookahead.
2863 *
2864 * @param {Number} n
2865 * @return {Object}
2866 * @api private
2867 */
2868
2869 lookahead: function(n){
2870 return this.lexer.lookahead(n);
2871 },
2872
2873 /**
2874 * Parse input returning a string of js for evaluation.
2875 *
2876 * @return {String}
2877 * @api public
2878 */
2879
2880 parse: function(){
2881 var block = new nodes.Block, parser;
2882 block.line = 0;
2883 block.filename = this.filename;
2884
2885 while ('eos' != this.peek().type) {
2886 if ('newline' == this.peek().type) {
2887 this.advance();
2888 } else {
2889 var next = this.peek();
2890 var expr = this.parseExpr();
2891 expr.filename = expr.filename || this.filename;
2892 expr.line = next.line;
2893 block.push(expr);
2894 }
2895 }
2896
2897 if (parser = this.extending) {
2898 this.context(parser);
2899 var ast = parser.parse();
2900 this.context();
2901
2902 // hoist mixins
2903 for (var name in this.mixins)
2904 ast.unshift(this.mixins[name]);
2905 return ast;
2906 }
2907
2908 if (!this.extending && !this.included && Object.keys(this.blocks).length){
2909 var blocks = [];
2910 utils.walkAST(block, function (node) {
2911 if (node.type === 'Block' && node.name) {
2912 blocks.push(node.name);
2913 }
2914 });
2915 Object.keys(this.blocks).forEach(function (name) {
2916 if (blocks.indexOf(name) === -1 && !this.blocks[name].isSubBlock) {
2917 console.warn('Warning: Unexpected block "'
2918 + name
2919 + '" '
2920 + ' on line '
2921 + this.blocks[name].line
2922 + ' of '
2923 + (this.blocks[name].filename)
2924 + '. This block is never used. This warning will be an error in v2.0.0');
2925 }
2926 }.bind(this));
2927 }
2928
2929 return block;
2930 },
2931
2932 /**
2933 * Expect the given type, or throw an exception.
2934 *
2935 * @param {String} type
2936 * @api private
2937 */
2938
2939 expect: function(type){
2940 if (this.peek().type === type) {
2941 return this.advance();
2942 } else {
2943 throw new Error('expected "' + type + '", but got "' + this.peek().type + '"');
2944 }
2945 },
2946
2947 /**
2948 * Accept the given `type`.
2949 *
2950 * @param {String} type
2951 * @api private
2952 */
2953
2954 accept: function(type){
2955 if (this.peek().type === type) {
2956 return this.advance();
2957 }
2958 },
2959
2960 /**
2961 * tag
2962 * | doctype
2963 * | mixin
2964 * | include
2965 * | filter
2966 * | comment
2967 * | text
2968 * | each
2969 * | code
2970 * | yield
2971 * | id
2972 * | class
2973 * | interpolation
2974 */
2975
2976 parseExpr: function(){
2977 switch (this.peek().type) {
2978 case 'tag':
2979 return this.parseTag();
2980 case 'mixin':
2981 return this.parseMixin();
2982 case 'block':
2983 return this.parseBlock();
2984 case 'mixin-block':
2985 return this.parseMixinBlock();
2986 case 'case':
2987 return this.parseCase();
2988 case 'extends':
2989 return this.parseExtends();
2990 case 'include':
2991 return this.parseInclude();
2992 case 'doctype':
2993 return this.parseDoctype();
2994 case 'filter':
2995 return this.parseFilter();
2996 case 'comment':
2997 return this.parseComment();
2998 case 'text':
2999 return this.parseText();
3000 case 'each':
3001 return this.parseEach();
3002 case 'code':
3003 return this.parseCode();
3004 case 'blockCode':
3005 return this.parseBlockCode();
3006 case 'call':
3007 return this.parseCall();
3008 case 'interpolation':
3009 return this.parseInterpolation();
3010 case 'yield':
3011 this.advance();
3012 var block = new nodes.Block;
3013 block.yield = true;
3014 return block;
3015 case 'id':
3016 case 'class':
3017 var tok = this.advance();
3018 this.lexer.defer(this.lexer.tok('tag', 'div'));
3019 this.lexer.defer(tok);
3020 return this.parseExpr();
3021 default:
3022 throw new Error('unexpected token "' + this.peek().type + '"');
3023 }
3024 },
3025
3026 /**
3027 * Text
3028 */
3029
3030 parseText: function(){
3031 var tok = this.expect('text');
3032 var tokens = this.parseInlineTagsInText(tok.val);
3033 if (tokens.length === 1) return tokens[0];
3034 var node = new nodes.Block;
3035 for (var i = 0; i < tokens.length; i++) {
3036 node.push(tokens[i]);
3037 };
3038 return node;
3039 },
3040
3041 /**
3042 * ':' expr
3043 * | block
3044 */
3045
3046 parseBlockExpansion: function(){
3047 if (':' == this.peek().type) {
3048 this.advance();
3049 return new nodes.Block(this.parseExpr());
3050 } else {
3051 return this.block();
3052 }
3053 },
3054
3055 /**
3056 * case
3057 */
3058
3059 parseCase: function(){
3060 var val = this.expect('case').val;
3061 var node = new nodes.Case(val);
3062 node.line = this.line();
3063
3064 var block = new nodes.Block;
3065 block.line = this.line();
3066 block.filename = this.filename;
3067 this.expect('indent');
3068 while ('outdent' != this.peek().type) {
3069 switch (this.peek().type) {
3070 case 'comment':
3071 case 'newline':
3072 this.advance();
3073 break;
3074 case 'when':
3075 block.push(this.parseWhen());
3076 break;
3077 case 'default':
3078 block.push(this.parseDefault());
3079 break;
3080 default:
3081 throw new Error('Unexpected token "' + this.peek().type
3082 + '", expected "when", "default" or "newline"');
3083 }
3084 }
3085 this.expect('outdent');
3086
3087 node.block = block;
3088
3089 return node;
3090 },
3091
3092 /**
3093 * when
3094 */
3095
3096 parseWhen: function(){
3097 var val = this.expect('when').val;
3098 if (this.peek().type !== 'newline')
3099 return new nodes.Case.When(val, this.parseBlockExpansion());
3100 else
3101 return new nodes.Case.When(val);
3102 },
3103
3104 /**
3105 * default
3106 */
3107
3108 parseDefault: function(){
3109 this.expect('default');
3110 return new nodes.Case.When('default', this.parseBlockExpansion());
3111 },
3112
3113 /**
3114 * code
3115 */
3116
3117 parseCode: function(afterIf){
3118 var tok = this.expect('code');
3119 var node = new nodes.Code(tok.val, tok.buffer, tok.escape);
3120 var block;
3121 node.line = this.line();
3122
3123 // throw an error if an else does not have an if
3124 if (tok.isElse && !tok.hasIf) {
3125 throw new Error('Unexpected else without if');
3126 }
3127
3128 // handle block
3129 block = 'indent' == this.peek().type;
3130 if (block) {
3131 node.block = this.block();
3132 }
3133
3134 // handle missing block
3135 if (tok.requiresBlock && !block) {
3136 node.block = new nodes.Block();
3137 }
3138
3139 // mark presense of if for future elses
3140 if (tok.isIf && this.peek().isElse) {
3141 this.peek().hasIf = true;
3142 } else if (tok.isIf && this.peek().type === 'newline' && this.lookahead(2).isElse) {
3143 this.lookahead(2).hasIf = true;
3144 }
3145
3146 return node;
3147 },
3148
3149 /**
3150 * block code
3151 */
3152
3153 parseBlockCode: function(){
3154 var tok = this.expect('blockCode');
3155 var node;
3156 var body = this.peek();
3157 var text;
3158 if (body.type === 'pipeless-text') {
3159 this.advance();
3160 text = body.val.join('\n');
3161 } else {
3162 text = '';
3163 }
3164 node = new nodes.Code(text, false, false);
3165 return node;
3166 },
3167
3168 /**
3169 * comment
3170 */
3171
3172 parseComment: function(){
3173 var tok = this.expect('comment');
3174 var node;
3175
3176 var block;
3177 if (block = this.parseTextBlock()) {
3178 node = new nodes.BlockComment(tok.val, block, tok.buffer);
3179 } else {
3180 node = new nodes.Comment(tok.val, tok.buffer);
3181 }
3182
3183 node.line = this.line();
3184 return node;
3185 },
3186
3187 /**
3188 * doctype
3189 */
3190
3191 parseDoctype: function(){
3192 var tok = this.expect('doctype');
3193 var node = new nodes.Doctype(tok.val);
3194 node.line = this.line();
3195 return node;
3196 },
3197
3198 /**
3199 * filter attrs? text-block
3200 */
3201
3202 parseFilter: function(){
3203 var tok = this.expect('filter');
3204 var attrs = this.accept('attrs');
3205 var block;
3206
3207 block = this.parseTextBlock() || new nodes.Block();
3208
3209 var options = {};
3210 if (attrs) {
3211 attrs.attrs.forEach(function (attribute) {
3212 options[attribute.name] = constantinople.toConstant(attribute.val);
3213 });
3214 }
3215
3216 var node = new nodes.Filter(tok.val, block, options);
3217 node.line = this.line();
3218 return node;
3219 },
3220
3221 /**
3222 * each block
3223 */
3224
3225 parseEach: function(){
3226 var tok = this.expect('each');
3227 var node = new nodes.Each(tok.code, tok.val, tok.key);
3228 node.line = this.line();
3229 node.block = this.block();
3230 if (this.peek().type == 'code' && this.peek().val == 'else') {
3231 this.advance();
3232 node.alternative = this.block();
3233 }
3234 return node;
3235 },
3236
3237 /**
3238 * Resolves a path relative to the template for use in
3239 * includes and extends
3240 *
3241 * @param {String} path
3242 * @param {String} purpose Used in error messages.
3243 * @return {String}
3244 * @api private
3245 */
3246
3247 resolvePath: function (path, purpose) {
3248 var p = require('path');
3249 var dirname = p.dirname;
3250 var basename = p.basename;
3251 var join = p.join;
3252
3253 if (path[0] !== '/' && !this.filename)
3254 throw new Error('the "filename" option is required to use "' + purpose + '" with "relative" paths');
3255
3256 if (path[0] === '/' && !this.options.basedir)
3257 throw new Error('the "basedir" option is required to use "' + purpose + '" with "absolute" paths');
3258
3259 path = join(path[0] === '/' ? this.options.basedir : dirname(this.filename), path);
3260
3261 if (basename(path).indexOf('.') === -1) path += '.jade';
3262
3263 return path;
3264 },
3265
3266 /**
3267 * 'extends' name
3268 */
3269
3270 parseExtends: function(){
3271 var fs = require('fs');
3272
3273 var path = this.resolvePath(this.expect('extends').val.trim(), 'extends');
3274 if ('.jade' != path.substr(-5)) path += '.jade';
3275
3276 this.dependencies.push(path);
3277 var str = fs.readFileSync(path, 'utf8');
3278 var parser = new this.constructor(str, path, this.options);
3279 parser.dependencies = this.dependencies;
3280
3281 parser.blocks = this.blocks;
3282 parser.included = this.included;
3283 parser.contexts = this.contexts;
3284 this.extending = parser;
3285
3286 // TODO: null node
3287 return new nodes.Literal('');
3288 },
3289
3290 /**
3291 * 'block' name block
3292 */
3293
3294 parseBlock: function(){
3295 var block = this.expect('block');
3296 var mode = block.mode;
3297 var name = block.val.trim();
3298
3299 var line = block.line;
3300
3301 this.inBlock++;
3302 block = 'indent' == this.peek().type
3303 ? this.block()
3304 : new nodes.Block(new nodes.Literal(''));
3305 this.inBlock--;
3306 block.name = name;
3307 block.line = line;
3308
3309 var prev = this.blocks[name] || {prepended: [], appended: []}
3310 if (prev.mode === 'replace') return this.blocks[name] = prev;
3311
3312 var allNodes = prev.prepended.concat(block.nodes).concat(prev.appended);
3313
3314 switch (mode) {
3315 case 'append':
3316 prev.appended = prev.parser === this ?
3317 prev.appended.concat(block.nodes) :
3318 block.nodes.concat(prev.appended);
3319 break;
3320 case 'prepend':
3321 prev.prepended = prev.parser === this ?
3322 block.nodes.concat(prev.prepended) :
3323 prev.prepended.concat(block.nodes);
3324 break;
3325 }
3326 block.nodes = allNodes;
3327 block.appended = prev.appended;
3328 block.prepended = prev.prepended;
3329 block.mode = mode;
3330 block.parser = this;
3331
3332 block.isSubBlock = this.inBlock > 0;
3333
3334 return this.blocks[name] = block;
3335 },
3336
3337 parseMixinBlock: function () {
3338 var block = this.expect('mixin-block');
3339 if (!this.inMixin) {
3340 throw new Error('Anonymous blocks are not allowed unless they are part of a mixin.');
3341 }
3342 return new nodes.MixinBlock();
3343 },
3344
3345 /**
3346 * include block?
3347 */
3348
3349 parseInclude: function(){
3350 var fs = require('fs');
3351 var tok = this.expect('include');
3352
3353 var path = this.resolvePath(tok.val.trim(), 'include');
3354 this.dependencies.push(path);
3355 // has-filter
3356 if (tok.filter) {
3357 var str = fs.readFileSync(path, 'utf8').replace(/\r/g, '');
3358 var options = {filename: path};
3359 if (tok.attrs) {
3360 tok.attrs.attrs.forEach(function (attribute) {
3361 options[attribute.name] = constantinople.toConstant(attribute.val);
3362 });
3363 }
3364 str = filters(tok.filter, str, options);
3365 return new nodes.Literal(str);
3366 }
3367
3368 // non-jade
3369 if ('.jade' != path.substr(-5)) {
3370 var str = fs.readFileSync(path, 'utf8').replace(/\r/g, '');
3371 return new nodes.Literal(str);
3372 }
3373
3374 var str = fs.readFileSync(path, 'utf8');
3375 var parser = new this.constructor(str, path, this.options);
3376 parser.dependencies = this.dependencies;
3377
3378 parser.blocks = utils.merge({}, this.blocks);
3379 parser.included = true;
3380
3381 parser.mixins = this.mixins;
3382
3383 this.context(parser);
3384 var ast = parser.parse();
3385 this.context();
3386 ast.filename = path;
3387
3388 if ('indent' == this.peek().type) {
3389 ast.includeBlock().push(this.block());
3390 }
3391
3392 return ast;
3393 },
3394
3395 /**
3396 * call ident block
3397 */
3398
3399 parseCall: function(){
3400 var tok = this.expect('call');
3401 var name = tok.val;
3402 var args = tok.args;
3403 var mixin = new nodes.Mixin(name, args, new nodes.Block, true);
3404
3405 this.tag(mixin);
3406 if (mixin.code) {
3407 mixin.block.push(mixin.code);
3408 mixin.code = null;
3409 }
3410 if (mixin.block.isEmpty()) mixin.block = null;
3411 return mixin;
3412 },
3413
3414 /**
3415 * mixin block
3416 */
3417
3418 parseMixin: function(){
3419 var tok = this.expect('mixin');
3420 var name = tok.val;
3421 var args = tok.args;
3422 var mixin;
3423
3424 // definition
3425 if ('indent' == this.peek().type) {
3426 this.inMixin++;
3427 mixin = new nodes.Mixin(name, args, this.block(), false);
3428 this.mixins[name] = mixin;
3429 this.inMixin--;
3430 return mixin;
3431 // call
3432 } else {
3433 return new nodes.Mixin(name, args, null, true);
3434 }
3435 },
3436
3437 parseInlineTagsInText: function (str) {
3438 var line = this.line();
3439
3440 var match = /(\\)?#\[((?:.|\n)*)$/.exec(str);
3441 if (match) {
3442 if (match[1]) { // escape
3443 var text = new nodes.Text(str.substr(0, match.index) + '#[');
3444 text.line = line;
3445 var rest = this.parseInlineTagsInText(match[2]);
3446 if (rest[0].type === 'Text') {
3447 text.val += rest[0].val;
3448 rest.shift();
3449 }
3450 return [text].concat(rest);
3451 } else {
3452 var text = new nodes.Text(str.substr(0, match.index));
3453 text.line = line;
3454 var buffer = [text];
3455 var rest = match[2];
3456 var range = parseJSExpression(rest);
3457 var inner = new Parser(range.src, this.filename, this.options);
3458 buffer.push(inner.parse());
3459 return buffer.concat(this.parseInlineTagsInText(rest.substr(range.end + 1)));
3460 }
3461 } else {
3462 var text = new nodes.Text(str);
3463 text.line = line;
3464 return [text];
3465 }
3466 },
3467
3468 /**
3469 * indent (text | newline)* outdent
3470 */
3471
3472 parseTextBlock: function(){
3473 var block = new nodes.Block;
3474 block.line = this.line();
3475 var body = this.peek();
3476 if (body.type !== 'pipeless-text') return;
3477 this.advance();
3478 block.nodes = body.val.reduce(function (accumulator, text) {
3479 return accumulator.concat(this.parseInlineTagsInText(text));
3480 }.bind(this), []);
3481 return block;
3482 },
3483
3484 /**
3485 * indent expr* outdent
3486 */
3487
3488 block: function(){
3489 var block = new nodes.Block;
3490 block.line = this.line();
3491 block.filename = this.filename;
3492 this.expect('indent');
3493 while ('outdent' != this.peek().type) {
3494 if ('newline' == this.peek().type) {
3495 this.advance();
3496 } else {
3497 var expr = this.parseExpr();
3498 expr.filename = this.filename;
3499 block.push(expr);
3500 }
3501 }
3502 this.expect('outdent');
3503 return block;
3504 },
3505
3506 /**
3507 * interpolation (attrs | class | id)* (text | code | ':')? newline* block?
3508 */
3509
3510 parseInterpolation: function(){
3511 var tok = this.advance();
3512 var tag = new nodes.Tag(tok.val);
3513 tag.buffer = true;
3514 return this.tag(tag);
3515 },
3516
3517 /**
3518 * tag (attrs | class | id)* (text | code | ':')? newline* block?
3519 */
3520
3521 parseTag: function(){
3522 var tok = this.advance();
3523 var tag = new nodes.Tag(tok.val);
3524
3525 tag.selfClosing = tok.selfClosing;
3526
3527 return this.tag(tag);
3528 },
3529
3530 /**
3531 * Parse tag.
3532 */
3533
3534 tag: function(tag){
3535 tag.line = this.line();
3536
3537 var seenAttrs = false;
3538 // (attrs | class | id)*
3539 out:
3540 while (true) {
3541 switch (this.peek().type) {
3542 case 'id':
3543 case 'class':
3544 var tok = this.advance();
3545 tag.setAttribute(tok.type, "'" + tok.val + "'");
3546 continue;
3547 case 'attrs':
3548 if (seenAttrs) {
3549 console.warn(this.filename + ', line ' + this.peek().line + ':\nYou should not have jade tags with multiple attributes.');
3550 }
3551 seenAttrs = true;
3552 var tok = this.advance();
3553 var attrs = tok.attrs;
3554
3555 if (tok.selfClosing) tag.selfClosing = true;
3556
3557 for (var i = 0; i < attrs.length; i++) {
3558 tag.setAttribute(attrs[i].name, attrs[i].val, attrs[i].escaped);
3559 }
3560 continue;
3561 case '&attributes':
3562 var tok = this.advance();
3563 tag.addAttributes(tok.val);
3564 break;
3565 default:
3566 break out;
3567 }
3568 }
3569
3570 // check immediate '.'
3571 if ('dot' == this.peek().type) {
3572 tag.textOnly = true;
3573 this.advance();
3574 }
3575
3576 // (text | code | ':')?
3577 switch (this.peek().type) {
3578 case 'text':
3579 tag.block.push(this.parseText());
3580 break;
3581 case 'code':
3582 tag.code = this.parseCode();
3583 break;
3584 case ':':
3585 this.advance();
3586 tag.block = new nodes.Block;
3587 tag.block.push(this.parseExpr());
3588 break;
3589 case 'newline':
3590 case 'indent':
3591 case 'outdent':
3592 case 'eos':
3593 case 'pipeless-text':
3594 break;
3595 default:
3596 throw new Error('Unexpected token `' + this.peek().type + '` expected `text`, `code`, `:`, `newline` or `eos`')
3597 }
3598
3599 // newline*
3600 while ('newline' == this.peek().type) this.advance();
3601
3602 // block?
3603 if (tag.textOnly) {
3604 tag.block = this.parseTextBlock() || new nodes.Block();
3605 } else if ('indent' == this.peek().type) {
3606 var block = this.block();
3607 for (var i = 0, len = block.nodes.length; i < len; ++i) {
3608 tag.block.push(block.nodes[i]);
3609 }
3610 }
3611
3612 return tag;
3613 }
3614};
3615
3616},{"./filters":4,"./lexer":6,"./nodes":16,"./utils":25,"character-parser":29,"constantinople":30,"fs":26,"path":27}],24:[function(require,module,exports){
3617'use strict';
3618
3619/**
3620 * Merge two attribute objects giving precedence
3621 * to values in object `b`. Classes are special-cased
3622 * allowing for arrays and merging/joining appropriately
3623 * resulting in a string.
3624 *
3625 * @param {Object} a
3626 * @param {Object} b
3627 * @return {Object} a
3628 * @api private
3629 */
3630
3631exports.merge = function merge(a, b) {
3632 if (arguments.length === 1) {
3633 var attrs = a[0];
3634 for (var i = 1; i < a.length; i++) {
3635 attrs = merge(attrs, a[i]);
3636 }
3637 return attrs;
3638 }
3639 var ac = a['class'];
3640 var bc = b['class'];
3641
3642 if (ac || bc) {
3643 ac = ac || [];
3644 bc = bc || [];
3645 if (!Array.isArray(ac)) ac = [ac];
3646 if (!Array.isArray(bc)) bc = [bc];
3647 a['class'] = ac.concat(bc).filter(nulls);
3648 }
3649
3650 for (var key in b) {
3651 if (key != 'class') {
3652 a[key] = b[key];
3653 }
3654 }
3655
3656 return a;
3657};
3658
3659/**
3660 * Filter null `val`s.
3661 *
3662 * @param {*} val
3663 * @return {Boolean}
3664 * @api private
3665 */
3666
3667function nulls(val) {
3668 return val != null && val !== '';
3669}
3670
3671/**
3672 * join array as classes.
3673 *
3674 * @param {*} val
3675 * @return {String}
3676 */
3677exports.joinClasses = joinClasses;
3678function joinClasses(val) {
3679 return (Array.isArray(val) ? val.map(joinClasses) :
3680 (val && typeof val === 'object') ? Object.keys(val).filter(function (key) { return val[key]; }) :
3681 [val]).filter(nulls).join(' ');
3682}
3683
3684/**
3685 * Render the given classes.
3686 *
3687 * @param {Array} classes
3688 * @param {Array.<Boolean>} escaped
3689 * @return {String}
3690 */
3691exports.cls = function cls(classes, escaped) {
3692 var buf = [];
3693 for (var i = 0; i < classes.length; i++) {
3694 if (escaped && escaped[i]) {
3695 buf.push(exports.escape(joinClasses([classes[i]])));
3696 } else {
3697 buf.push(joinClasses(classes[i]));
3698 }
3699 }
3700 var text = joinClasses(buf);
3701 if (text.length) {
3702 return ' class="' + text + '"';
3703 } else {
3704 return '';
3705 }
3706};
3707
3708
3709exports.style = function (val) {
3710 if (val && typeof val === 'object') {
3711 return Object.keys(val).map(function (style) {
3712 return style + ':' + val[style];
3713 }).join(';');
3714 } else {
3715 return val;
3716 }
3717};
3718/**
3719 * Render the given attribute.
3720 *
3721 * @param {String} key
3722 * @param {String} val
3723 * @param {Boolean} escaped
3724 * @param {Boolean} terse
3725 * @return {String}
3726 */
3727exports.attr = function attr(key, val, escaped, terse) {
3728 if (key === 'style') {
3729 val = exports.style(val);
3730 }
3731 if ('boolean' == typeof val || null == val) {
3732 if (val) {
3733 return ' ' + (terse ? key : key + '="' + key + '"');
3734 } else {
3735 return '';
3736 }
3737 } else if (0 == key.indexOf('data') && 'string' != typeof val) {
3738 if (JSON.stringify(val).indexOf('&') !== -1) {
3739 console.warn('Since Jade 2.0.0, ampersands (`&`) in data attributes ' +
3740 'will be escaped to `&amp;`');
3741 };
3742 if (val && typeof val.toISOString === 'function') {
3743 console.warn('Jade will eliminate the double quotes around dates in ' +
3744 'ISO form after 2.0.0');
3745 }
3746 return ' ' + key + "='" + JSON.stringify(val).replace(/'/g, '&apos;') + "'";
3747 } else if (escaped) {
3748 if (val && typeof val.toISOString === 'function') {
3749 console.warn('Jade will stringify dates in ISO form after 2.0.0');
3750 }
3751 return ' ' + key + '="' + exports.escape(val) + '"';
3752 } else {
3753 if (val && typeof val.toISOString === 'function') {
3754 console.warn('Jade will stringify dates in ISO form after 2.0.0');
3755 }
3756 return ' ' + key + '="' + val + '"';
3757 }
3758};
3759
3760/**
3761 * Render the given attributes object.
3762 *
3763 * @param {Object} obj
3764 * @param {Object} escaped
3765 * @return {String}
3766 */
3767exports.attrs = function attrs(obj, terse){
3768 var buf = [];
3769
3770 var keys = Object.keys(obj);
3771
3772 if (keys.length) {
3773 for (var i = 0; i < keys.length; ++i) {
3774 var key = keys[i]
3775 , val = obj[key];
3776
3777 if ('class' == key) {
3778 if (val = joinClasses(val)) {
3779 buf.push(' ' + key + '="' + val + '"');
3780 }
3781 } else {
3782 buf.push(exports.attr(key, val, false, terse));
3783 }
3784 }
3785 }
3786
3787 return buf.join('');
3788};
3789
3790/**
3791 * Escape the given string of `html`.
3792 *
3793 * @param {String} html
3794 * @return {String}
3795 * @api private
3796 */
3797
3798var jade_encode_html_rules = {
3799 '&': '&amp;',
3800 '<': '&lt;',
3801 '>': '&gt;',
3802 '"': '&quot;'
3803};
3804var jade_match_html = /[&<>"]/g;
3805
3806function jade_encode_char(c) {
3807 return jade_encode_html_rules[c] || c;
3808}
3809
3810exports.escape = jade_escape;
3811function jade_escape(html){
3812 var result = String(html).replace(jade_match_html, jade_encode_char);
3813 if (result === '' + html) return html;
3814 else return result;
3815};
3816
3817/**
3818 * Re-throw the given `err` in context to the
3819 * the jade in `filename` at the given `lineno`.
3820 *
3821 * @param {Error} err
3822 * @param {String} filename
3823 * @param {String} lineno
3824 * @api private
3825 */
3826
3827exports.rethrow = function rethrow(err, filename, lineno, str){
3828 if (!(err instanceof Error)) throw err;
3829 if ((typeof window != 'undefined' || !filename) && !str) {
3830 err.message += ' on line ' + lineno;
3831 throw err;
3832 }
3833 try {
3834 str = str || require('fs').readFileSync(filename, 'utf8')
3835 } catch (ex) {
3836 rethrow(err, null, lineno)
3837 }
3838 var context = 3
3839 , lines = str.split('\n')
3840 , start = Math.max(lineno - context, 0)
3841 , end = Math.min(lines.length, lineno + context);
3842
3843 // Error context
3844 var context = lines.slice(start, end).map(function(line, i){
3845 var curr = i + start + 1;
3846 return (curr == lineno ? ' > ' : ' ')
3847 + curr
3848 + '| '
3849 + line;
3850 }).join('\n');
3851
3852 // Alter exception message
3853 err.path = filename;
3854 err.message = (filename || 'Jade') + ':' + lineno
3855 + '\n' + context + '\n\n' + err.message;
3856 throw err;
3857};
3858
3859exports.DebugItem = function DebugItem(lineno, filename) {
3860 this.lineno = lineno;
3861 this.filename = filename;
3862}
3863
3864},{"fs":26}],25:[function(require,module,exports){
3865'use strict';
3866
3867/**
3868 * Merge `b` into `a`.
3869 *
3870 * @param {Object} a
3871 * @param {Object} b
3872 * @return {Object}
3873 * @api public
3874 */
3875
3876exports.merge = function(a, b) {
3877 for (var key in b) a[key] = b[key];
3878 return a;
3879};
3880
3881exports.stringify = function(str) {
3882 return JSON.stringify(str)
3883 .replace(/\u2028/g, '\\u2028')
3884 .replace(/\u2029/g, '\\u2029');
3885};
3886
3887exports.walkAST = function walkAST(ast, before, after) {
3888 before && before(ast);
3889 switch (ast.type) {
3890 case 'Block':
3891 ast.nodes.forEach(function (node) {
3892 walkAST(node, before, after);
3893 });
3894 break;
3895 case 'Case':
3896 case 'Each':
3897 case 'Mixin':
3898 case 'Tag':
3899 case 'When':
3900 case 'Code':
3901 ast.block && walkAST(ast.block, before, after);
3902 break;
3903 case 'Attrs':
3904 case 'BlockComment':
3905 case 'Comment':
3906 case 'Doctype':
3907 case 'Filter':
3908 case 'Literal':
3909 case 'MixinBlock':
3910 case 'Text':
3911 break;
3912 default:
3913 throw new Error('Unexpected node type ' + ast.type);
3914 break;
3915 }
3916 after && after(ast);
3917};
3918
3919},{}],26:[function(require,module,exports){
3920
3921},{}],27:[function(require,module,exports){
3922(function (process){
3923// Copyright Joyent, Inc. and other Node contributors.
3924//
3925// Permission is hereby granted, free of charge, to any person obtaining a
3926// copy of this software and associated documentation files (the
3927// "Software"), to deal in the Software without restriction, including
3928// without limitation the rights to use, copy, modify, merge, publish,
3929// distribute, sublicense, and/or sell copies of the Software, and to permit
3930// persons to whom the Software is furnished to do so, subject to the
3931// following conditions:
3932//
3933// The above copyright notice and this permission notice shall be included
3934// in all copies or substantial portions of the Software.
3935//
3936// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
3937// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
3938// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
3939// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
3940// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
3941// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
3942// USE OR OTHER DEALINGS IN THE SOFTWARE.
3943
3944// resolves . and .. elements in a path array with directory names there
3945// must be no slashes, empty elements, or device names (c:\) in the array
3946// (so also no leading and trailing slashes - it does not distinguish
3947// relative and absolute paths)
3948function normalizeArray(parts, allowAboveRoot) {
3949 // if the path tries to go above the root, `up` ends up > 0
3950 var up = 0;
3951 for (var i = parts.length - 1; i >= 0; i--) {
3952 var last = parts[i];
3953 if (last === '.') {
3954 parts.splice(i, 1);
3955 } else if (last === '..') {
3956 parts.splice(i, 1);
3957 up++;
3958 } else if (up) {
3959 parts.splice(i, 1);
3960 up--;
3961 }
3962 }
3963
3964 // if the path is allowed to go above the root, restore leading ..s
3965 if (allowAboveRoot) {
3966 for (; up--; up) {
3967 parts.unshift('..');
3968 }
3969 }
3970
3971 return parts;
3972}
3973
3974// Split a filename into [root, dir, basename, ext], unix version
3975// 'root' is just a slash, or nothing.
3976var splitPathRe =
3977 /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;
3978var splitPath = function(filename) {
3979 return splitPathRe.exec(filename).slice(1);
3980};
3981
3982// path.resolve([from ...], to)
3983// posix version
3984exports.resolve = function() {
3985 var resolvedPath = '',
3986 resolvedAbsolute = false;
3987
3988 for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) {
3989 var path = (i >= 0) ? arguments[i] : process.cwd();
3990
3991 // Skip empty and invalid entries
3992 if (typeof path !== 'string') {
3993 throw new TypeError('Arguments to path.resolve must be strings');
3994 } else if (!path) {
3995 continue;
3996 }
3997
3998 resolvedPath = path + '/' + resolvedPath;
3999 resolvedAbsolute = path.charAt(0) === '/';
4000 }
4001
4002 // At this point the path should be resolved to a full absolute path, but
4003 // handle relative paths to be safe (might happen when process.cwd() fails)
4004
4005 // Normalize the path
4006 resolvedPath = normalizeArray(filter(resolvedPath.split('/'), function(p) {
4007 return !!p;
4008 }), !resolvedAbsolute).join('/');
4009
4010 return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.';
4011};
4012
4013// path.normalize(path)
4014// posix version
4015exports.normalize = function(path) {
4016 var isAbsolute = exports.isAbsolute(path),
4017 trailingSlash = substr(path, -1) === '/';
4018
4019 // Normalize the path
4020 path = normalizeArray(filter(path.split('/'), function(p) {
4021 return !!p;
4022 }), !isAbsolute).join('/');
4023
4024 if (!path && !isAbsolute) {
4025 path = '.';
4026 }
4027 if (path && trailingSlash) {
4028 path += '/';
4029 }
4030
4031 return (isAbsolute ? '/' : '') + path;
4032};
4033
4034// posix version
4035exports.isAbsolute = function(path) {
4036 return path.charAt(0) === '/';
4037};
4038
4039// posix version
4040exports.join = function() {
4041 var paths = Array.prototype.slice.call(arguments, 0);
4042 return exports.normalize(filter(paths, function(p, index) {
4043 if (typeof p !== 'string') {
4044 throw new TypeError('Arguments to path.join must be strings');
4045 }
4046 return p;
4047 }).join('/'));
4048};
4049
4050
4051// path.relative(from, to)
4052// posix version
4053exports.relative = function(from, to) {
4054 from = exports.resolve(from).substr(1);
4055 to = exports.resolve(to).substr(1);
4056
4057 function trim(arr) {
4058 var start = 0;
4059 for (; start < arr.length; start++) {
4060 if (arr[start] !== '') break;
4061 }
4062
4063 var end = arr.length - 1;
4064 for (; end >= 0; end--) {
4065 if (arr[end] !== '') break;
4066 }
4067
4068 if (start > end) return [];
4069 return arr.slice(start, end - start + 1);
4070 }
4071
4072 var fromParts = trim(from.split('/'));
4073 var toParts = trim(to.split('/'));
4074
4075 var length = Math.min(fromParts.length, toParts.length);
4076 var samePartsLength = length;
4077 for (var i = 0; i < length; i++) {
4078 if (fromParts[i] !== toParts[i]) {
4079 samePartsLength = i;
4080 break;
4081 }
4082 }
4083
4084 var outputParts = [];
4085 for (var i = samePartsLength; i < fromParts.length; i++) {
4086 outputParts.push('..');
4087 }
4088
4089 outputParts = outputParts.concat(toParts.slice(samePartsLength));
4090
4091 return outputParts.join('/');
4092};
4093
4094exports.sep = '/';
4095exports.delimiter = ':';
4096
4097exports.dirname = function(path) {
4098 var result = splitPath(path),
4099 root = result[0],
4100 dir = result[1];
4101
4102 if (!root && !dir) {
4103 // No dirname whatsoever
4104 return '.';
4105 }
4106
4107 if (dir) {
4108 // It has a dirname, strip trailing slash
4109 dir = dir.substr(0, dir.length - 1);
4110 }
4111
4112 return root + dir;
4113};
4114
4115
4116exports.basename = function(path, ext) {
4117 var f = splitPath(path)[2];
4118 // TODO: make this comparison case-insensitive on windows?
4119 if (ext && f.substr(-1 * ext.length) === ext) {
4120 f = f.substr(0, f.length - ext.length);
4121 }
4122 return f;
4123};
4124
4125
4126exports.extname = function(path) {
4127 return splitPath(path)[3];
4128};
4129
4130function filter (xs, f) {
4131 if (xs.filter) return xs.filter(f);
4132 var res = [];
4133 for (var i = 0; i < xs.length; i++) {
4134 if (f(xs[i], i, xs)) res.push(xs[i]);
4135 }
4136 return res;
4137}
4138
4139// String.prototype.substr - negative index don't work in IE8
4140var substr = 'ab'.substr(-1) === 'b'
4141 ? function (str, start, len) { return str.substr(start, len) }
4142 : function (str, start, len) {
4143 if (start < 0) start = str.length + start;
4144 return str.substr(start, len);
4145 }
4146;
4147
4148}).call(this,require('_process'))
4149},{"_process":28}],28:[function(require,module,exports){
4150// shim for using process in browser
4151
4152var process = module.exports = {};
4153var queue = [];
4154var draining = false;
4155var currentQueue;
4156var queueIndex = -1;
4157
4158function cleanUpNextTick() {
4159 draining = false;
4160 if (currentQueue.length) {
4161 queue = currentQueue.concat(queue);
4162 } else {
4163 queueIndex = -1;
4164 }
4165 if (queue.length) {
4166 drainQueue();
4167 }
4168}
4169
4170function drainQueue() {
4171 if (draining) {
4172 return;
4173 }
4174 var timeout = setTimeout(cleanUpNextTick);
4175 draining = true;
4176
4177 var len = queue.length;
4178 while(len) {
4179 currentQueue = queue;
4180 queue = [];
4181 while (++queueIndex < len) {
4182 currentQueue[queueIndex].run();
4183 }
4184 queueIndex = -1;
4185 len = queue.length;
4186 }
4187 currentQueue = null;
4188 draining = false;
4189 clearTimeout(timeout);
4190}
4191
4192process.nextTick = function (fun) {
4193 var args = new Array(arguments.length - 1);
4194 if (arguments.length > 1) {
4195 for (var i = 1; i < arguments.length; i++) {
4196 args[i - 1] = arguments[i];
4197 }
4198 }
4199 queue.push(new Item(fun, args));
4200 if (queue.length === 1 && !draining) {
4201 setTimeout(drainQueue, 0);
4202 }
4203};
4204
4205// v8 likes predictible objects
4206function Item(fun, array) {
4207 this.fun = fun;
4208 this.array = array;
4209}
4210Item.prototype.run = function () {
4211 this.fun.apply(null, this.array);
4212};
4213process.title = 'browser';
4214process.browser = true;
4215process.env = {};
4216process.argv = [];
4217process.version = ''; // empty string to avoid regexp issues
4218process.versions = {};
4219
4220function noop() {}
4221
4222process.on = noop;
4223process.addListener = noop;
4224process.once = noop;
4225process.off = noop;
4226process.removeListener = noop;
4227process.removeAllListeners = noop;
4228process.emit = noop;
4229
4230process.binding = function (name) {
4231 throw new Error('process.binding is not supported');
4232};
4233
4234// TODO(shtylman)
4235process.cwd = function () { return '/' };
4236process.chdir = function (dir) {
4237 throw new Error('process.chdir is not supported');
4238};
4239process.umask = function() { return 0; };
4240
4241},{}],29:[function(require,module,exports){
4242exports = (module.exports = parse);
4243exports.parse = parse;
4244function parse(src, state, options) {
4245 options = options || {};
4246 state = state || exports.defaultState();
4247 var start = options.start || 0;
4248 var end = options.end || src.length;
4249 var index = start;
4250 while (index < end) {
4251 if (state.roundDepth < 0 || state.curlyDepth < 0 || state.squareDepth < 0) {
4252 throw new SyntaxError('Mismatched Bracket: ' + src[index - 1]);
4253 }
4254 exports.parseChar(src[index++], state);
4255 }
4256 return state;
4257}
4258
4259exports.parseMax = parseMax;
4260function parseMax(src, options) {
4261 options = options || {};
4262 var start = options.start || 0;
4263 var index = start;
4264 var state = exports.defaultState();
4265 while (state.roundDepth >= 0 && state.curlyDepth >= 0 && state.squareDepth >= 0) {
4266 if (index >= src.length) {
4267 throw new Error('The end of the string was reached with no closing bracket found.');
4268 }
4269 exports.parseChar(src[index++], state);
4270 }
4271 var end = index - 1;
4272 return {
4273 start: start,
4274 end: end,
4275 src: src.substring(start, end)
4276 };
4277}
4278
4279exports.parseUntil = parseUntil;
4280function parseUntil(src, delimiter, options) {
4281 options = options || {};
4282 var includeLineComment = options.includeLineComment || false;
4283 var start = options.start || 0;
4284 var index = start;
4285 var state = exports.defaultState();
4286 while (state.isString() || state.regexp || state.blockComment ||
4287 (!includeLineComment && state.lineComment) || !startsWith(src, delimiter, index)) {
4288 exports.parseChar(src[index++], state);
4289 }
4290 var end = index;
4291 return {
4292 start: start,
4293 end: end,
4294 src: src.substring(start, end)
4295 };
4296}
4297
4298
4299exports.parseChar = parseChar;
4300function parseChar(character, state) {
4301 if (character.length !== 1) throw new Error('Character must be a string of length 1');
4302 state = state || exports.defaultState();
4303 state.src = state.src || '';
4304 state.src += character;
4305 var wasComment = state.blockComment || state.lineComment;
4306 var lastChar = state.history ? state.history[0] : '';
4307
4308 if (state.regexpStart) {
4309 if (character === '/' || character == '*') {
4310 state.regexp = false;
4311 }
4312 state.regexpStart = false;
4313 }
4314 if (state.lineComment) {
4315 if (character === '\n') {
4316 state.lineComment = false;
4317 }
4318 } else if (state.blockComment) {
4319 if (state.lastChar === '*' && character === '/') {
4320 state.blockComment = false;
4321 }
4322 } else if (state.singleQuote) {
4323 if (character === '\'' && !state.escaped) {
4324 state.singleQuote = false;
4325 } else if (character === '\\' && !state.escaped) {
4326 state.escaped = true;
4327 } else {
4328 state.escaped = false;
4329 }
4330 } else if (state.doubleQuote) {
4331 if (character === '"' && !state.escaped) {
4332 state.doubleQuote = false;
4333 } else if (character === '\\' && !state.escaped) {
4334 state.escaped = true;
4335 } else {
4336 state.escaped = false;
4337 }
4338 } else if (state.regexp) {
4339 if (character === '/' && !state.escaped) {
4340 state.regexp = false;
4341 } else if (character === '\\' && !state.escaped) {
4342 state.escaped = true;
4343 } else {
4344 state.escaped = false;
4345 }
4346 } else if (lastChar === '/' && character === '/') {
4347 state.history = state.history.substr(1);
4348 state.lineComment = true;
4349 } else if (lastChar === '/' && character === '*') {
4350 state.history = state.history.substr(1);
4351 state.blockComment = true;
4352 } else if (character === '/' && isRegexp(state.history)) {
4353 state.regexp = true;
4354 state.regexpStart = true;
4355 } else if (character === '\'') {
4356 state.singleQuote = true;
4357 } else if (character === '"') {
4358 state.doubleQuote = true;
4359 } else if (character === '(') {
4360 state.roundDepth++;
4361 } else if (character === ')') {
4362 state.roundDepth--;
4363 } else if (character === '{') {
4364 state.curlyDepth++;
4365 } else if (character === '}') {
4366 state.curlyDepth--;
4367 } else if (character === '[') {
4368 state.squareDepth++;
4369 } else if (character === ']') {
4370 state.squareDepth--;
4371 }
4372 if (!state.blockComment && !state.lineComment && !wasComment) state.history = character + state.history;
4373 state.lastChar = character; // store last character for ending block comments
4374 return state;
4375}
4376
4377exports.defaultState = function () { return new State() };
4378function State() {
4379 this.lineComment = false;
4380 this.blockComment = false;
4381
4382 this.singleQuote = false;
4383 this.doubleQuote = false;
4384 this.regexp = false;
4385
4386 this.escaped = false;
4387
4388 this.roundDepth = 0;
4389 this.curlyDepth = 0;
4390 this.squareDepth = 0;
4391
4392 this.history = ''
4393 this.lastChar = ''
4394}
4395State.prototype.isString = function () {
4396 return this.singleQuote || this.doubleQuote;
4397}
4398State.prototype.isComment = function () {
4399 return this.lineComment || this.blockComment;
4400}
4401State.prototype.isNesting = function () {
4402 return this.isString() || this.isComment() || this.regexp || this.roundDepth > 0 || this.curlyDepth > 0 || this.squareDepth > 0
4403}
4404
4405function startsWith(str, start, i) {
4406 return str.substr(i || 0, start.length) === start;
4407}
4408
4409exports.isPunctuator = isPunctuator
4410function isPunctuator(c) {
4411 if (!c) return true; // the start of a string is a punctuator
4412 var code = c.charCodeAt(0)
4413
4414 switch (code) {
4415 case 46: // . dot
4416 case 40: // ( open bracket
4417 case 41: // ) close bracket
4418 case 59: // ; semicolon
4419 case 44: // , comma
4420 case 123: // { open curly brace
4421 case 125: // } close curly brace
4422 case 91: // [
4423 case 93: // ]
4424 case 58: // :
4425 case 63: // ?
4426 case 126: // ~
4427 case 37: // %
4428 case 38: // &
4429 case 42: // *:
4430 case 43: // +
4431 case 45: // -
4432 case 47: // /
4433 case 60: // <
4434 case 62: // >
4435 case 94: // ^
4436 case 124: // |
4437 case 33: // !
4438 case 61: // =
4439 return true;
4440 default:
4441 return false;
4442 }
4443}
4444exports.isKeyword = isKeyword
4445function isKeyword(id) {
4446 return (id === 'if') || (id === 'in') || (id === 'do') || (id === 'var') || (id === 'for') || (id === 'new') ||
4447 (id === 'try') || (id === 'let') || (id === 'this') || (id === 'else') || (id === 'case') ||
4448 (id === 'void') || (id === 'with') || (id === 'enum') || (id === 'while') || (id === 'break') || (id === 'catch') ||
4449 (id === 'throw') || (id === 'const') || (id === 'yield') || (id === 'class') || (id === 'super') ||
4450 (id === 'return') || (id === 'typeof') || (id === 'delete') || (id === 'switch') || (id === 'export') ||
4451 (id === 'import') || (id === 'default') || (id === 'finally') || (id === 'extends') || (id === 'function') ||
4452 (id === 'continue') || (id === 'debugger') || (id === 'package') || (id === 'private') || (id === 'interface') ||
4453 (id === 'instanceof') || (id === 'implements') || (id === 'protected') || (id === 'public') || (id === 'static') ||
4454 (id === 'yield') || (id === 'let');
4455}
4456
4457function isRegexp(history) {
4458 //could be start of regexp or divide sign
4459
4460 history = history.replace(/^\s*/, '');
4461
4462 //unless its an `if`, `while`, `for` or `with` it's a divide, so we assume it's a divide
4463 if (history[0] === ')') return false;
4464 //unless it's a function expression, it's a regexp, so we assume it's a regexp
4465 if (history[0] === '}') return true;
4466 //any punctuation means it's a regexp
4467 if (isPunctuator(history[0])) return true;
4468 //if the last thing was a keyword then it must be a regexp (e.g. `typeof /foo/`)
4469 if (/^\w+\b/.test(history) && isKeyword(/^\w+\b/.exec(history)[0].split('').reverse().join(''))) return true;
4470
4471 return false;
4472}
4473
4474},{}],30:[function(require,module,exports){
4475'use strict'
4476
4477var detect = require('acorn-globals');
4478
4479var lastSRC = '(null)';
4480var lastRes = true;
4481var lastConstants = undefined;
4482
4483module.exports = isConstant;
4484function isConstant(src, constants) {
4485 src = '(' + src + ')';
4486 if (lastSRC === src && lastConstants === constants) return lastRes;
4487 lastSRC = src;
4488 lastConstants = constants;
4489 try {
4490 isExpression(src);
4491 return lastRes = (detect(src).filter(function (key) {
4492 return !constants || !(key.name in constants);
4493 }).length === 0);
4494 } catch (ex) {
4495 return lastRes = false;
4496 }
4497}
4498isConstant.isConstant = isConstant;
4499
4500isConstant.toConstant = toConstant;
4501function toConstant(src, constants) {
4502 if (!isConstant(src, constants)) throw new Error(JSON.stringify(src) + ' is not constant.');
4503 return Function(Object.keys(constants || {}).join(','), 'return (' + src + ')').apply(null, Object.keys(constants || {}).map(function (key) {
4504 return constants[key];
4505 }));
4506}
4507
4508function isExpression(src) {
4509 try {
4510 eval('throw "STOP"; (function () { return (' + src + '); })()');
4511 return false;
4512 }
4513 catch (err) {
4514 return err === 'STOP';
4515 }
4516}
4517
4518},{"acorn-globals":31}],31:[function(require,module,exports){
4519'use strict';
4520
4521var acorn = require('acorn');
4522var walk = require('acorn/dist/walk');
4523
4524// polyfill for https://github.com/marijnh/acorn/pull/231
4525walk.base.ExportNamedDeclaration = walk.base.ExportDefaultDeclaration = function (node, st, c) {
4526 return c(node.declaration, st);
4527};
4528walk.base.ImportDefaultSpecifier = walk.base.ImportNamespaceSpecifier = function () {};
4529
4530function isScope(node) {
4531 return node.type === 'FunctionExpression' || node.type === 'FunctionDeclaration' || node.type === 'Program';
4532}
4533function isBlockScope(node) {
4534 return node.type === 'BlockStatement' || isScope(node);
4535}
4536
4537function declaresArguments(node) {
4538 return node.type === 'FunctionExpression' || node.type === 'FunctionDeclaration' || node.type === 'ArrowFunction';
4539}
4540function declaresThis(node) {
4541 return node.type === 'FunctionExpression' || node.type === 'FunctionDeclaration';
4542}
4543
4544function reallyParse(source) {
4545 try {
4546 return acorn.parse(source, {
4547 ecmaVersion: 6,
4548 allowReturnOutsideFunction: true,
4549 sourceType: 'module'
4550 });
4551 } catch (ex) {
4552 if (ex.name !== 'SyntaxError') {
4553 throw ex;
4554 }
4555 try {
4556 return acorn.parse(source, {
4557 ecmaVersion: 6,
4558 allowReturnOutsideFunction: true
4559 });
4560 } catch (ex) {
4561 if (ex.name !== 'SyntaxError') {
4562 throw ex;
4563 }
4564 return acorn.parse(source, {
4565 ecmaVersion: 5,
4566 allowReturnOutsideFunction: true
4567 });
4568 }
4569 }
4570}
4571module.exports = findGlobals;
4572module.exports.parse = reallyParse;
4573function findGlobals(source) {
4574 var globals = [];
4575 var ast = typeof source === 'string' ?
4576 ast = reallyParse(source) :
4577 source;
4578 if (!(ast && typeof ast === 'object' && ast.type === 'Program')) {
4579 throw new TypeError('Source must be either a string of JavaScript or an acorn AST');
4580 }
4581 var declareFunction = function (node) {
4582 var fn = node;
4583 fn.locals = fn.locals || {};
4584 node.params.forEach(function (node) {
4585 fn.locals[node.name] = true;
4586 });
4587 if (node.id) {
4588 fn.locals[node.id.name] = true;
4589 }
4590 }
4591 walk.ancestor(ast, {
4592 'VariableDeclaration': function (node, parents) {
4593 var parent = null;
4594 for (var i = parents.length - 1; i >= 0 && parent === null; i--) {
4595 if (node.kind === 'var' ? isScope(parents[i]) : isBlockScope(parents[i])) {
4596 parent = parents[i];
4597 }
4598 }
4599 parent.locals = parent.locals || {};
4600 node.declarations.forEach(function (declaration) {
4601 parent.locals[declaration.id.name] = true;
4602 });
4603 },
4604 'FunctionDeclaration': function (node, parents) {
4605 var parent = null;
4606 for (var i = parents.length - 2; i >= 0 && parent === null; i--) {
4607 if (isScope(parents[i])) {
4608 parent = parents[i];
4609 }
4610 }
4611 parent.locals = parent.locals || {};
4612 parent.locals[node.id.name] = true;
4613 declareFunction(node);
4614 },
4615 'Function': declareFunction,
4616 'TryStatement': function (node) {
4617 node.handler.body.locals = node.handler.body.locals || {};
4618 node.handler.body.locals[node.handler.param.name] = true;
4619 },
4620 'ImportDefaultSpecifier': function (node) {
4621 if (node.local.type === 'Identifier') {
4622 ast.locals = ast.locals || {};
4623 ast.locals[node.local.name] = true;
4624 }
4625 },
4626 'ImportSpecifier': function (node) {
4627 var id = node.local ? node.local : node.imported;
4628 if (id.type === 'Identifier') {
4629 ast.locals = ast.locals || {};
4630 ast.locals[id.name] = true;
4631 }
4632 },
4633 'ImportNamespaceSpecifier': function (node) {
4634 if (node.local.type === 'Identifier') {
4635 ast.locals = ast.locals || {};
4636 ast.locals[node.local.name] = true;
4637 }
4638 }
4639 });
4640 walk.ancestor(ast, {
4641 'Identifier': function (node, parents) {
4642 var name = node.name;
4643 if (name === 'undefined') return;
4644 for (var i = 0; i < parents.length; i++) {
4645 if (name === 'arguments' && declaresArguments(parents[i])) {
4646 return;
4647 }
4648 if (parents[i].locals && name in parents[i].locals) {
4649 return;
4650 }
4651 }
4652 node.parents = parents;
4653 globals.push(node);
4654 },
4655 ThisExpression: function (node, parents) {
4656 for (var i = 0; i < parents.length; i++) {
4657 if (declaresThis(parents[i])) {
4658 return;
4659 }
4660 }
4661 node.parents = parents;
4662 globals.push(node);
4663 }
4664 });
4665 var groupedGlobals = {};
4666 globals.forEach(function (node) {
4667 groupedGlobals[node.name] = (groupedGlobals[node.name] || []);
4668 groupedGlobals[node.name].push(node);
4669 });
4670 return Object.keys(groupedGlobals).sort().map(function (name) {
4671 return {name: name, nodes: groupedGlobals[name]};
4672 });
4673}
4674
4675},{"acorn":32,"acorn/dist/walk":33}],32:[function(require,module,exports){
4676(function (global){
4677(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.acorn = 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){
4678
4679
4680// The main exported interface (under `self.acorn` when in the
4681// browser) is a `parse` function that takes a code string and
4682// returns an abstract syntax tree as specified by [Mozilla parser
4683// API][api].
4684//
4685// [api]: https://developer.mozilla.org/en-US/docs/SpiderMonkey/Parser_API
4686
4687"use strict";
4688
4689exports.parse = parse;
4690
4691// This function tries to parse a single expression at a given
4692// offset in a string. Useful for parsing mixed-language formats
4693// that embed JavaScript expressions.
4694
4695exports.parseExpressionAt = parseExpressionAt;
4696
4697// Acorn is organized as a tokenizer and a recursive-descent parser.
4698// The `tokenize` export provides an interface to the tokenizer.
4699
4700exports.tokenizer = tokenizer;
4701exports.__esModule = true;
4702// Acorn is a tiny, fast JavaScript parser written in JavaScript.
4703//
4704// Acorn was written by Marijn Haverbeke, Ingvar Stepanyan, and
4705// various contributors and released under an MIT license.
4706//
4707// Git repositories for Acorn are available at
4708//
4709// http://marijnhaverbeke.nl/git/acorn
4710// https://github.com/marijnh/acorn.git
4711//
4712// Please use the [github bug tracker][ghbt] to report issues.
4713//
4714// [ghbt]: https://github.com/marijnh/acorn/issues
4715//
4716// This file defines the main parser interface. The library also comes
4717// with a [error-tolerant parser][dammit] and an
4718// [abstract syntax tree walker][walk], defined in other files.
4719//
4720// [dammit]: acorn_loose.js
4721// [walk]: util/walk.js
4722
4723var _state = _dereq_("./state");
4724
4725var Parser = _state.Parser;
4726
4727var _options = _dereq_("./options");
4728
4729var getOptions = _options.getOptions;
4730
4731_dereq_("./parseutil");
4732
4733_dereq_("./statement");
4734
4735_dereq_("./lval");
4736
4737_dereq_("./expression");
4738
4739exports.Parser = _state.Parser;
4740exports.plugins = _state.plugins;
4741exports.defaultOptions = _options.defaultOptions;
4742
4743var _location = _dereq_("./location");
4744
4745exports.SourceLocation = _location.SourceLocation;
4746exports.getLineInfo = _location.getLineInfo;
4747exports.Node = _dereq_("./node").Node;
4748
4749var _tokentype = _dereq_("./tokentype");
4750
4751exports.TokenType = _tokentype.TokenType;
4752exports.tokTypes = _tokentype.types;
4753
4754var _tokencontext = _dereq_("./tokencontext");
4755
4756exports.TokContext = _tokencontext.TokContext;
4757exports.tokContexts = _tokencontext.types;
4758
4759var _identifier = _dereq_("./identifier");
4760
4761exports.isIdentifierChar = _identifier.isIdentifierChar;
4762exports.isIdentifierStart = _identifier.isIdentifierStart;
4763exports.Token = _dereq_("./tokenize").Token;
4764
4765var _whitespace = _dereq_("./whitespace");
4766
4767exports.isNewLine = _whitespace.isNewLine;
4768exports.lineBreak = _whitespace.lineBreak;
4769exports.lineBreakG = _whitespace.lineBreakG;
4770var version = "1.2.2";exports.version = version;
4771
4772function parse(input, options) {
4773 var p = parser(options, input);
4774 var startPos = p.pos,
4775 startLoc = p.options.locations && p.curPosition();
4776 p.nextToken();
4777 return p.parseTopLevel(p.options.program || p.startNodeAt(startPos, startLoc));
4778}
4779
4780function parseExpressionAt(input, pos, options) {
4781 var p = parser(options, input, pos);
4782 p.nextToken();
4783 return p.parseExpression();
4784}
4785
4786function tokenizer(input, options) {
4787 return parser(options, input);
4788}
4789
4790function parser(options, input) {
4791 return new Parser(getOptions(options), String(input));
4792}
4793
4794},{"./expression":6,"./identifier":7,"./location":8,"./lval":9,"./node":10,"./options":11,"./parseutil":12,"./state":13,"./statement":14,"./tokencontext":15,"./tokenize":16,"./tokentype":17,"./whitespace":19}],2:[function(_dereq_,module,exports){
4795if (typeof Object.create === 'function') {
4796 // implementation from standard node.js 'util' module
4797 module.exports = function inherits(ctor, superCtor) {
4798 ctor.super_ = superCtor
4799 ctor.prototype = Object.create(superCtor.prototype, {
4800 constructor: {
4801 value: ctor,
4802 enumerable: false,
4803 writable: true,
4804 configurable: true
4805 }
4806 });
4807 };
4808} else {
4809 // old school shim for old browsers
4810 module.exports = function inherits(ctor, superCtor) {
4811 ctor.super_ = superCtor
4812 var TempCtor = function () {}
4813 TempCtor.prototype = superCtor.prototype
4814 ctor.prototype = new TempCtor()
4815 ctor.prototype.constructor = ctor
4816 }
4817}
4818
4819},{}],3:[function(_dereq_,module,exports){
4820// shim for using process in browser
4821
4822var process = module.exports = {};
4823var queue = [];
4824var draining = false;
4825
4826function drainQueue() {
4827 if (draining) {
4828 return;
4829 }
4830 draining = true;
4831 var currentQueue;
4832 var len = queue.length;
4833 while(len) {
4834 currentQueue = queue;
4835 queue = [];
4836 var i = -1;
4837 while (++i < len) {
4838 currentQueue[i]();
4839 }
4840 len = queue.length;
4841 }
4842 draining = false;
4843}
4844process.nextTick = function (fun) {
4845 queue.push(fun);
4846 if (!draining) {
4847 setTimeout(drainQueue, 0);
4848 }
4849};
4850
4851process.title = 'browser';
4852process.browser = true;
4853process.env = {};
4854process.argv = [];
4855process.version = ''; // empty string to avoid regexp issues
4856process.versions = {};
4857
4858function noop() {}
4859
4860process.on = noop;
4861process.addListener = noop;
4862process.once = noop;
4863process.off = noop;
4864process.removeListener = noop;
4865process.removeAllListeners = noop;
4866process.emit = noop;
4867
4868process.binding = function (name) {
4869 throw new Error('process.binding is not supported');
4870};
4871
4872// TODO(shtylman)
4873process.cwd = function () { return '/' };
4874process.chdir = function (dir) {
4875 throw new Error('process.chdir is not supported');
4876};
4877process.umask = function() { return 0; };
4878
4879},{}],4:[function(_dereq_,module,exports){
4880module.exports = function isBuffer(arg) {
4881 return arg && typeof arg === 'object'
4882 && typeof arg.copy === 'function'
4883 && typeof arg.fill === 'function'
4884 && typeof arg.readUInt8 === 'function';
4885}
4886},{}],5:[function(_dereq_,module,exports){
4887(function (process,global){
4888// Copyright Joyent, Inc. and other Node contributors.
4889//
4890// Permission is hereby granted, free of charge, to any person obtaining a
4891// copy of this software and associated documentation files (the
4892// "Software"), to deal in the Software without restriction, including
4893// without limitation the rights to use, copy, modify, merge, publish,
4894// distribute, sublicense, and/or sell copies of the Software, and to permit
4895// persons to whom the Software is furnished to do so, subject to the
4896// following conditions:
4897//
4898// The above copyright notice and this permission notice shall be included
4899// in all copies or substantial portions of the Software.
4900//
4901// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
4902// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
4903// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
4904// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
4905// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
4906// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
4907// USE OR OTHER DEALINGS IN THE SOFTWARE.
4908
4909var formatRegExp = /%[sdj%]/g;
4910exports.format = function(f) {
4911 if (!isString(f)) {
4912 var objects = [];
4913 for (var i = 0; i < arguments.length; i++) {
4914 objects.push(inspect(arguments[i]));
4915 }
4916 return objects.join(' ');
4917 }
4918
4919 var i = 1;
4920 var args = arguments;
4921 var len = args.length;
4922 var str = String(f).replace(formatRegExp, function(x) {
4923 if (x === '%%') return '%';
4924 if (i >= len) return x;
4925 switch (x) {
4926 case '%s': return String(args[i++]);
4927 case '%d': return Number(args[i++]);
4928 case '%j':
4929 try {
4930 return JSON.stringify(args[i++]);
4931 } catch (_) {
4932 return '[Circular]';
4933 }
4934 default:
4935 return x;
4936 }
4937 });
4938 for (var x = args[i]; i < len; x = args[++i]) {
4939 if (isNull(x) || !isObject(x)) {
4940 str += ' ' + x;
4941 } else {
4942 str += ' ' + inspect(x);
4943 }
4944 }
4945 return str;
4946};
4947
4948
4949// Mark that a method should not be used.
4950// Returns a modified function which warns once by default.
4951// If --no-deprecation is set, then it is a no-op.
4952exports.deprecate = function(fn, msg) {
4953 // Allow for deprecating things in the process of starting up.
4954 if (isUndefined(global.process)) {
4955 return function() {
4956 return exports.deprecate(fn, msg).apply(this, arguments);
4957 };
4958 }
4959
4960 if (process.noDeprecation === true) {
4961 return fn;
4962 }
4963
4964 var warned = false;
4965 function deprecated() {
4966 if (!warned) {
4967 if (process.throwDeprecation) {
4968 throw new Error(msg);
4969 } else if (process.traceDeprecation) {
4970 console.trace(msg);
4971 } else {
4972 console.error(msg);
4973 }
4974 warned = true;
4975 }
4976 return fn.apply(this, arguments);
4977 }
4978
4979 return deprecated;
4980};
4981
4982
4983var debugs = {};
4984var debugEnviron;
4985exports.debuglog = function(set) {
4986 if (isUndefined(debugEnviron))
4987 debugEnviron = process.env.NODE_DEBUG || '';
4988 set = set.toUpperCase();
4989 if (!debugs[set]) {
4990 if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) {
4991 var pid = process.pid;
4992 debugs[set] = function() {
4993 var msg = exports.format.apply(exports, arguments);
4994 console.error('%s %d: %s', set, pid, msg);
4995 };
4996 } else {
4997 debugs[set] = function() {};
4998 }
4999 }
5000 return debugs[set];
5001};
5002
5003
5004/**
5005 * Echos the value of a value. Trys to print the value out
5006 * in the best way possible given the different types.
5007 *
5008 * @param {Object} obj The object to print out.
5009 * @param {Object} opts Optional options object that alters the output.
5010 */
5011/* legacy: obj, showHidden, depth, colors*/
5012function inspect(obj, opts) {
5013 // default options
5014 var ctx = {
5015 seen: [],
5016 stylize: stylizeNoColor
5017 };
5018 // legacy...
5019 if (arguments.length >= 3) ctx.depth = arguments[2];
5020 if (arguments.length >= 4) ctx.colors = arguments[3];
5021 if (isBoolean(opts)) {
5022 // legacy...
5023 ctx.showHidden = opts;
5024 } else if (opts) {
5025 // got an "options" object
5026 exports._extend(ctx, opts);
5027 }
5028 // set default options
5029 if (isUndefined(ctx.showHidden)) ctx.showHidden = false;
5030 if (isUndefined(ctx.depth)) ctx.depth = 2;
5031 if (isUndefined(ctx.colors)) ctx.colors = false;
5032 if (isUndefined(ctx.customInspect)) ctx.customInspect = true;
5033 if (ctx.colors) ctx.stylize = stylizeWithColor;
5034 return formatValue(ctx, obj, ctx.depth);
5035}
5036exports.inspect = inspect;
5037
5038
5039// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics
5040inspect.colors = {
5041 'bold' : [1, 22],
5042 'italic' : [3, 23],
5043 'underline' : [4, 24],
5044 'inverse' : [7, 27],
5045 'white' : [37, 39],
5046 'grey' : [90, 39],
5047 'black' : [30, 39],
5048 'blue' : [34, 39],
5049 'cyan' : [36, 39],
5050 'green' : [32, 39],
5051 'magenta' : [35, 39],
5052 'red' : [31, 39],
5053 'yellow' : [33, 39]
5054};
5055
5056// Don't use 'blue' not visible on cmd.exe
5057inspect.styles = {
5058 'special': 'cyan',
5059 'number': 'yellow',
5060 'boolean': 'yellow',
5061 'undefined': 'grey',
5062 'null': 'bold',
5063 'string': 'green',
5064 'date': 'magenta',
5065 // "name": intentionally not styling
5066 'regexp': 'red'
5067};
5068
5069
5070function stylizeWithColor(str, styleType) {
5071 var style = inspect.styles[styleType];
5072
5073 if (style) {
5074 return '\u001b[' + inspect.colors[style][0] + 'm' + str +
5075 '\u001b[' + inspect.colors[style][1] + 'm';
5076 } else {
5077 return str;
5078 }
5079}
5080
5081
5082function stylizeNoColor(str, styleType) {
5083 return str;
5084}
5085
5086
5087function arrayToHash(array) {
5088 var hash = {};
5089
5090 array.forEach(function(val, idx) {
5091 hash[val] = true;
5092 });
5093
5094 return hash;
5095}
5096
5097
5098function formatValue(ctx, value, recurseTimes) {
5099 // Provide a hook for user-specified inspect functions.
5100 // Check that value is an object with an inspect function on it
5101 if (ctx.customInspect &&
5102 value &&
5103 isFunction(value.inspect) &&
5104 // Filter out the util module, it's inspect function is special
5105 value.inspect !== exports.inspect &&
5106 // Also filter out any prototype objects using the circular check.
5107 !(value.constructor && value.constructor.prototype === value)) {
5108 var ret = value.inspect(recurseTimes, ctx);
5109 if (!isString(ret)) {
5110 ret = formatValue(ctx, ret, recurseTimes);
5111 }
5112 return ret;
5113 }
5114
5115 // Primitive types cannot have properties
5116 var primitive = formatPrimitive(ctx, value);
5117 if (primitive) {
5118 return primitive;
5119 }
5120
5121 // Look up the keys of the object.
5122 var keys = Object.keys(value);
5123 var visibleKeys = arrayToHash(keys);
5124
5125 if (ctx.showHidden) {
5126 keys = Object.getOwnPropertyNames(value);
5127 }
5128
5129 // IE doesn't make error fields non-enumerable
5130 // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx
5131 if (isError(value)
5132 && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) {
5133 return formatError(value);
5134 }
5135
5136 // Some type of object without properties can be shortcutted.
5137 if (keys.length === 0) {
5138 if (isFunction(value)) {
5139 var name = value.name ? ': ' + value.name : '';
5140 return ctx.stylize('[Function' + name + ']', 'special');
5141 }
5142 if (isRegExp(value)) {
5143 return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
5144 }
5145 if (isDate(value)) {
5146 return ctx.stylize(Date.prototype.toString.call(value), 'date');
5147 }
5148 if (isError(value)) {
5149 return formatError(value);
5150 }
5151 }
5152
5153 var base = '', array = false, braces = ['{', '}'];
5154
5155 // Make Array say that they are Array
5156 if (isArray(value)) {
5157 array = true;
5158 braces = ['[', ']'];
5159 }
5160
5161 // Make functions say that they are functions
5162 if (isFunction(value)) {
5163 var n = value.name ? ': ' + value.name : '';
5164 base = ' [Function' + n + ']';
5165 }
5166
5167 // Make RegExps say that they are RegExps
5168 if (isRegExp(value)) {
5169 base = ' ' + RegExp.prototype.toString.call(value);
5170 }
5171
5172 // Make dates with properties first say the date
5173 if (isDate(value)) {
5174 base = ' ' + Date.prototype.toUTCString.call(value);
5175 }
5176
5177 // Make error with message first say the error
5178 if (isError(value)) {
5179 base = ' ' + formatError(value);
5180 }
5181
5182 if (keys.length === 0 && (!array || value.length == 0)) {
5183 return braces[0] + base + braces[1];
5184 }
5185
5186 if (recurseTimes < 0) {
5187 if (isRegExp(value)) {
5188 return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
5189 } else {
5190 return ctx.stylize('[Object]', 'special');
5191 }
5192 }
5193
5194 ctx.seen.push(value);
5195
5196 var output;
5197 if (array) {
5198 output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);
5199 } else {
5200 output = keys.map(function(key) {
5201 return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);
5202 });
5203 }
5204
5205 ctx.seen.pop();
5206
5207 return reduceToSingleString(output, base, braces);
5208}
5209
5210
5211function formatPrimitive(ctx, value) {
5212 if (isUndefined(value))
5213 return ctx.stylize('undefined', 'undefined');
5214 if (isString(value)) {
5215 var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '')
5216 .replace(/'/g, "\\'")
5217 .replace(/\\"/g, '"') + '\'';
5218 return ctx.stylize(simple, 'string');
5219 }
5220 if (isNumber(value))
5221 return ctx.stylize('' + value, 'number');
5222 if (isBoolean(value))
5223 return ctx.stylize('' + value, 'boolean');
5224 // For some reason typeof null is "object", so special case here.
5225 if (isNull(value))
5226 return ctx.stylize('null', 'null');
5227}
5228
5229
5230function formatError(value) {
5231 return '[' + Error.prototype.toString.call(value) + ']';
5232}
5233
5234
5235function formatArray(ctx, value, recurseTimes, visibleKeys, keys) {
5236 var output = [];
5237 for (var i = 0, l = value.length; i < l; ++i) {
5238 if (hasOwnProperty(value, String(i))) {
5239 output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
5240 String(i), true));
5241 } else {
5242 output.push('');
5243 }
5244 }
5245 keys.forEach(function(key) {
5246 if (!key.match(/^\d+$/)) {
5247 output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
5248 key, true));
5249 }
5250 });
5251 return output;
5252}
5253
5254
5255function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {
5256 var name, str, desc;
5257 desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] };
5258 if (desc.get) {
5259 if (desc.set) {
5260 str = ctx.stylize('[Getter/Setter]', 'special');
5261 } else {
5262 str = ctx.stylize('[Getter]', 'special');
5263 }
5264 } else {
5265 if (desc.set) {
5266 str = ctx.stylize('[Setter]', 'special');
5267 }
5268 }
5269 if (!hasOwnProperty(visibleKeys, key)) {
5270 name = '[' + key + ']';
5271 }
5272 if (!str) {
5273 if (ctx.seen.indexOf(desc.value) < 0) {
5274 if (isNull(recurseTimes)) {
5275 str = formatValue(ctx, desc.value, null);
5276 } else {
5277 str = formatValue(ctx, desc.value, recurseTimes - 1);
5278 }
5279 if (str.indexOf('\n') > -1) {
5280 if (array) {
5281 str = str.split('\n').map(function(line) {
5282 return ' ' + line;
5283 }).join('\n').substr(2);
5284 } else {
5285 str = '\n' + str.split('\n').map(function(line) {
5286 return ' ' + line;
5287 }).join('\n');
5288 }
5289 }
5290 } else {
5291 str = ctx.stylize('[Circular]', 'special');
5292 }
5293 }
5294 if (isUndefined(name)) {
5295 if (array && key.match(/^\d+$/)) {
5296 return str;
5297 }
5298 name = JSON.stringify('' + key);
5299 if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) {
5300 name = name.substr(1, name.length - 2);
5301 name = ctx.stylize(name, 'name');
5302 } else {
5303 name = name.replace(/'/g, "\\'")
5304 .replace(/\\"/g, '"')
5305 .replace(/(^"|"$)/g, "'");
5306 name = ctx.stylize(name, 'string');
5307 }
5308 }
5309
5310 return name + ': ' + str;
5311}
5312
5313
5314function reduceToSingleString(output, base, braces) {
5315 var numLinesEst = 0;
5316 var length = output.reduce(function(prev, cur) {
5317 numLinesEst++;
5318 if (cur.indexOf('\n') >= 0) numLinesEst++;
5319 return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1;
5320 }, 0);
5321
5322 if (length > 60) {
5323 return braces[0] +
5324 (base === '' ? '' : base + '\n ') +
5325 ' ' +
5326 output.join(',\n ') +
5327 ' ' +
5328 braces[1];
5329 }
5330
5331 return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];
5332}
5333
5334
5335// NOTE: These type checking functions intentionally don't use `instanceof`
5336// because it is fragile and can be easily faked with `Object.create()`.
5337function isArray(ar) {
5338 return Array.isArray(ar);
5339}
5340exports.isArray = isArray;
5341
5342function isBoolean(arg) {
5343 return typeof arg === 'boolean';
5344}
5345exports.isBoolean = isBoolean;
5346
5347function isNull(arg) {
5348 return arg === null;
5349}
5350exports.isNull = isNull;
5351
5352function isNullOrUndefined(arg) {
5353 return arg == null;
5354}
5355exports.isNullOrUndefined = isNullOrUndefined;
5356
5357function isNumber(arg) {
5358 return typeof arg === 'number';
5359}
5360exports.isNumber = isNumber;
5361
5362function isString(arg) {
5363 return typeof arg === 'string';
5364}
5365exports.isString = isString;
5366
5367function isSymbol(arg) {
5368 return typeof arg === 'symbol';
5369}
5370exports.isSymbol = isSymbol;
5371
5372function isUndefined(arg) {
5373 return arg === void 0;
5374}
5375exports.isUndefined = isUndefined;
5376
5377function isRegExp(re) {
5378 return isObject(re) && objectToString(re) === '[object RegExp]';
5379}
5380exports.isRegExp = isRegExp;
5381
5382function isObject(arg) {
5383 return typeof arg === 'object' && arg !== null;
5384}
5385exports.isObject = isObject;
5386
5387function isDate(d) {
5388 return isObject(d) && objectToString(d) === '[object Date]';
5389}
5390exports.isDate = isDate;
5391
5392function isError(e) {
5393 return isObject(e) &&
5394 (objectToString(e) === '[object Error]' || e instanceof Error);
5395}
5396exports.isError = isError;
5397
5398function isFunction(arg) {
5399 return typeof arg === 'function';
5400}
5401exports.isFunction = isFunction;
5402
5403function isPrimitive(arg) {
5404 return arg === null ||
5405 typeof arg === 'boolean' ||
5406 typeof arg === 'number' ||
5407 typeof arg === 'string' ||
5408 typeof arg === 'symbol' || // ES6 symbol
5409 typeof arg === 'undefined';
5410}
5411exports.isPrimitive = isPrimitive;
5412
5413exports.isBuffer = _dereq_('./support/isBuffer');
5414
5415function objectToString(o) {
5416 return Object.prototype.toString.call(o);
5417}
5418
5419
5420function pad(n) {
5421 return n < 10 ? '0' + n.toString(10) : n.toString(10);
5422}
5423
5424
5425var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep',
5426 'Oct', 'Nov', 'Dec'];
5427
5428// 26 Feb 16:19:34
5429function timestamp() {
5430 var d = new Date();
5431 var time = [pad(d.getHours()),
5432 pad(d.getMinutes()),
5433 pad(d.getSeconds())].join(':');
5434 return [d.getDate(), months[d.getMonth()], time].join(' ');
5435}
5436
5437
5438// log is just a thin wrapper to console.log that prepends a timestamp
5439exports.log = function() {
5440 console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments));
5441};
5442
5443
5444/**
5445 * Inherit the prototype methods from one constructor into another.
5446 *
5447 * The Function.prototype.inherits from lang.js rewritten as a standalone
5448 * function (not on Function.prototype). NOTE: If this file is to be loaded
5449 * during bootstrapping this function needs to be rewritten using some native
5450 * functions as prototype setup using normal JavaScript does not work as
5451 * expected during bootstrapping (see mirror.js in r114903).
5452 *
5453 * @param {function} ctor Constructor function which needs to inherit the
5454 * prototype.
5455 * @param {function} superCtor Constructor function to inherit prototype from.
5456 */
5457exports.inherits = _dereq_('inherits');
5458
5459exports._extend = function(origin, add) {
5460 // Don't do anything if add isn't an object
5461 if (!add || !isObject(add)) return origin;
5462
5463 var keys = Object.keys(add);
5464 var i = keys.length;
5465 while (i--) {
5466 origin[keys[i]] = add[keys[i]];
5467 }
5468 return origin;
5469};
5470
5471function hasOwnProperty(obj, prop) {
5472 return Object.prototype.hasOwnProperty.call(obj, prop);
5473}
5474
5475}).call(this,_dereq_('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
5476},{"./support/isBuffer":4,"_process":3,"inherits":2}],6:[function(_dereq_,module,exports){
5477// A recursive descent parser operates by defining functions for all
5478// syntactic elements, and recursively calling those, each function
5479// advancing the input stream and returning an AST node. Precedence
5480// of constructs (for example, the fact that `!x[1]` means `!(x[1])`
5481// instead of `(!x)[1]` is handled by the fact that the parser
5482// function that parses unary prefix operators is called first, and
5483// in turn calls the function that parses `[]` subscripts — that
5484// way, it'll receive the node for `x[1]` already parsed, and wraps
5485// *that* in the unary operator node.
5486//
5487// Acorn uses an [operator precedence parser][opp] to handle binary
5488// operator precedence, because it is much more compact than using
5489// the technique outlined above, which uses different, nesting
5490// functions to specify precedence, for all of the ten binary
5491// precedence levels that JavaScript defines.
5492//
5493// [opp]: http://en.wikipedia.org/wiki/Operator-precedence_parser
5494
5495"use strict";
5496
5497var tt = _dereq_("./tokentype").types;
5498
5499var Parser = _dereq_("./state").Parser;
5500
5501var reservedWords = _dereq_("./identifier").reservedWords;
5502
5503var has = _dereq_("./util").has;
5504
5505var pp = Parser.prototype;
5506
5507// Check if property name clashes with already added.
5508// Object/class getters and setters are not allowed to clash —
5509// either with each other or with an init property — and in
5510// strict mode, init properties are also not allowed to be repeated.
5511
5512pp.checkPropClash = function (prop, propHash) {
5513 if (this.options.ecmaVersion >= 6) return;
5514 var key = prop.key,
5515 name = undefined;
5516 switch (key.type) {
5517 case "Identifier":
5518 name = key.name;break;
5519 case "Literal":
5520 name = String(key.value);break;
5521 default:
5522 return;
5523 }
5524 var kind = prop.kind || "init",
5525 other = undefined;
5526 if (has(propHash, name)) {
5527 other = propHash[name];
5528 var isGetSet = kind !== "init";
5529 if ((this.strict || isGetSet) && other[kind] || !(isGetSet ^ other.init)) this.raise(key.start, "Redefinition of property");
5530 } else {
5531 other = propHash[name] = {
5532 init: false,
5533 get: false,
5534 set: false
5535 };
5536 }
5537 other[kind] = true;
5538};
5539
5540// ### Expression parsing
5541
5542// These nest, from the most general expression type at the top to
5543// 'atomic', nondivisible expression types at the bottom. Most of
5544// the functions will simply let the function(s) below them parse,
5545// and, *if* the syntactic construct they handle is present, wrap
5546// the AST node that the inner parser gave them in another node.
5547
5548// Parse a full expression. The optional arguments are used to
5549// forbid the `in` operator (in for loops initalization expressions)
5550// and provide reference for storing '=' operator inside shorthand
5551// property assignment in contexts where both object expression
5552// and object pattern might appear (so it's possible to raise
5553// delayed syntax error at correct position).
5554
5555pp.parseExpression = function (noIn, refShorthandDefaultPos) {
5556 var startPos = this.start,
5557 startLoc = this.startLoc;
5558 var expr = this.parseMaybeAssign(noIn, refShorthandDefaultPos);
5559 if (this.type === tt.comma) {
5560 var node = this.startNodeAt(startPos, startLoc);
5561 node.expressions = [expr];
5562 while (this.eat(tt.comma)) node.expressions.push(this.parseMaybeAssign(noIn, refShorthandDefaultPos));
5563 return this.finishNode(node, "SequenceExpression");
5564 }
5565 return expr;
5566};
5567
5568// Parse an assignment expression. This includes applications of
5569// operators like `+=`.
5570
5571pp.parseMaybeAssign = function (noIn, refShorthandDefaultPos, afterLeftParse) {
5572 if (this.type == tt._yield && this.inGenerator) return this.parseYield();
5573
5574 var failOnShorthandAssign = undefined;
5575 if (!refShorthandDefaultPos) {
5576 refShorthandDefaultPos = { start: 0 };
5577 failOnShorthandAssign = true;
5578 } else {
5579 failOnShorthandAssign = false;
5580 }
5581 var startPos = this.start,
5582 startLoc = this.startLoc;
5583 if (this.type == tt.parenL || this.type == tt.name) this.potentialArrowAt = this.start;
5584 var left = this.parseMaybeConditional(noIn, refShorthandDefaultPos);
5585 if (afterLeftParse) left = afterLeftParse.call(this, left, startPos, startLoc);
5586 if (this.type.isAssign) {
5587 var node = this.startNodeAt(startPos, startLoc);
5588 node.operator = this.value;
5589 node.left = this.type === tt.eq ? this.toAssignable(left) : left;
5590 refShorthandDefaultPos.start = 0; // reset because shorthand default was used correctly
5591 this.checkLVal(left);
5592 this.next();
5593 node.right = this.parseMaybeAssign(noIn);
5594 return this.finishNode(node, "AssignmentExpression");
5595 } else if (failOnShorthandAssign && refShorthandDefaultPos.start) {
5596 this.unexpected(refShorthandDefaultPos.start);
5597 }
5598 return left;
5599};
5600
5601// Parse a ternary conditional (`?:`) operator.
5602
5603pp.parseMaybeConditional = function (noIn, refShorthandDefaultPos) {
5604 var startPos = this.start,
5605 startLoc = this.startLoc;
5606 var expr = this.parseExprOps(noIn, refShorthandDefaultPos);
5607 if (refShorthandDefaultPos && refShorthandDefaultPos.start) return expr;
5608 if (this.eat(tt.question)) {
5609 var node = this.startNodeAt(startPos, startLoc);
5610 node.test = expr;
5611 node.consequent = this.parseMaybeAssign();
5612 this.expect(tt.colon);
5613 node.alternate = this.parseMaybeAssign(noIn);
5614 return this.finishNode(node, "ConditionalExpression");
5615 }
5616 return expr;
5617};
5618
5619// Start the precedence parser.
5620
5621pp.parseExprOps = function (noIn, refShorthandDefaultPos) {
5622 var startPos = this.start,
5623 startLoc = this.startLoc;
5624 var expr = this.parseMaybeUnary(refShorthandDefaultPos);
5625 if (refShorthandDefaultPos && refShorthandDefaultPos.start) return expr;
5626 return this.parseExprOp(expr, startPos, startLoc, -1, noIn);
5627};
5628
5629// Parse binary operators with the operator precedence parsing
5630// algorithm. `left` is the left-hand side of the operator.
5631// `minPrec` provides context that allows the function to stop and
5632// defer further parser to one of its callers when it encounters an
5633// operator that has a lower precedence than the set it is parsing.
5634
5635pp.parseExprOp = function (left, leftStartPos, leftStartLoc, minPrec, noIn) {
5636 var prec = this.type.binop;
5637 if (Array.isArray(leftStartPos)) {
5638 if (this.options.locations && noIn === undefined) {
5639 // shift arguments to left by one
5640 noIn = minPrec;
5641 minPrec = leftStartLoc;
5642 // flatten leftStartPos
5643 leftStartLoc = leftStartPos[1];
5644 leftStartPos = leftStartPos[0];
5645 }
5646 }
5647 if (prec != null && (!noIn || this.type !== tt._in)) {
5648 if (prec > minPrec) {
5649 var node = this.startNodeAt(leftStartPos, leftStartLoc);
5650 node.left = left;
5651 node.operator = this.value;
5652 var op = this.type;
5653 this.next();
5654 var startPos = this.start,
5655 startLoc = this.startLoc;
5656 node.right = this.parseExprOp(this.parseMaybeUnary(), startPos, startLoc, prec, noIn);
5657 this.finishNode(node, op === tt.logicalOR || op === tt.logicalAND ? "LogicalExpression" : "BinaryExpression");
5658 return this.parseExprOp(node, leftStartPos, leftStartLoc, minPrec, noIn);
5659 }
5660 }
5661 return left;
5662};
5663
5664// Parse unary operators, both prefix and postfix.
5665
5666pp.parseMaybeUnary = function (refShorthandDefaultPos) {
5667 if (this.type.prefix) {
5668 var node = this.startNode(),
5669 update = this.type === tt.incDec;
5670 node.operator = this.value;
5671 node.prefix = true;
5672 this.next();
5673 node.argument = this.parseMaybeUnary();
5674 if (refShorthandDefaultPos && refShorthandDefaultPos.start) this.unexpected(refShorthandDefaultPos.start);
5675 if (update) this.checkLVal(node.argument);else if (this.strict && node.operator === "delete" && node.argument.type === "Identifier") this.raise(node.start, "Deleting local variable in strict mode");
5676 return this.finishNode(node, update ? "UpdateExpression" : "UnaryExpression");
5677 }
5678 var startPos = this.start,
5679 startLoc = this.startLoc;
5680 var expr = this.parseExprSubscripts(refShorthandDefaultPos);
5681 if (refShorthandDefaultPos && refShorthandDefaultPos.start) return expr;
5682 while (this.type.postfix && !this.canInsertSemicolon()) {
5683 var node = this.startNodeAt(startPos, startLoc);
5684 node.operator = this.value;
5685 node.prefix = false;
5686 node.argument = expr;
5687 this.checkLVal(expr);
5688 this.next();
5689 expr = this.finishNode(node, "UpdateExpression");
5690 }
5691 return expr;
5692};
5693
5694// Parse call, dot, and `[]`-subscript expressions.
5695
5696pp.parseExprSubscripts = function (refShorthandDefaultPos) {
5697 var startPos = this.start,
5698 startLoc = this.startLoc;
5699 var expr = this.parseExprAtom(refShorthandDefaultPos);
5700 if (refShorthandDefaultPos && refShorthandDefaultPos.start) return expr;
5701 return this.parseSubscripts(expr, startPos, startLoc);
5702};
5703
5704pp.parseSubscripts = function (base, startPos, startLoc, noCalls) {
5705 if (Array.isArray(startPos)) {
5706 if (this.options.locations && noCalls === undefined) {
5707 // shift arguments to left by one
5708 noCalls = startLoc;
5709 // flatten startPos
5710 startLoc = startPos[1];
5711 startPos = startPos[0];
5712 }
5713 }
5714 for (;;) {
5715 if (this.eat(tt.dot)) {
5716 var node = this.startNodeAt(startPos, startLoc);
5717 node.object = base;
5718 node.property = this.parseIdent(true);
5719 node.computed = false;
5720 base = this.finishNode(node, "MemberExpression");
5721 } else if (this.eat(tt.bracketL)) {
5722 var node = this.startNodeAt(startPos, startLoc);
5723 node.object = base;
5724 node.property = this.parseExpression();
5725 node.computed = true;
5726 this.expect(tt.bracketR);
5727 base = this.finishNode(node, "MemberExpression");
5728 } else if (!noCalls && this.eat(tt.parenL)) {
5729 var node = this.startNodeAt(startPos, startLoc);
5730 node.callee = base;
5731 node.arguments = this.parseExprList(tt.parenR, false);
5732 base = this.finishNode(node, "CallExpression");
5733 } else if (this.type === tt.backQuote) {
5734 var node = this.startNodeAt(startPos, startLoc);
5735 node.tag = base;
5736 node.quasi = this.parseTemplate();
5737 base = this.finishNode(node, "TaggedTemplateExpression");
5738 } else {
5739 return base;
5740 }
5741 }
5742};
5743
5744// Parse an atomic expression — either a single token that is an
5745// expression, an expression started by a keyword like `function` or
5746// `new`, or an expression wrapped in punctuation like `()`, `[]`,
5747// or `{}`.
5748
5749pp.parseExprAtom = function (refShorthandDefaultPos) {
5750 var node = undefined,
5751 canBeArrow = this.potentialArrowAt == this.start;
5752 switch (this.type) {
5753 case tt._this:
5754 case tt._super:
5755 var type = this.type === tt._this ? "ThisExpression" : "Super";
5756 node = this.startNode();
5757 this.next();
5758 return this.finishNode(node, type);
5759
5760 case tt._yield:
5761 if (this.inGenerator) this.unexpected();
5762
5763 case tt.name:
5764 var startPos = this.start,
5765 startLoc = this.startLoc;
5766 var id = this.parseIdent(this.type !== tt.name);
5767 if (canBeArrow && !this.canInsertSemicolon() && this.eat(tt.arrow)) return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), [id]);
5768 return id;
5769
5770 case tt.regexp:
5771 var value = this.value;
5772 node = this.parseLiteral(value.value);
5773 node.regex = { pattern: value.pattern, flags: value.flags };
5774 return node;
5775
5776 case tt.num:case tt.string:
5777 return this.parseLiteral(this.value);
5778
5779 case tt._null:case tt._true:case tt._false:
5780 node = this.startNode();
5781 node.value = this.type === tt._null ? null : this.type === tt._true;
5782 node.raw = this.type.keyword;
5783 this.next();
5784 return this.finishNode(node, "Literal");
5785
5786 case tt.parenL:
5787 return this.parseParenAndDistinguishExpression(canBeArrow);
5788
5789 case tt.bracketL:
5790 node = this.startNode();
5791 this.next();
5792 // check whether this is array comprehension or regular array
5793 if (this.options.ecmaVersion >= 7 && this.type === tt._for) {
5794 return this.parseComprehension(node, false);
5795 }
5796 node.elements = this.parseExprList(tt.bracketR, true, true, refShorthandDefaultPos);
5797 return this.finishNode(node, "ArrayExpression");
5798
5799 case tt.braceL:
5800 return this.parseObj(false, refShorthandDefaultPos);
5801
5802 case tt._function:
5803 node = this.startNode();
5804 this.next();
5805 return this.parseFunction(node, false);
5806
5807 case tt._class:
5808 return this.parseClass(this.startNode(), false);
5809
5810 case tt._new:
5811 return this.parseNew();
5812
5813 case tt.backQuote:
5814 return this.parseTemplate();
5815
5816 default:
5817 this.unexpected();
5818 }
5819};
5820
5821pp.parseLiteral = function (value) {
5822 var node = this.startNode();
5823 node.value = value;
5824 node.raw = this.input.slice(this.start, this.end);
5825 this.next();
5826 return this.finishNode(node, "Literal");
5827};
5828
5829pp.parseParenExpression = function () {
5830 this.expect(tt.parenL);
5831 var val = this.parseExpression();
5832 this.expect(tt.parenR);
5833 return val;
5834};
5835
5836pp.parseParenAndDistinguishExpression = function (canBeArrow) {
5837 var startPos = this.start,
5838 startLoc = this.startLoc,
5839 val = undefined;
5840 if (this.options.ecmaVersion >= 6) {
5841 this.next();
5842
5843 if (this.options.ecmaVersion >= 7 && this.type === tt._for) {
5844 return this.parseComprehension(this.startNodeAt(startPos, startLoc), true);
5845 }
5846
5847 var innerStartPos = this.start,
5848 innerStartLoc = this.startLoc;
5849 var exprList = [],
5850 first = true;
5851 var refShorthandDefaultPos = { start: 0 },
5852 spreadStart = undefined,
5853 innerParenStart = undefined;
5854 while (this.type !== tt.parenR) {
5855 first ? first = false : this.expect(tt.comma);
5856 if (this.type === tt.ellipsis) {
5857 spreadStart = this.start;
5858 exprList.push(this.parseParenItem(this.parseRest()));
5859 break;
5860 } else {
5861 if (this.type === tt.parenL && !innerParenStart) {
5862 innerParenStart = this.start;
5863 }
5864 exprList.push(this.parseMaybeAssign(false, refShorthandDefaultPos, this.parseParenItem));
5865 }
5866 }
5867 var innerEndPos = this.start,
5868 innerEndLoc = this.startLoc;
5869 this.expect(tt.parenR);
5870
5871 if (canBeArrow && !this.canInsertSemicolon() && this.eat(tt.arrow)) {
5872 if (innerParenStart) this.unexpected(innerParenStart);
5873 return this.parseParenArrowList(startPos, startLoc, exprList);
5874 }
5875
5876 if (!exprList.length) this.unexpected(this.lastTokStart);
5877 if (spreadStart) this.unexpected(spreadStart);
5878 if (refShorthandDefaultPos.start) this.unexpected(refShorthandDefaultPos.start);
5879
5880 if (exprList.length > 1) {
5881 val = this.startNodeAt(innerStartPos, innerStartLoc);
5882 val.expressions = exprList;
5883 this.finishNodeAt(val, "SequenceExpression", innerEndPos, innerEndLoc);
5884 } else {
5885 val = exprList[0];
5886 }
5887 } else {
5888 val = this.parseParenExpression();
5889 }
5890
5891 if (this.options.preserveParens) {
5892 var par = this.startNodeAt(startPos, startLoc);
5893 par.expression = val;
5894 return this.finishNode(par, "ParenthesizedExpression");
5895 } else {
5896 return val;
5897 }
5898};
5899
5900pp.parseParenItem = function (item) {
5901 return item;
5902};
5903
5904pp.parseParenArrowList = function (startPos, startLoc, exprList) {
5905 return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), exprList);
5906};
5907
5908// New's precedence is slightly tricky. It must allow its argument
5909// to be a `[]` or dot subscript expression, but not a call — at
5910// least, not without wrapping it in parentheses. Thus, it uses the
5911
5912var empty = [];
5913
5914pp.parseNew = function () {
5915 var node = this.startNode();
5916 var meta = this.parseIdent(true);
5917 if (this.options.ecmaVersion >= 6 && this.eat(tt.dot)) {
5918 node.meta = meta;
5919 node.property = this.parseIdent(true);
5920 if (node.property.name !== "target") this.raise(node.property.start, "The only valid meta property for new is new.target");
5921 return this.finishNode(node, "MetaProperty");
5922 }
5923 var startPos = this.start,
5924 startLoc = this.startLoc;
5925 node.callee = this.parseSubscripts(this.parseExprAtom(), startPos, startLoc, true);
5926 if (this.eat(tt.parenL)) node.arguments = this.parseExprList(tt.parenR, false);else node.arguments = empty;
5927 return this.finishNode(node, "NewExpression");
5928};
5929
5930// Parse template expression.
5931
5932pp.parseTemplateElement = function () {
5933 var elem = this.startNode();
5934 elem.value = {
5935 raw: this.input.slice(this.start, this.end),
5936 cooked: this.value
5937 };
5938 this.next();
5939 elem.tail = this.type === tt.backQuote;
5940 return this.finishNode(elem, "TemplateElement");
5941};
5942
5943pp.parseTemplate = function () {
5944 var node = this.startNode();
5945 this.next();
5946 node.expressions = [];
5947 var curElt = this.parseTemplateElement();
5948 node.quasis = [curElt];
5949 while (!curElt.tail) {
5950 this.expect(tt.dollarBraceL);
5951 node.expressions.push(this.parseExpression());
5952 this.expect(tt.braceR);
5953 node.quasis.push(curElt = this.parseTemplateElement());
5954 }
5955 this.next();
5956 return this.finishNode(node, "TemplateLiteral");
5957};
5958
5959// Parse an object literal or binding pattern.
5960
5961pp.parseObj = function (isPattern, refShorthandDefaultPos) {
5962 var node = this.startNode(),
5963 first = true,
5964 propHash = {};
5965 node.properties = [];
5966 this.next();
5967 while (!this.eat(tt.braceR)) {
5968 if (!first) {
5969 this.expect(tt.comma);
5970 if (this.afterTrailingComma(tt.braceR)) break;
5971 } else first = false;
5972
5973 var prop = this.startNode(),
5974 isGenerator = undefined,
5975 startPos = undefined,
5976 startLoc = undefined;
5977 if (this.options.ecmaVersion >= 6) {
5978 prop.method = false;
5979 prop.shorthand = false;
5980 if (isPattern || refShorthandDefaultPos) {
5981 startPos = this.start;
5982 startLoc = this.startLoc;
5983 }
5984 if (!isPattern) isGenerator = this.eat(tt.star);
5985 }
5986 this.parsePropertyName(prop);
5987 this.parsePropertyValue(prop, isPattern, isGenerator, startPos, startLoc, refShorthandDefaultPos);
5988 this.checkPropClash(prop, propHash);
5989 node.properties.push(this.finishNode(prop, "Property"));
5990 }
5991 return this.finishNode(node, isPattern ? "ObjectPattern" : "ObjectExpression");
5992};
5993
5994pp.parsePropertyValue = function (prop, isPattern, isGenerator, startPos, startLoc, refShorthandDefaultPos) {
5995 if (this.eat(tt.colon)) {
5996 prop.value = isPattern ? this.parseMaybeDefault(this.start, this.startLoc) : this.parseMaybeAssign(false, refShorthandDefaultPos);
5997 prop.kind = "init";
5998 } else if (this.options.ecmaVersion >= 6 && this.type === tt.parenL) {
5999 if (isPattern) this.unexpected();
6000 prop.kind = "init";
6001 prop.method = true;
6002 prop.value = this.parseMethod(isGenerator);
6003 } else if (this.options.ecmaVersion >= 5 && !prop.computed && prop.key.type === "Identifier" && (prop.key.name === "get" || prop.key.name === "set") && (this.type != tt.comma && this.type != tt.braceR)) {
6004 if (isGenerator || isPattern) this.unexpected();
6005 prop.kind = prop.key.name;
6006 this.parsePropertyName(prop);
6007 prop.value = this.parseMethod(false);
6008 } else if (this.options.ecmaVersion >= 6 && !prop.computed && prop.key.type === "Identifier") {
6009 prop.kind = "init";
6010 if (isPattern) {
6011 if (this.isKeyword(prop.key.name) || this.strict && (reservedWords.strictBind(prop.key.name) || reservedWords.strict(prop.key.name)) || !this.options.allowReserved && this.isReservedWord(prop.key.name)) this.raise(prop.key.start, "Binding " + prop.key.name);
6012 prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key);
6013 } else if (this.type === tt.eq && refShorthandDefaultPos) {
6014 if (!refShorthandDefaultPos.start) refShorthandDefaultPos.start = this.start;
6015 prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key);
6016 } else {
6017 prop.value = prop.key;
6018 }
6019 prop.shorthand = true;
6020 } else this.unexpected();
6021};
6022
6023pp.parsePropertyName = function (prop) {
6024 if (this.options.ecmaVersion >= 6) {
6025 if (this.eat(tt.bracketL)) {
6026 prop.computed = true;
6027 prop.key = this.parseMaybeAssign();
6028 this.expect(tt.bracketR);
6029 return prop.key;
6030 } else {
6031 prop.computed = false;
6032 }
6033 }
6034 return prop.key = this.type === tt.num || this.type === tt.string ? this.parseExprAtom() : this.parseIdent(true);
6035};
6036
6037// Initialize empty function node.
6038
6039pp.initFunction = function (node) {
6040 node.id = null;
6041 if (this.options.ecmaVersion >= 6) {
6042 node.generator = false;
6043 node.expression = false;
6044 }
6045};
6046
6047// Parse object or class method.
6048
6049pp.parseMethod = function (isGenerator) {
6050 var node = this.startNode();
6051 this.initFunction(node);
6052 this.expect(tt.parenL);
6053 node.params = this.parseBindingList(tt.parenR, false, false);
6054 var allowExpressionBody = undefined;
6055 if (this.options.ecmaVersion >= 6) {
6056 node.generator = isGenerator;
6057 allowExpressionBody = true;
6058 } else {
6059 allowExpressionBody = false;
6060 }
6061 this.parseFunctionBody(node, allowExpressionBody);
6062 return this.finishNode(node, "FunctionExpression");
6063};
6064
6065// Parse arrow function expression with given parameters.
6066
6067pp.parseArrowExpression = function (node, params) {
6068 this.initFunction(node);
6069 node.params = this.toAssignableList(params, true);
6070 this.parseFunctionBody(node, true);
6071 return this.finishNode(node, "ArrowFunctionExpression");
6072};
6073
6074// Parse function body and check parameters.
6075
6076pp.parseFunctionBody = function (node, allowExpression) {
6077 var isExpression = allowExpression && this.type !== tt.braceL;
6078
6079 if (isExpression) {
6080 node.body = this.parseMaybeAssign();
6081 node.expression = true;
6082 } else {
6083 // Start a new scope with regard to labels and the `inFunction`
6084 // flag (restore them to their old value afterwards).
6085 var oldInFunc = this.inFunction,
6086 oldInGen = this.inGenerator,
6087 oldLabels = this.labels;
6088 this.inFunction = true;this.inGenerator = node.generator;this.labels = [];
6089 node.body = this.parseBlock(true);
6090 node.expression = false;
6091 this.inFunction = oldInFunc;this.inGenerator = oldInGen;this.labels = oldLabels;
6092 }
6093
6094 // If this is a strict mode function, verify that argument names
6095 // are not repeated, and it does not try to bind the words `eval`
6096 // or `arguments`.
6097 if (this.strict || !isExpression && node.body.body.length && this.isUseStrict(node.body.body[0])) {
6098 var nameHash = {},
6099 oldStrict = this.strict;
6100 this.strict = true;
6101 if (node.id) this.checkLVal(node.id, true);
6102 for (var i = 0; i < node.params.length; i++) {
6103 this.checkLVal(node.params[i], true, nameHash);
6104 }this.strict = oldStrict;
6105 }
6106};
6107
6108// Parses a comma-separated list of expressions, and returns them as
6109// an array. `close` is the token type that ends the list, and
6110// `allowEmpty` can be turned on to allow subsequent commas with
6111// nothing in between them to be parsed as `null` (which is needed
6112// for array literals).
6113
6114pp.parseExprList = function (close, allowTrailingComma, allowEmpty, refShorthandDefaultPos) {
6115 var elts = [],
6116 first = true;
6117 while (!this.eat(close)) {
6118 if (!first) {
6119 this.expect(tt.comma);
6120 if (allowTrailingComma && this.afterTrailingComma(close)) break;
6121 } else first = false;
6122
6123 if (allowEmpty && this.type === tt.comma) {
6124 elts.push(null);
6125 } else {
6126 if (this.type === tt.ellipsis) elts.push(this.parseSpread(refShorthandDefaultPos));else elts.push(this.parseMaybeAssign(false, refShorthandDefaultPos));
6127 }
6128 }
6129 return elts;
6130};
6131
6132// Parse the next token as an identifier. If `liberal` is true (used
6133// when parsing properties), it will also convert keywords into
6134// identifiers.
6135
6136pp.parseIdent = function (liberal) {
6137 var node = this.startNode();
6138 if (liberal && this.options.allowReserved == "never") liberal = false;
6139 if (this.type === tt.name) {
6140 if (!liberal && (!this.options.allowReserved && this.isReservedWord(this.value) || this.strict && reservedWords.strict(this.value) && (this.options.ecmaVersion >= 6 || this.input.slice(this.start, this.end).indexOf("\\") == -1))) this.raise(this.start, "The keyword '" + this.value + "' is reserved");
6141 node.name = this.value;
6142 } else if (liberal && this.type.keyword) {
6143 node.name = this.type.keyword;
6144 } else {
6145 this.unexpected();
6146 }
6147 this.next();
6148 return this.finishNode(node, "Identifier");
6149};
6150
6151// Parses yield expression inside generator.
6152
6153pp.parseYield = function () {
6154 var node = this.startNode();
6155 this.next();
6156 if (this.type == tt.semi || this.canInsertSemicolon() || this.type != tt.star && !this.type.startsExpr) {
6157 node.delegate = false;
6158 node.argument = null;
6159 } else {
6160 node.delegate = this.eat(tt.star);
6161 node.argument = this.parseMaybeAssign();
6162 }
6163 return this.finishNode(node, "YieldExpression");
6164};
6165
6166// Parses array and generator comprehensions.
6167
6168pp.parseComprehension = function (node, isGenerator) {
6169 node.blocks = [];
6170 while (this.type === tt._for) {
6171 var block = this.startNode();
6172 this.next();
6173 this.expect(tt.parenL);
6174 block.left = this.parseBindingAtom();
6175 this.checkLVal(block.left, true);
6176 this.expectContextual("of");
6177 block.right = this.parseExpression();
6178 this.expect(tt.parenR);
6179 node.blocks.push(this.finishNode(block, "ComprehensionBlock"));
6180 }
6181 node.filter = this.eat(tt._if) ? this.parseParenExpression() : null;
6182 node.body = this.parseExpression();
6183 this.expect(isGenerator ? tt.parenR : tt.bracketR);
6184 node.generator = isGenerator;
6185 return this.finishNode(node, "ComprehensionExpression");
6186};
6187
6188},{"./identifier":7,"./state":13,"./tokentype":17,"./util":18}],7:[function(_dereq_,module,exports){
6189
6190
6191// Test whether a given character code starts an identifier.
6192
6193"use strict";
6194
6195exports.isIdentifierStart = isIdentifierStart;
6196
6197// Test whether a given character is part of an identifier.
6198
6199exports.isIdentifierChar = isIdentifierChar;
6200exports.__esModule = true;
6201// This is a trick taken from Esprima. It turns out that, on
6202// non-Chrome browsers, to check whether a string is in a set, a
6203// predicate containing a big ugly `switch` statement is faster than
6204// a regular expression, and on Chrome the two are about on par.
6205// This function uses `eval` (non-lexical) to produce such a
6206// predicate from a space-separated string of words.
6207//
6208// It starts by sorting the words by length.
6209
6210function makePredicate(words) {
6211 words = words.split(" ");
6212 var f = "",
6213 cats = [];
6214 out: for (var i = 0; i < words.length; ++i) {
6215 for (var j = 0; j < cats.length; ++j) {
6216 if (cats[j][0].length == words[i].length) {
6217 cats[j].push(words[i]);
6218 continue out;
6219 }
6220 }cats.push([words[i]]);
6221 }
6222 function compareTo(arr) {
6223 if (arr.length == 1) {
6224 return f += "return str === " + JSON.stringify(arr[0]) + ";";
6225 }f += "switch(str){";
6226 for (var i = 0; i < arr.length; ++i) {
6227 f += "case " + JSON.stringify(arr[i]) + ":";
6228 }f += "return true}return false;";
6229 }
6230
6231 // When there are more than three length categories, an outer
6232 // switch first dispatches on the lengths, to save on comparisons.
6233
6234 if (cats.length > 3) {
6235 cats.sort(function (a, b) {
6236 return b.length - a.length;
6237 });
6238 f += "switch(str.length){";
6239 for (var i = 0; i < cats.length; ++i) {
6240 var cat = cats[i];
6241 f += "case " + cat[0].length + ":";
6242 compareTo(cat);
6243 }
6244 f += "}"
6245
6246 // Otherwise, simply generate a flat `switch` statement.
6247
6248 ;
6249 } else {
6250 compareTo(words);
6251 }
6252 return new Function("str", f);
6253}
6254
6255// Reserved word lists for various dialects of the language
6256
6257var reservedWords = {
6258 3: makePredicate("abstract boolean byte char class double enum export extends final float goto implements import int interface long native package private protected public short static super synchronized throws transient volatile"),
6259 5: makePredicate("class enum extends super const export import"),
6260 6: makePredicate("enum await"),
6261 strict: makePredicate("implements interface let package private protected public static yield"),
6262 strictBind: makePredicate("eval arguments")
6263};
6264
6265exports.reservedWords = reservedWords;
6266// And the keywords
6267
6268var ecma5AndLessKeywords = "break case catch continue debugger default do else finally for function if return switch throw try var while with null true false instanceof typeof void delete new in this";
6269
6270var keywords = {
6271 5: makePredicate(ecma5AndLessKeywords),
6272 6: makePredicate(ecma5AndLessKeywords + " let const class extends export import yield super")
6273};
6274
6275exports.keywords = keywords;
6276// ## Character categories
6277
6278// Big ugly regular expressions that match characters in the
6279// whitespace, identifier, and identifier-start categories. These
6280// are only applied when a character is found to actually have a
6281// code point above 128.
6282// Generated by `tools/generate-identifier-regex.js`.
6283
6284var nonASCIIidentifierStartChars = "ªµºÀ-ÖØ-öø-ˁˆ-ˑˠ-ˤˬˮͰ-ʹͶͷͺ-ͽͿΆΈ-ΊΌΎ-ΡΣ-ϵϷ-ҁҊ-ԯԱ-Ֆՙա-ևא-תװ-ײؠ-يٮٯٱ-ۓەۥۦۮۯۺ-ۼۿܐܒ-ܯݍ-ޥޱߊ-ߪߴߵߺࠀ-ࠕࠚࠤࠨࡀ-ࡘࢠ-ࢲऄ-हऽॐक़-ॡॱ-ঀঅ-ঌএঐও-নপ-রলশ-হঽৎড়ঢ়য়-ৡৰৱਅ-ਊਏਐਓ-ਨਪ-ਰਲਲ਼ਵਸ਼ਸਹਖ਼-ੜਫ਼ੲ-ੴઅ-ઍએ-ઑઓ-નપ-રલળવ-હઽૐૠૡଅ-ଌଏଐଓ-ନପ-ରଲଳଵ-ହଽଡ଼ଢ଼ୟ-ୡୱஃஅ-ஊஎ-ஐஒ-கஙசஜஞடணதந-பம-ஹௐఅ-ఌఎ-ఐఒ-నప-హఽౘౙౠౡಅ-ಌಎ-ಐಒ-ನಪ-ಳವ-ಹಽೞೠೡೱೲഅ-ഌഎ-ഐഒ-ഺഽൎൠൡൺ-ൿඅ-ඖක-නඳ-රලව-ෆก-ะาำเ-ๆກຂຄງຈຊຍດ-ທນ-ຟມ-ຣລວສຫອ-ະາຳຽເ-ໄໆໜ-ໟༀཀ-ཇཉ-ཬྈ-ྌက-ဪဿၐ-ၕၚ-ၝၡၥၦၮ-ၰၵ-ႁႎႠ-ჅჇჍა-ჺჼ-ቈቊ-ቍቐ-ቖቘቚ-ቝበ-ኈኊ-ኍነ-ኰኲ-ኵኸ-ኾዀዂ-ዅወ-ዖዘ-ጐጒ-ጕጘ-ፚᎀ-ᎏᎠ-Ᏼᐁ-ᙬᙯ-ᙿᚁ-ᚚᚠ-ᛪᛮ-ᛸᜀ-ᜌᜎ-ᜑᜠ-ᜱᝀ-ᝑᝠ-ᝬᝮ-ᝰក-ឳៗៜᠠ-ᡷᢀ-ᢨᢪᢰ-ᣵᤀ-ᤞᥐ-ᥭᥰ-ᥴᦀ-ᦫᧁ-ᧇᨀ-ᨖᨠ-ᩔᪧᬅ-ᬳᭅ-ᭋᮃ-ᮠᮮᮯᮺ-ᯥᰀ-ᰣᱍ-ᱏᱚ-ᱽᳩ-ᳬᳮ-ᳱᳵᳶᴀ-ᶿḀ-ἕἘ-Ἕἠ-ὅὈ-Ὅὐ-ὗὙὛὝὟ-ώᾀ-ᾴᾶ-ᾼιῂ-ῄῆ-ῌῐ-ΐῖ-Ίῠ-Ῥῲ-ῴῶ-ῼⁱⁿₐ-ₜℂℇℊ-ℓℕ℘-ℝℤΩℨK-ℹℼ-ℿⅅ-ⅉⅎⅠ-ↈⰀ-Ⱞⰰ-ⱞⱠ-ⳤⳫ-ⳮⳲⳳⴀ-ⴥⴧⴭⴰ-ⵧⵯⶀ-ⶖⶠ-ⶦⶨ-ⶮⶰ-ⶶⶸ-ⶾⷀ-ⷆⷈ-ⷎⷐ-ⷖⷘ-ⷞ々-〇〡-〩〱-〵〸-〼ぁ-ゖ゛-ゟァ-ヺー-ヿㄅ-ㄭㄱ-ㆎㆠ-ㆺㇰ-ㇿ㐀-䶵一-鿌ꀀ-ꒌꓐ-ꓽꔀ-ꘌꘐ-ꘟꘪꘫꙀ-ꙮꙿ-ꚝꚠ-ꛯꜗ-ꜟꜢ-ꞈꞋ-ꞎꞐ-ꞭꞰꞱꟷ-ꠁꠃ-ꠅꠇ-ꠊꠌ-ꠢꡀ-ꡳꢂ-ꢳꣲ-ꣷꣻꤊ-ꤥꤰ-ꥆꥠ-ꥼꦄ-ꦲꧏꧠ-ꧤꧦ-ꧯꧺ-ꧾꨀ-ꨨꩀ-ꩂꩄ-ꩋꩠ-ꩶꩺꩾ-ꪯꪱꪵꪶꪹ-ꪽꫀꫂꫛ-ꫝꫠ-ꫪꫲ-ꫴꬁ-ꬆꬉ-ꬎꬑ-ꬖꬠ-ꬦꬨ-ꬮꬰ-ꭚꭜ-ꭟꭤꭥꯀ-ꯢ가-힣ힰ-ퟆퟋ-ퟻ豈-舘並-龎ff-stﬓ-ﬗיִײַ-ﬨשׁ-זּטּ-לּמּנּסּףּפּצּ-ﮱﯓ-ﴽﵐ-ﶏﶒ-ﷇﷰ-ﷻﹰ-ﹴﹶ-ﻼA-Za-zヲ-하-ᅦᅧ-ᅬᅭ-ᅲᅳ-ᅵ";
6285var nonASCIIidentifierChars = "‌‍·̀-ͯ·҃-֑҇-ׇֽֿׁׂׅׄؐ-ًؚ-٩ٰۖ-ۜ۟-۪ۤۧۨ-ۭ۰-۹ܑܰ-݊ަ-ް߀-߉߫-߳ࠖ-࠙ࠛ-ࠣࠥ-ࠧࠩ-࡙࠭-࡛ࣤ-ःऺ-़ा-ॏ॑-ॗॢॣ०-९ঁ-ঃ়া-ৄেৈো-্ৗৢৣ০-৯ਁ-ਃ਼ਾ-ੂੇੈੋ-੍ੑ੦-ੱੵઁ-ઃ઼ા-ૅે-ૉો-્ૢૣ૦-૯ଁ-ଃ଼ା-ୄେୈୋ-୍ୖୗୢୣ୦-୯ஂா-ூெ-ைொ-்ௗ௦-௯ఀ-ఃా-ౄె-ైొ-్ౕౖౢౣ౦-౯ಁ-ಃ಼ಾ-ೄೆ-ೈೊ-್ೕೖೢೣ೦-೯ഁ-ഃാ-ൄെ-ൈൊ-്ൗൢൣ൦-൯ංඃ්ා-ුූෘ-ෟ෦-෯ෲෳัิ-ฺ็-๎๐-๙ັິ-ູົຼ່-ໍ໐-໙༘༙༠-༩༹༵༷༾༿ཱ-྄྆྇ྍ-ྗྙ-ྼ࿆ါ-ှ၀-၉ၖ-ၙၞ-ၠၢ-ၤၧ-ၭၱ-ၴႂ-ႍႏ-ႝ፝-፟፩-፱ᜒ-᜔ᜲ-᜴ᝒᝓᝲᝳ឴-៓៝០-៩᠋-᠍᠐-᠙ᢩᤠ-ᤫᤰ-᤻᥆-᥏ᦰ-ᧀᧈᧉ᧐-᧚ᨗ-ᨛᩕ-ᩞ᩠-᩿᩼-᪉᪐-᪙᪰-᪽ᬀ-ᬄ᬴-᭄᭐-᭙᭫-᭳ᮀ-ᮂᮡ-ᮭ᮰-᮹᯦-᯳ᰤ-᰷᱀-᱉᱐-᱙᳐-᳔᳒-᳨᳭ᳲ-᳴᳸᳹᷀-᷵᷼-᷿‿⁀⁔⃐-⃥⃜⃡-⃰⳯-⵿⳱ⷠ-〪ⷿ-゙゚〯꘠-꘩꙯ꙴ-꙽ꚟ꛰꛱ꠂ꠆ꠋꠣ-ꠧꢀꢁꢴ-꣄꣐-꣙꣠-꣱꤀-꤉ꤦ-꤭ꥇ-꥓ꦀ-ꦃ꦳-꧀꧐-꧙ꧥ꧰-꧹ꨩ-ꨶꩃꩌꩍ꩐-꩙ꩻ-ꩽꪰꪲ-ꪴꪷꪸꪾ꪿꫁ꫫ-ꫯꫵ꫶ꯣ-ꯪ꯬꯭꯰-꯹ﬞ︀-️︠-︭︳︴﹍-﹏0-9_";
6286
6287var nonASCIIidentifierStart = new RegExp("[" + nonASCIIidentifierStartChars + "]");
6288var nonASCIIidentifier = new RegExp("[" + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "]");
6289
6290nonASCIIidentifierStartChars = nonASCIIidentifierChars = null;
6291
6292// These are a run-length and offset encoded representation of the
6293// >0xffff code points that are a valid part of identifiers. The
6294// offset starts at 0x10000, and each pair of numbers represents an
6295// offset to the next range, and then a size of the range. They were
6296// generated by tools/generate-identifier-regex.js
6297var astralIdentifierStartCodes = [0, 11, 2, 25, 2, 18, 2, 1, 2, 14, 3, 13, 35, 122, 70, 52, 268, 28, 4, 48, 48, 31, 17, 26, 6, 37, 11, 29, 3, 35, 5, 7, 2, 4, 43, 157, 99, 39, 9, 51, 157, 310, 10, 21, 11, 7, 153, 5, 3, 0, 2, 43, 2, 1, 4, 0, 3, 22, 11, 22, 10, 30, 98, 21, 11, 25, 71, 55, 7, 1, 65, 0, 16, 3, 2, 2, 2, 26, 45, 28, 4, 28, 36, 7, 2, 27, 28, 53, 11, 21, 11, 18, 14, 17, 111, 72, 955, 52, 76, 44, 33, 24, 27, 35, 42, 34, 4, 0, 13, 47, 15, 3, 22, 0, 38, 17, 2, 24, 133, 46, 39, 7, 3, 1, 3, 21, 2, 6, 2, 1, 2, 4, 4, 0, 32, 4, 287, 47, 21, 1, 2, 0, 185, 46, 82, 47, 21, 0, 60, 42, 502, 63, 32, 0, 449, 56, 1288, 920, 104, 110, 2962, 1070, 13266, 568, 8, 30, 114, 29, 19, 47, 17, 3, 32, 20, 6, 18, 881, 68, 12, 0, 67, 12, 16481, 1, 3071, 106, 6, 12, 4, 8, 8, 9, 5991, 84, 2, 70, 2, 1, 3, 0, 3, 1, 3, 3, 2, 11, 2, 0, 2, 6, 2, 64, 2, 3, 3, 7, 2, 6, 2, 27, 2, 3, 2, 4, 2, 0, 4, 6, 2, 339, 3, 24, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 7, 4149, 196, 1340, 3, 2, 26, 2, 1, 2, 0, 3, 0, 2, 9, 2, 3, 2, 0, 2, 0, 7, 0, 5, 0, 2, 0, 2, 0, 2, 2, 2, 1, 2, 0, 3, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 1, 2, 0, 3, 3, 2, 6, 2, 3, 2, 3, 2, 0, 2, 9, 2, 16, 6, 2, 2, 4, 2, 16, 4421, 42710, 42, 4148, 12, 221, 16355, 541];
6298var astralIdentifierCodes = [509, 0, 227, 0, 150, 4, 294, 9, 1368, 2, 2, 1, 6, 3, 41, 2, 5, 0, 166, 1, 1306, 2, 54, 14, 32, 9, 16, 3, 46, 10, 54, 9, 7, 2, 37, 13, 2, 9, 52, 0, 13, 2, 49, 13, 16, 9, 83, 11, 168, 11, 6, 9, 8, 2, 57, 0, 2, 6, 3, 1, 3, 2, 10, 0, 11, 1, 3, 6, 4, 4, 316, 19, 13, 9, 214, 6, 3, 8, 112, 16, 16, 9, 82, 12, 9, 9, 535, 9, 20855, 9, 135, 4, 60, 6, 26, 9, 1016, 45, 17, 3, 19723, 1, 5319, 4, 4, 5, 9, 7, 3, 6, 31, 3, 149, 2, 1418, 49, 4305, 6, 792618, 239];
6299
6300// This has a complexity linear to the value of the code. The
6301// assumption is that looking up astral identifier characters is
6302// rare.
6303function isInAstralSet(code, set) {
6304 var pos = 65536;
6305 for (var i = 0; i < set.length; i += 2) {
6306 pos += set[i];
6307 if (pos > code) {
6308 return false;
6309 }pos += set[i + 1];
6310 if (pos >= code) {
6311 return true;
6312 }
6313 }
6314}
6315function isIdentifierStart(code, astral) {
6316 if (code < 65) {
6317 return code === 36;
6318 }if (code < 91) {
6319 return true;
6320 }if (code < 97) {
6321 return code === 95;
6322 }if (code < 123) {
6323 return true;
6324 }if (code <= 65535) {
6325 return code >= 170 && nonASCIIidentifierStart.test(String.fromCharCode(code));
6326 }if (astral === false) {
6327 return false;
6328 }return isInAstralSet(code, astralIdentifierStartCodes);
6329}
6330
6331function isIdentifierChar(code, astral) {
6332 if (code < 48) {
6333 return code === 36;
6334 }if (code < 58) {
6335 return true;
6336 }if (code < 65) {
6337 return false;
6338 }if (code < 91) {
6339 return true;
6340 }if (code < 97) {
6341 return code === 95;
6342 }if (code < 123) {
6343 return true;
6344 }if (code <= 65535) {
6345 return code >= 170 && nonASCIIidentifier.test(String.fromCharCode(code));
6346 }if (astral === false) {
6347 return false;
6348 }return isInAstralSet(code, astralIdentifierStartCodes) || isInAstralSet(code, astralIdentifierCodes);
6349}
6350
6351},{}],8:[function(_dereq_,module,exports){
6352"use strict";
6353
6354var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } };
6355
6356// The `getLineInfo` function is mostly useful when the
6357// `locations` option is off (for performance reasons) and you
6358// want to find the line/column position for a given character
6359// offset. `input` should be the code string that the offset refers
6360// into.
6361
6362exports.getLineInfo = getLineInfo;
6363exports.__esModule = true;
6364
6365var Parser = _dereq_("./state").Parser;
6366
6367var lineBreakG = _dereq_("./whitespace").lineBreakG;
6368
6369var deprecate = _dereq_("util").deprecate;
6370
6371// These are used when `options.locations` is on, for the
6372// `startLoc` and `endLoc` properties.
6373
6374var Position = exports.Position = (function () {
6375 function Position(line, col) {
6376 _classCallCheck(this, Position);
6377
6378 this.line = line;
6379 this.column = col;
6380 }
6381
6382 Position.prototype.offset = function offset(n) {
6383 return new Position(this.line, this.column + n);
6384 };
6385
6386 return Position;
6387})();
6388
6389var SourceLocation = exports.SourceLocation = function SourceLocation(p, start, end) {
6390 _classCallCheck(this, SourceLocation);
6391
6392 this.start = start;
6393 this.end = end;
6394 if (p.sourceFile !== null) this.source = p.sourceFile;
6395};
6396
6397function getLineInfo(input, offset) {
6398 for (var line = 1, cur = 0;;) {
6399 lineBreakG.lastIndex = cur;
6400 var match = lineBreakG.exec(input);
6401 if (match && match.index < offset) {
6402 ++line;
6403 cur = match.index + match[0].length;
6404 } else {
6405 return new Position(line, offset - cur);
6406 }
6407 }
6408}
6409
6410var pp = Parser.prototype;
6411
6412// This function is used to raise exceptions on parse errors. It
6413// takes an offset integer (into the current `input`) to indicate
6414// the location of the error, attaches the position to the end
6415// of the error message, and then raises a `SyntaxError` with that
6416// message.
6417
6418pp.raise = function (pos, message) {
6419 var loc = getLineInfo(this.input, pos);
6420 message += " (" + loc.line + ":" + loc.column + ")";
6421 var err = new SyntaxError(message);
6422 err.pos = pos;err.loc = loc;err.raisedAt = this.pos;
6423 throw err;
6424};
6425
6426pp.curPosition = function () {
6427 return new Position(this.curLine, this.pos - this.lineStart);
6428};
6429
6430pp.markPosition = function () {
6431 return this.options.locations ? [this.start, this.startLoc] : this.start;
6432};
6433
6434},{"./state":13,"./whitespace":19,"util":5}],9:[function(_dereq_,module,exports){
6435"use strict";
6436
6437var tt = _dereq_("./tokentype").types;
6438
6439var Parser = _dereq_("./state").Parser;
6440
6441var reservedWords = _dereq_("./identifier").reservedWords;
6442
6443var has = _dereq_("./util").has;
6444
6445var pp = Parser.prototype;
6446
6447// Convert existing expression atom to assignable pattern
6448// if possible.
6449
6450pp.toAssignable = function (node, isBinding) {
6451 if (this.options.ecmaVersion >= 6 && node) {
6452 switch (node.type) {
6453 case "Identifier":
6454 case "ObjectPattern":
6455 case "ArrayPattern":
6456 case "AssignmentPattern":
6457 break;
6458
6459 case "ObjectExpression":
6460 node.type = "ObjectPattern";
6461 for (var i = 0; i < node.properties.length; i++) {
6462 var prop = node.properties[i];
6463 if (prop.kind !== "init") this.raise(prop.key.start, "Object pattern can't contain getter or setter");
6464 this.toAssignable(prop.value, isBinding);
6465 }
6466 break;
6467
6468 case "ArrayExpression":
6469 node.type = "ArrayPattern";
6470 this.toAssignableList(node.elements, isBinding);
6471 break;
6472
6473 case "AssignmentExpression":
6474 if (node.operator === "=") {
6475 node.type = "AssignmentPattern";
6476 } else {
6477 this.raise(node.left.end, "Only '=' operator can be used for specifying default value.");
6478 }
6479 break;
6480
6481 case "ParenthesizedExpression":
6482 node.expression = this.toAssignable(node.expression, isBinding);
6483 break;
6484
6485 case "MemberExpression":
6486 if (!isBinding) break;
6487
6488 default:
6489 this.raise(node.start, "Assigning to rvalue");
6490 }
6491 }
6492 return node;
6493};
6494
6495// Convert list of expression atoms to binding list.
6496
6497pp.toAssignableList = function (exprList, isBinding) {
6498 var end = exprList.length;
6499 if (end) {
6500 var last = exprList[end - 1];
6501 if (last && last.type == "RestElement") {
6502 --end;
6503 } else if (last && last.type == "SpreadElement") {
6504 last.type = "RestElement";
6505 var arg = last.argument;
6506 this.toAssignable(arg, isBinding);
6507 if (arg.type !== "Identifier" && arg.type !== "MemberExpression" && arg.type !== "ArrayPattern") this.unexpected(arg.start);
6508 --end;
6509 }
6510 }
6511 for (var i = 0; i < end; i++) {
6512 var elt = exprList[i];
6513 if (elt) this.toAssignable(elt, isBinding);
6514 }
6515 return exprList;
6516};
6517
6518// Parses spread element.
6519
6520pp.parseSpread = function (refShorthandDefaultPos) {
6521 var node = this.startNode();
6522 this.next();
6523 node.argument = this.parseMaybeAssign(refShorthandDefaultPos);
6524 return this.finishNode(node, "SpreadElement");
6525};
6526
6527pp.parseRest = function () {
6528 var node = this.startNode();
6529 this.next();
6530 node.argument = this.type === tt.name || this.type === tt.bracketL ? this.parseBindingAtom() : this.unexpected();
6531 return this.finishNode(node, "RestElement");
6532};
6533
6534// Parses lvalue (assignable) atom.
6535
6536pp.parseBindingAtom = function () {
6537 if (this.options.ecmaVersion < 6) return this.parseIdent();
6538 switch (this.type) {
6539 case tt.name:
6540 return this.parseIdent();
6541
6542 case tt.bracketL:
6543 var node = this.startNode();
6544 this.next();
6545 node.elements = this.parseBindingList(tt.bracketR, true, true);
6546 return this.finishNode(node, "ArrayPattern");
6547
6548 case tt.braceL:
6549 return this.parseObj(true);
6550
6551 default:
6552 this.unexpected();
6553 }
6554};
6555
6556pp.parseBindingList = function (close, allowEmpty, allowTrailingComma) {
6557 var elts = [],
6558 first = true;
6559 while (!this.eat(close)) {
6560 if (first) first = false;else this.expect(tt.comma);
6561 if (allowEmpty && this.type === tt.comma) {
6562 elts.push(null);
6563 } else if (allowTrailingComma && this.afterTrailingComma(close)) {
6564 break;
6565 } else if (this.type === tt.ellipsis) {
6566 var rest = this.parseRest();
6567 this.parseBindingListItem(rest);
6568 elts.push(rest);
6569 this.expect(close);
6570 break;
6571 } else {
6572 var elem = this.parseMaybeDefault(this.start, this.startLoc);
6573 this.parseBindingListItem(elem);
6574 elts.push(elem);
6575 }
6576 }
6577 return elts;
6578};
6579
6580pp.parseBindingListItem = function (param) {
6581 return param;
6582};
6583
6584// Parses assignment pattern around given atom if possible.
6585
6586pp.parseMaybeDefault = function (startPos, startLoc, left) {
6587 if (Array.isArray(startPos)) {
6588 if (this.options.locations && noCalls === undefined) {
6589 // shift arguments to left by one
6590 left = startLoc;
6591 // flatten startPos
6592 startLoc = startPos[1];
6593 startPos = startPos[0];
6594 }
6595 }
6596 left = left || this.parseBindingAtom();
6597 if (!this.eat(tt.eq)) return left;
6598 var node = this.startNodeAt(startPos, startLoc);
6599 node.operator = "=";
6600 node.left = left;
6601 node.right = this.parseMaybeAssign();
6602 return this.finishNode(node, "AssignmentPattern");
6603};
6604
6605// Verify that a node is an lval — something that can be assigned
6606// to.
6607
6608pp.checkLVal = function (expr, isBinding, checkClashes) {
6609 switch (expr.type) {
6610 case "Identifier":
6611 if (this.strict && (reservedWords.strictBind(expr.name) || reservedWords.strict(expr.name))) this.raise(expr.start, (isBinding ? "Binding " : "Assigning to ") + expr.name + " in strict mode");
6612 if (checkClashes) {
6613 if (has(checkClashes, expr.name)) this.raise(expr.start, "Argument name clash in strict mode");
6614 checkClashes[expr.name] = true;
6615 }
6616 break;
6617
6618 case "MemberExpression":
6619 if (isBinding) this.raise(expr.start, (isBinding ? "Binding" : "Assigning to") + " member expression");
6620 break;
6621
6622 case "ObjectPattern":
6623 for (var i = 0; i < expr.properties.length; i++) {
6624 this.checkLVal(expr.properties[i].value, isBinding, checkClashes);
6625 }break;
6626
6627 case "ArrayPattern":
6628 for (var i = 0; i < expr.elements.length; i++) {
6629 var elem = expr.elements[i];
6630 if (elem) this.checkLVal(elem, isBinding, checkClashes);
6631 }
6632 break;
6633
6634 case "AssignmentPattern":
6635 this.checkLVal(expr.left, isBinding, checkClashes);
6636 break;
6637
6638 case "RestElement":
6639 this.checkLVal(expr.argument, isBinding, checkClashes);
6640 break;
6641
6642 case "ParenthesizedExpression":
6643 this.checkLVal(expr.expression, isBinding, checkClashes);
6644 break;
6645
6646 default:
6647 this.raise(expr.start, (isBinding ? "Binding" : "Assigning to") + " rvalue");
6648 }
6649};
6650
6651},{"./identifier":7,"./state":13,"./tokentype":17,"./util":18}],10:[function(_dereq_,module,exports){
6652"use strict";
6653
6654var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } };
6655
6656exports.__esModule = true;
6657
6658var Parser = _dereq_("./state").Parser;
6659
6660var SourceLocation = _dereq_("./location").SourceLocation;
6661
6662// Start an AST node, attaching a start offset.
6663
6664var pp = Parser.prototype;
6665
6666var Node = exports.Node = function Node() {
6667 _classCallCheck(this, Node);
6668};
6669
6670pp.startNode = function () {
6671 var node = new Node();
6672 node.start = this.start;
6673 if (this.options.locations) node.loc = new SourceLocation(this, this.startLoc);
6674 if (this.options.directSourceFile) node.sourceFile = this.options.directSourceFile;
6675 if (this.options.ranges) node.range = [this.start, 0];
6676 return node;
6677};
6678
6679pp.startNodeAt = function (pos, loc) {
6680 var node = new Node();
6681 if (Array.isArray(pos)) {
6682 if (this.options.locations && loc === undefined) {
6683 // flatten pos
6684 loc = pos[1];
6685 pos = pos[0];
6686 }
6687 }
6688 node.start = pos;
6689 if (this.options.locations) node.loc = new SourceLocation(this, loc);
6690 if (this.options.directSourceFile) node.sourceFile = this.options.directSourceFile;
6691 if (this.options.ranges) node.range = [pos, 0];
6692 return node;
6693};
6694
6695// Finish an AST node, adding `type` and `end` properties.
6696
6697pp.finishNode = function (node, type) {
6698 node.type = type;
6699 node.end = this.lastTokEnd;
6700 if (this.options.locations) node.loc.end = this.lastTokEndLoc;
6701 if (this.options.ranges) node.range[1] = this.lastTokEnd;
6702 return node;
6703};
6704
6705// Finish node at given position
6706
6707pp.finishNodeAt = function (node, type, pos, loc) {
6708 node.type = type;
6709 if (Array.isArray(pos)) {
6710 if (this.options.locations && loc === undefined) {
6711 // flatten pos
6712 loc = pos[1];
6713 pos = pos[0];
6714 }
6715 }
6716 node.end = pos;
6717 if (this.options.locations) node.loc.end = loc;
6718 if (this.options.ranges) node.range[1] = pos;
6719 return node;
6720};
6721
6722},{"./location":8,"./state":13}],11:[function(_dereq_,module,exports){
6723
6724
6725// Interpret and default an options object
6726
6727"use strict";
6728
6729exports.getOptions = getOptions;
6730exports.__esModule = true;
6731
6732var _util = _dereq_("./util");
6733
6734var has = _util.has;
6735var isArray = _util.isArray;
6736
6737var SourceLocation = _dereq_("./location").SourceLocation;
6738
6739// A second optional argument can be given to further configure
6740// the parser process. These options are recognized:
6741
6742var defaultOptions = {
6743 // `ecmaVersion` indicates the ECMAScript version to parse. Must
6744 // be either 3, or 5, or 6. This influences support for strict
6745 // mode, the set of reserved words, support for getters and
6746 // setters and other features.
6747 ecmaVersion: 5,
6748 // Source type ("script" or "module") for different semantics
6749 sourceType: "script",
6750 // `onInsertedSemicolon` can be a callback that will be called
6751 // when a semicolon is automatically inserted. It will be passed
6752 // th position of the comma as an offset, and if `locations` is
6753 // enabled, it is given the location as a `{line, column}` object
6754 // as second argument.
6755 onInsertedSemicolon: null,
6756 // `onTrailingComma` is similar to `onInsertedSemicolon`, but for
6757 // trailing commas.
6758 onTrailingComma: null,
6759 // By default, reserved words are not enforced. Disable
6760 // `allowReserved` to enforce them. When this option has the
6761 // value "never", reserved words and keywords can also not be
6762 // used as property names.
6763 allowReserved: true,
6764 // When enabled, a return at the top level is not considered an
6765 // error.
6766 allowReturnOutsideFunction: false,
6767 // When enabled, import/export statements are not constrained to
6768 // appearing at the top of the program.
6769 allowImportExportEverywhere: false,
6770 // When enabled, hashbang directive in the beginning of file
6771 // is allowed and treated as a line comment.
6772 allowHashBang: false,
6773 // When `locations` is on, `loc` properties holding objects with
6774 // `start` and `end` properties in `{line, column}` form (with
6775 // line being 1-based and column 0-based) will be attached to the
6776 // nodes.
6777 locations: false,
6778 // A function can be passed as `onToken` option, which will
6779 // cause Acorn to call that function with object in the same
6780 // format as tokenize() returns. Note that you are not
6781 // allowed to call the parser from the callback—that will
6782 // corrupt its internal state.
6783 onToken: null,
6784 // A function can be passed as `onComment` option, which will
6785 // cause Acorn to call that function with `(block, text, start,
6786 // end)` parameters whenever a comment is skipped. `block` is a
6787 // boolean indicating whether this is a block (`/* */`) comment,
6788 // `text` is the content of the comment, and `start` and `end` are
6789 // character offsets that denote the start and end of the comment.
6790 // When the `locations` option is on, two more parameters are
6791 // passed, the full `{line, column}` locations of the start and
6792 // end of the comments. Note that you are not allowed to call the
6793 // parser from the callback—that will corrupt its internal state.
6794 onComment: null,
6795 // Nodes have their start and end characters offsets recorded in
6796 // `start` and `end` properties (directly on the node, rather than
6797 // the `loc` object, which holds line/column data. To also add a
6798 // [semi-standardized][range] `range` property holding a `[start,
6799 // end]` array with the same numbers, set the `ranges` option to
6800 // `true`.
6801 //
6802 // [range]: https://bugzilla.mozilla.org/show_bug.cgi?id=745678
6803 ranges: false,
6804 // It is possible to parse multiple files into a single AST by
6805 // passing the tree produced by parsing the first file as
6806 // `program` option in subsequent parses. This will add the
6807 // toplevel forms of the parsed file to the `Program` (top) node
6808 // of an existing parse tree.
6809 program: null,
6810 // When `locations` is on, you can pass this to record the source
6811 // file in every node's `loc` object.
6812 sourceFile: null,
6813 // This value, if given, is stored in every node, whether
6814 // `locations` is on or off.
6815 directSourceFile: null,
6816 // When enabled, parenthesized expressions are represented by
6817 // (non-standard) ParenthesizedExpression nodes
6818 preserveParens: false,
6819 plugins: {}
6820};exports.defaultOptions = defaultOptions;
6821
6822function getOptions(opts) {
6823 var options = {};
6824 for (var opt in defaultOptions) {
6825 options[opt] = opts && has(opts, opt) ? opts[opt] : defaultOptions[opt];
6826 }if (isArray(options.onToken)) {
6827 (function () {
6828 var tokens = options.onToken;
6829 options.onToken = function (token) {
6830 return tokens.push(token);
6831 };
6832 })();
6833 }
6834 if (isArray(options.onComment)) options.onComment = pushComment(options, options.onComment);
6835
6836 return options;
6837}
6838
6839function pushComment(options, array) {
6840 return function (block, text, start, end, startLoc, endLoc) {
6841 var comment = {
6842 type: block ? "Block" : "Line",
6843 value: text,
6844 start: start,
6845 end: end
6846 };
6847 if (options.locations) comment.loc = new SourceLocation(this, startLoc, endLoc);
6848 if (options.ranges) comment.range = [start, end];
6849 array.push(comment);
6850 };
6851}
6852
6853},{"./location":8,"./util":18}],12:[function(_dereq_,module,exports){
6854"use strict";
6855
6856var tt = _dereq_("./tokentype").types;
6857
6858var Parser = _dereq_("./state").Parser;
6859
6860var lineBreak = _dereq_("./whitespace").lineBreak;
6861
6862var pp = Parser.prototype;
6863
6864// ## Parser utilities
6865
6866// Test whether a statement node is the string literal `"use strict"`.
6867
6868pp.isUseStrict = function (stmt) {
6869 return this.options.ecmaVersion >= 5 && stmt.type === "ExpressionStatement" && stmt.expression.type === "Literal" && stmt.expression.value === "use strict";
6870};
6871
6872// Predicate that tests whether the next token is of the given
6873// type, and if yes, consumes it as a side effect.
6874
6875pp.eat = function (type) {
6876 if (this.type === type) {
6877 this.next();
6878 return true;
6879 } else {
6880 return false;
6881 }
6882};
6883
6884// Tests whether parsed token is a contextual keyword.
6885
6886pp.isContextual = function (name) {
6887 return this.type === tt.name && this.value === name;
6888};
6889
6890// Consumes contextual keyword if possible.
6891
6892pp.eatContextual = function (name) {
6893 return this.value === name && this.eat(tt.name);
6894};
6895
6896// Asserts that following token is given contextual keyword.
6897
6898pp.expectContextual = function (name) {
6899 if (!this.eatContextual(name)) this.unexpected();
6900};
6901
6902// Test whether a semicolon can be inserted at the current position.
6903
6904pp.canInsertSemicolon = function () {
6905 return this.type === tt.eof || this.type === tt.braceR || lineBreak.test(this.input.slice(this.lastTokEnd, this.start));
6906};
6907
6908pp.insertSemicolon = function () {
6909 if (this.canInsertSemicolon()) {
6910 if (this.options.onInsertedSemicolon) this.options.onInsertedSemicolon(this.lastTokEnd, this.lastTokEndLoc);
6911 return true;
6912 }
6913};
6914
6915// Consume a semicolon, or, failing that, see if we are allowed to
6916// pretend that there is a semicolon at this position.
6917
6918pp.semicolon = function () {
6919 if (!this.eat(tt.semi) && !this.insertSemicolon()) this.unexpected();
6920};
6921
6922pp.afterTrailingComma = function (tokType) {
6923 if (this.type == tokType) {
6924 if (this.options.onTrailingComma) this.options.onTrailingComma(this.lastTokStart, this.lastTokStartLoc);
6925 this.next();
6926 return true;
6927 }
6928};
6929
6930// Expect a token of a given type. If found, consume it, otherwise,
6931// raise an unexpected token error.
6932
6933pp.expect = function (type) {
6934 this.eat(type) || this.unexpected();
6935};
6936
6937// Raise an unexpected token error.
6938
6939pp.unexpected = function (pos) {
6940 this.raise(pos != null ? pos : this.start, "Unexpected token");
6941};
6942
6943},{"./state":13,"./tokentype":17,"./whitespace":19}],13:[function(_dereq_,module,exports){
6944"use strict";
6945
6946exports.Parser = Parser;
6947exports.__esModule = true;
6948
6949var _identifier = _dereq_("./identifier");
6950
6951var reservedWords = _identifier.reservedWords;
6952var keywords = _identifier.keywords;
6953
6954var tt = _dereq_("./tokentype").types;
6955
6956var lineBreak = _dereq_("./whitespace").lineBreak;
6957
6958function Parser(options, input, startPos) {
6959 this.options = options;
6960 this.sourceFile = this.options.sourceFile || null;
6961 this.isKeyword = keywords[this.options.ecmaVersion >= 6 ? 6 : 5];
6962 this.isReservedWord = reservedWords[this.options.ecmaVersion];
6963 this.input = input;
6964
6965 // Load plugins
6966 this.loadPlugins(this.options.plugins);
6967
6968 // Set up token state
6969
6970 // The current position of the tokenizer in the input.
6971 if (startPos) {
6972 this.pos = startPos;
6973 this.lineStart = Math.max(0, this.input.lastIndexOf("\n", startPos));
6974 this.curLine = this.input.slice(0, this.lineStart).split(lineBreak).length;
6975 } else {
6976 this.pos = this.lineStart = 0;
6977 this.curLine = 1;
6978 }
6979
6980 // Properties of the current token:
6981 // Its type
6982 this.type = tt.eof;
6983 // For tokens that include more information than their type, the value
6984 this.value = null;
6985 // Its start and end offset
6986 this.start = this.end = this.pos;
6987 // And, if locations are used, the {line, column} object
6988 // corresponding to those offsets
6989 this.startLoc = this.endLoc = null;
6990
6991 // Position information for the previous token
6992 this.lastTokEndLoc = this.lastTokStartLoc = null;
6993 this.lastTokStart = this.lastTokEnd = this.pos;
6994
6995 // The context stack is used to superficially track syntactic
6996 // context to predict whether a regular expression is allowed in a
6997 // given position.
6998 this.context = this.initialContext();
6999 this.exprAllowed = true;
7000
7001 // Figure out if it's a module code.
7002 this.strict = this.inModule = this.options.sourceType === "module";
7003
7004 // Used to signify the start of a potential arrow function
7005 this.potentialArrowAt = -1;
7006
7007 // Flags to track whether we are in a function, a generator.
7008 this.inFunction = this.inGenerator = false;
7009 // Labels in scope.
7010 this.labels = [];
7011
7012 // If enabled, skip leading hashbang line.
7013 if (this.pos === 0 && this.options.allowHashBang && this.input.slice(0, 2) === "#!") this.skipLineComment(2);
7014}
7015
7016Parser.prototype.extend = function (name, f) {
7017 this[name] = f(this[name]);
7018};
7019
7020// Registered plugins
7021
7022var plugins = {};
7023
7024exports.plugins = plugins;
7025Parser.prototype.loadPlugins = function (plugins) {
7026 for (var _name in plugins) {
7027 var plugin = exports.plugins[_name];
7028 if (!plugin) throw new Error("Plugin '" + _name + "' not found");
7029 plugin(this, plugins[_name]);
7030 }
7031};
7032
7033},{"./identifier":7,"./tokentype":17,"./whitespace":19}],14:[function(_dereq_,module,exports){
7034"use strict";
7035
7036var tt = _dereq_("./tokentype").types;
7037
7038var Parser = _dereq_("./state").Parser;
7039
7040var lineBreak = _dereq_("./whitespace").lineBreak;
7041
7042var pp = Parser.prototype;
7043
7044// ### Statement parsing
7045
7046// Parse a program. Initializes the parser, reads any number of
7047// statements, and wraps them in a Program node. Optionally takes a
7048// `program` argument. If present, the statements will be appended
7049// to its body instead of creating a new node.
7050
7051pp.parseTopLevel = function (node) {
7052 var first = true;
7053 if (!node.body) node.body = [];
7054 while (this.type !== tt.eof) {
7055 var stmt = this.parseStatement(true, true);
7056 node.body.push(stmt);
7057 if (first && this.isUseStrict(stmt)) this.setStrict(true);
7058 first = false;
7059 }
7060 this.next();
7061 if (this.options.ecmaVersion >= 6) {
7062 node.sourceType = this.options.sourceType;
7063 }
7064 return this.finishNode(node, "Program");
7065};
7066
7067var loopLabel = { kind: "loop" },
7068 switchLabel = { kind: "switch" };
7069
7070// Parse a single statement.
7071//
7072// If expecting a statement and finding a slash operator, parse a
7073// regular expression literal. This is to handle cases like
7074// `if (foo) /blah/.exec(foo)`, where looking at the previous token
7075// does not help.
7076
7077pp.parseStatement = function (declaration, topLevel) {
7078 var starttype = this.type,
7079 node = this.startNode();
7080
7081 // Most types of statements are recognized by the keyword they
7082 // start with. Many are trivial to parse, some require a bit of
7083 // complexity.
7084
7085 switch (starttype) {
7086 case tt._break:case tt._continue:
7087 return this.parseBreakContinueStatement(node, starttype.keyword);
7088 case tt._debugger:
7089 return this.parseDebuggerStatement(node);
7090 case tt._do:
7091 return this.parseDoStatement(node);
7092 case tt._for:
7093 return this.parseForStatement(node);
7094 case tt._function:
7095 if (!declaration && this.options.ecmaVersion >= 6) this.unexpected();
7096 return this.parseFunctionStatement(node);
7097 case tt._class:
7098 if (!declaration) this.unexpected();
7099 return this.parseClass(node, true);
7100 case tt._if:
7101 return this.parseIfStatement(node);
7102 case tt._return:
7103 return this.parseReturnStatement(node);
7104 case tt._switch:
7105 return this.parseSwitchStatement(node);
7106 case tt._throw:
7107 return this.parseThrowStatement(node);
7108 case tt._try:
7109 return this.parseTryStatement(node);
7110 case tt._let:case tt._const:
7111 if (!declaration) this.unexpected(); // NOTE: falls through to _var
7112 case tt._var:
7113 return this.parseVarStatement(node, starttype);
7114 case tt._while:
7115 return this.parseWhileStatement(node);
7116 case tt._with:
7117 return this.parseWithStatement(node);
7118 case tt.braceL:
7119 return this.parseBlock();
7120 case tt.semi:
7121 return this.parseEmptyStatement(node);
7122 case tt._export:
7123 case tt._import:
7124 if (!this.options.allowImportExportEverywhere) {
7125 if (!topLevel) this.raise(this.start, "'import' and 'export' may only appear at the top level");
7126 if (!this.inModule) this.raise(this.start, "'import' and 'export' may appear only with 'sourceType: module'");
7127 }
7128 return starttype === tt._import ? this.parseImport(node) : this.parseExport(node);
7129
7130 // If the statement does not start with a statement keyword or a
7131 // brace, it's an ExpressionStatement or LabeledStatement. We
7132 // simply start parsing an expression, and afterwards, if the
7133 // next token is a colon and the expression was a simple
7134 // Identifier node, we switch to interpreting it as a label.
7135 default:
7136 var maybeName = this.value,
7137 expr = this.parseExpression();
7138 if (starttype === tt.name && expr.type === "Identifier" && this.eat(tt.colon)) return this.parseLabeledStatement(node, maybeName, expr);else return this.parseExpressionStatement(node, expr);
7139 }
7140};
7141
7142pp.parseBreakContinueStatement = function (node, keyword) {
7143 var isBreak = keyword == "break";
7144 this.next();
7145 if (this.eat(tt.semi) || this.insertSemicolon()) node.label = null;else if (this.type !== tt.name) this.unexpected();else {
7146 node.label = this.parseIdent();
7147 this.semicolon();
7148 }
7149
7150 // Verify that there is an actual destination to break or
7151 // continue to.
7152 for (var i = 0; i < this.labels.length; ++i) {
7153 var lab = this.labels[i];
7154 if (node.label == null || lab.name === node.label.name) {
7155 if (lab.kind != null && (isBreak || lab.kind === "loop")) break;
7156 if (node.label && isBreak) break;
7157 }
7158 }
7159 if (i === this.labels.length) this.raise(node.start, "Unsyntactic " + keyword);
7160 return this.finishNode(node, isBreak ? "BreakStatement" : "ContinueStatement");
7161};
7162
7163pp.parseDebuggerStatement = function (node) {
7164 this.next();
7165 this.semicolon();
7166 return this.finishNode(node, "DebuggerStatement");
7167};
7168
7169pp.parseDoStatement = function (node) {
7170 this.next();
7171 this.labels.push(loopLabel);
7172 node.body = this.parseStatement(false);
7173 this.labels.pop();
7174 this.expect(tt._while);
7175 node.test = this.parseParenExpression();
7176 if (this.options.ecmaVersion >= 6) this.eat(tt.semi);else this.semicolon();
7177 return this.finishNode(node, "DoWhileStatement");
7178};
7179
7180// Disambiguating between a `for` and a `for`/`in` or `for`/`of`
7181// loop is non-trivial. Basically, we have to parse the init `var`
7182// statement or expression, disallowing the `in` operator (see
7183// the second parameter to `parseExpression`), and then check
7184// whether the next token is `in` or `of`. When there is no init
7185// part (semicolon immediately after the opening parenthesis), it
7186// is a regular `for` loop.
7187
7188pp.parseForStatement = function (node) {
7189 this.next();
7190 this.labels.push(loopLabel);
7191 this.expect(tt.parenL);
7192 if (this.type === tt.semi) return this.parseFor(node, null);
7193 if (this.type === tt._var || this.type === tt._let || this.type === tt._const) {
7194 var _init = this.startNode(),
7195 varKind = this.type;
7196 this.next();
7197 this.parseVar(_init, true, varKind);
7198 this.finishNode(_init, "VariableDeclaration");
7199 if ((this.type === tt._in || this.options.ecmaVersion >= 6 && this.isContextual("of")) && _init.declarations.length === 1 && !(varKind !== tt._var && _init.declarations[0].init)) return this.parseForIn(node, _init);
7200 return this.parseFor(node, _init);
7201 }
7202 var refShorthandDefaultPos = { start: 0 };
7203 var init = this.parseExpression(true, refShorthandDefaultPos);
7204 if (this.type === tt._in || this.options.ecmaVersion >= 6 && this.isContextual("of")) {
7205 this.toAssignable(init);
7206 this.checkLVal(init);
7207 return this.parseForIn(node, init);
7208 } else if (refShorthandDefaultPos.start) {
7209 this.unexpected(refShorthandDefaultPos.start);
7210 }
7211 return this.parseFor(node, init);
7212};
7213
7214pp.parseFunctionStatement = function (node) {
7215 this.next();
7216 return this.parseFunction(node, true);
7217};
7218
7219pp.parseIfStatement = function (node) {
7220 this.next();
7221 node.test = this.parseParenExpression();
7222 node.consequent = this.parseStatement(false);
7223 node.alternate = this.eat(tt._else) ? this.parseStatement(false) : null;
7224 return this.finishNode(node, "IfStatement");
7225};
7226
7227pp.parseReturnStatement = function (node) {
7228 if (!this.inFunction && !this.options.allowReturnOutsideFunction) this.raise(this.start, "'return' outside of function");
7229 this.next();
7230
7231 // In `return` (and `break`/`continue`), the keywords with
7232 // optional arguments, we eagerly look for a semicolon or the
7233 // possibility to insert one.
7234
7235 if (this.eat(tt.semi) || this.insertSemicolon()) node.argument = null;else {
7236 node.argument = this.parseExpression();this.semicolon();
7237 }
7238 return this.finishNode(node, "ReturnStatement");
7239};
7240
7241pp.parseSwitchStatement = function (node) {
7242 this.next();
7243 node.discriminant = this.parseParenExpression();
7244 node.cases = [];
7245 this.expect(tt.braceL);
7246 this.labels.push(switchLabel);
7247
7248 // Statements under must be grouped (by label) in SwitchCase
7249 // nodes. `cur` is used to keep the node that we are currently
7250 // adding statements to.
7251
7252 for (var cur, sawDefault; this.type != tt.braceR;) {
7253 if (this.type === tt._case || this.type === tt._default) {
7254 var isCase = this.type === tt._case;
7255 if (cur) this.finishNode(cur, "SwitchCase");
7256 node.cases.push(cur = this.startNode());
7257 cur.consequent = [];
7258 this.next();
7259 if (isCase) {
7260 cur.test = this.parseExpression();
7261 } else {
7262 if (sawDefault) this.raise(this.lastTokStart, "Multiple default clauses");
7263 sawDefault = true;
7264 cur.test = null;
7265 }
7266 this.expect(tt.colon);
7267 } else {
7268 if (!cur) this.unexpected();
7269 cur.consequent.push(this.parseStatement(true));
7270 }
7271 }
7272 if (cur) this.finishNode(cur, "SwitchCase");
7273 this.next(); // Closing brace
7274 this.labels.pop();
7275 return this.finishNode(node, "SwitchStatement");
7276};
7277
7278pp.parseThrowStatement = function (node) {
7279 this.next();
7280 if (lineBreak.test(this.input.slice(this.lastTokEnd, this.start))) this.raise(this.lastTokEnd, "Illegal newline after throw");
7281 node.argument = this.parseExpression();
7282 this.semicolon();
7283 return this.finishNode(node, "ThrowStatement");
7284};
7285
7286// Reused empty array added for node fields that are always empty.
7287
7288var empty = [];
7289
7290pp.parseTryStatement = function (node) {
7291 this.next();
7292 node.block = this.parseBlock();
7293 node.handler = null;
7294 if (this.type === tt._catch) {
7295 var clause = this.startNode();
7296 this.next();
7297 this.expect(tt.parenL);
7298 clause.param = this.parseBindingAtom();
7299 this.checkLVal(clause.param, true);
7300 this.expect(tt.parenR);
7301 clause.guard = null;
7302 clause.body = this.parseBlock();
7303 node.handler = this.finishNode(clause, "CatchClause");
7304 }
7305 node.guardedHandlers = empty;
7306 node.finalizer = this.eat(tt._finally) ? this.parseBlock() : null;
7307 if (!node.handler && !node.finalizer) this.raise(node.start, "Missing catch or finally clause");
7308 return this.finishNode(node, "TryStatement");
7309};
7310
7311pp.parseVarStatement = function (node, kind) {
7312 this.next();
7313 this.parseVar(node, false, kind);
7314 this.semicolon();
7315 return this.finishNode(node, "VariableDeclaration");
7316};
7317
7318pp.parseWhileStatement = function (node) {
7319 this.next();
7320 node.test = this.parseParenExpression();
7321 this.labels.push(loopLabel);
7322 node.body = this.parseStatement(false);
7323 this.labels.pop();
7324 return this.finishNode(node, "WhileStatement");
7325};
7326
7327pp.parseWithStatement = function (node) {
7328 if (this.strict) this.raise(this.start, "'with' in strict mode");
7329 this.next();
7330 node.object = this.parseParenExpression();
7331 node.body = this.parseStatement(false);
7332 return this.finishNode(node, "WithStatement");
7333};
7334
7335pp.parseEmptyStatement = function (node) {
7336 this.next();
7337 return this.finishNode(node, "EmptyStatement");
7338};
7339
7340pp.parseLabeledStatement = function (node, maybeName, expr) {
7341 for (var i = 0; i < this.labels.length; ++i) {
7342 if (this.labels[i].name === maybeName) this.raise(expr.start, "Label '" + maybeName + "' is already declared");
7343 }var kind = this.type.isLoop ? "loop" : this.type === tt._switch ? "switch" : null;
7344 this.labels.push({ name: maybeName, kind: kind });
7345 node.body = this.parseStatement(true);
7346 this.labels.pop();
7347 node.label = expr;
7348 return this.finishNode(node, "LabeledStatement");
7349};
7350
7351pp.parseExpressionStatement = function (node, expr) {
7352 node.expression = expr;
7353 this.semicolon();
7354 return this.finishNode(node, "ExpressionStatement");
7355};
7356
7357// Parse a semicolon-enclosed block of statements, handling `"use
7358// strict"` declarations when `allowStrict` is true (used for
7359// function bodies).
7360
7361pp.parseBlock = function (allowStrict) {
7362 var node = this.startNode(),
7363 first = true,
7364 oldStrict = undefined;
7365 node.body = [];
7366 this.expect(tt.braceL);
7367 while (!this.eat(tt.braceR)) {
7368 var stmt = this.parseStatement(true);
7369 node.body.push(stmt);
7370 if (first && allowStrict && this.isUseStrict(stmt)) {
7371 oldStrict = this.strict;
7372 this.setStrict(this.strict = true);
7373 }
7374 first = false;
7375 }
7376 if (oldStrict === false) this.setStrict(false);
7377 return this.finishNode(node, "BlockStatement");
7378};
7379
7380// Parse a regular `for` loop. The disambiguation code in
7381// `parseStatement` will already have parsed the init statement or
7382// expression.
7383
7384pp.parseFor = function (node, init) {
7385 node.init = init;
7386 this.expect(tt.semi);
7387 node.test = this.type === tt.semi ? null : this.parseExpression();
7388 this.expect(tt.semi);
7389 node.update = this.type === tt.parenR ? null : this.parseExpression();
7390 this.expect(tt.parenR);
7391 node.body = this.parseStatement(false);
7392 this.labels.pop();
7393 return this.finishNode(node, "ForStatement");
7394};
7395
7396// Parse a `for`/`in` and `for`/`of` loop, which are almost
7397// same from parser's perspective.
7398
7399pp.parseForIn = function (node, init) {
7400 var type = this.type === tt._in ? "ForInStatement" : "ForOfStatement";
7401 this.next();
7402 node.left = init;
7403 node.right = this.parseExpression();
7404 this.expect(tt.parenR);
7405 node.body = this.parseStatement(false);
7406 this.labels.pop();
7407 return this.finishNode(node, type);
7408};
7409
7410// Parse a list of variable declarations.
7411
7412pp.parseVar = function (node, isFor, kind) {
7413 node.declarations = [];
7414 node.kind = kind.keyword;
7415 for (;;) {
7416 var decl = this.startNode();
7417 this.parseVarId(decl);
7418 if (this.eat(tt.eq)) {
7419 decl.init = this.parseMaybeAssign(isFor);
7420 } else if (kind === tt._const && !(this.type === tt._in || this.options.ecmaVersion >= 6 && this.isContextual("of"))) {
7421 this.unexpected();
7422 } else if (decl.id.type != "Identifier" && !(isFor && (this.type === tt._in || this.isContextual("of")))) {
7423 this.raise(this.lastTokEnd, "Complex binding patterns require an initialization value");
7424 } else {
7425 decl.init = null;
7426 }
7427 node.declarations.push(this.finishNode(decl, "VariableDeclarator"));
7428 if (!this.eat(tt.comma)) break;
7429 }
7430 return node;
7431};
7432
7433pp.parseVarId = function (decl) {
7434 decl.id = this.parseBindingAtom();
7435 this.checkLVal(decl.id, true);
7436};
7437
7438// Parse a function declaration or literal (depending on the
7439// `isStatement` parameter).
7440
7441pp.parseFunction = function (node, isStatement, allowExpressionBody) {
7442 this.initFunction(node);
7443 if (this.options.ecmaVersion >= 6) node.generator = this.eat(tt.star);
7444 if (isStatement || this.type === tt.name) node.id = this.parseIdent();
7445 this.parseFunctionParams(node);
7446 this.parseFunctionBody(node, allowExpressionBody);
7447 return this.finishNode(node, isStatement ? "FunctionDeclaration" : "FunctionExpression");
7448};
7449
7450pp.parseFunctionParams = function (node) {
7451 this.expect(tt.parenL);
7452 node.params = this.parseBindingList(tt.parenR, false, false);
7453};
7454
7455// Parse a class declaration or literal (depending on the
7456// `isStatement` parameter).
7457
7458pp.parseClass = function (node, isStatement) {
7459 this.next();
7460 this.parseClassId(node, isStatement);
7461 this.parseClassSuper(node);
7462 var classBody = this.startNode();
7463 var hadConstructor = false;
7464 classBody.body = [];
7465 this.expect(tt.braceL);
7466 while (!this.eat(tt.braceR)) {
7467 if (this.eat(tt.semi)) continue;
7468 var method = this.startNode();
7469 var isGenerator = this.eat(tt.star);
7470 var isMaybeStatic = this.type === tt.name && this.value === "static";
7471 this.parsePropertyName(method);
7472 method["static"] = isMaybeStatic && this.type !== tt.parenL;
7473 if (method["static"]) {
7474 if (isGenerator) this.unexpected();
7475 isGenerator = this.eat(tt.star);
7476 this.parsePropertyName(method);
7477 }
7478 method.kind = "method";
7479 if (!method.computed) {
7480 var key = method.key;
7481
7482 var isGetSet = false;
7483 if (!isGenerator && key.type === "Identifier" && this.type !== tt.parenL && (key.name === "get" || key.name === "set")) {
7484 isGetSet = true;
7485 method.kind = key.name;
7486 key = this.parsePropertyName(method);
7487 }
7488 if (!method["static"] && (key.type === "Identifier" && key.name === "constructor" || key.type === "Literal" && key.value === "constructor")) {
7489 if (hadConstructor) this.raise(key.start, "Duplicate constructor in the same class");
7490 if (isGetSet) this.raise(key.start, "Constructor can't have get/set modifier");
7491 if (isGenerator) this.raise(key.start, "Constructor can't be a generator");
7492 method.kind = "constructor";
7493 hadConstructor = true;
7494 }
7495 }
7496 this.parseClassMethod(classBody, method, isGenerator);
7497 }
7498 node.body = this.finishNode(classBody, "ClassBody");
7499 return this.finishNode(node, isStatement ? "ClassDeclaration" : "ClassExpression");
7500};
7501
7502pp.parseClassMethod = function (classBody, method, isGenerator) {
7503 method.value = this.parseMethod(isGenerator);
7504 classBody.body.push(this.finishNode(method, "MethodDefinition"));
7505};
7506
7507pp.parseClassId = function (node, isStatement) {
7508 node.id = this.type === tt.name ? this.parseIdent() : isStatement ? this.unexpected() : null;
7509};
7510
7511pp.parseClassSuper = function (node) {
7512 node.superClass = this.eat(tt._extends) ? this.parseExprSubscripts() : null;
7513};
7514
7515// Parses module export declaration.
7516
7517pp.parseExport = function (node) {
7518 this.next();
7519 // export * from '...'
7520 if (this.eat(tt.star)) {
7521 this.expectContextual("from");
7522 node.source = this.type === tt.string ? this.parseExprAtom() : this.unexpected();
7523 this.semicolon();
7524 return this.finishNode(node, "ExportAllDeclaration");
7525 }
7526 if (this.eat(tt._default)) {
7527 // export default ...
7528 var expr = this.parseMaybeAssign();
7529 var needsSemi = true;
7530 if (expr.type == "FunctionExpression" || expr.type == "ClassExpression") {
7531 needsSemi = false;
7532 if (expr.id) {
7533 expr.type = expr.type == "FunctionExpression" ? "FunctionDeclaration" : "ClassDeclaration";
7534 }
7535 }
7536 node.declaration = expr;
7537 if (needsSemi) this.semicolon();
7538 return this.finishNode(node, "ExportDefaultDeclaration");
7539 }
7540 // export var|const|let|function|class ...
7541 if (this.shouldParseExportStatement()) {
7542 node.declaration = this.parseStatement(true);
7543 node.specifiers = [];
7544 node.source = null;
7545 } else {
7546 // export { x, y as z } [from '...']
7547 node.declaration = null;
7548 node.specifiers = this.parseExportSpecifiers();
7549 if (this.eatContextual("from")) {
7550 node.source = this.type === tt.string ? this.parseExprAtom() : this.unexpected();
7551 } else {
7552 node.source = null;
7553 }
7554 this.semicolon();
7555 }
7556 return this.finishNode(node, "ExportNamedDeclaration");
7557};
7558
7559pp.shouldParseExportStatement = function () {
7560 return this.type.keyword;
7561};
7562
7563// Parses a comma-separated list of module exports.
7564
7565pp.parseExportSpecifiers = function () {
7566 var nodes = [],
7567 first = true;
7568 // export { x, y as z } [from '...']
7569 this.expect(tt.braceL);
7570 while (!this.eat(tt.braceR)) {
7571 if (!first) {
7572 this.expect(tt.comma);
7573 if (this.afterTrailingComma(tt.braceR)) break;
7574 } else first = false;
7575
7576 var node = this.startNode();
7577 node.local = this.parseIdent(this.type === tt._default);
7578 node.exported = this.eatContextual("as") ? this.parseIdent(true) : node.local;
7579 nodes.push(this.finishNode(node, "ExportSpecifier"));
7580 }
7581 return nodes;
7582};
7583
7584// Parses import declaration.
7585
7586pp.parseImport = function (node) {
7587 this.next();
7588 // import '...'
7589 if (this.type === tt.string) {
7590 node.specifiers = empty;
7591 node.source = this.parseExprAtom();
7592 node.kind = "";
7593 } else {
7594 node.specifiers = this.parseImportSpecifiers();
7595 this.expectContextual("from");
7596 node.source = this.type === tt.string ? this.parseExprAtom() : this.unexpected();
7597 }
7598 this.semicolon();
7599 return this.finishNode(node, "ImportDeclaration");
7600};
7601
7602// Parses a comma-separated list of module imports.
7603
7604pp.parseImportSpecifiers = function () {
7605 var nodes = [],
7606 first = true;
7607 if (this.type === tt.name) {
7608 // import defaultObj, { x, y as z } from '...'
7609 var node = this.startNode();
7610 node.local = this.parseIdent();
7611 this.checkLVal(node.local, true);
7612 nodes.push(this.finishNode(node, "ImportDefaultSpecifier"));
7613 if (!this.eat(tt.comma)) return nodes;
7614 }
7615 if (this.type === tt.star) {
7616 var node = this.startNode();
7617 this.next();
7618 this.expectContextual("as");
7619 node.local = this.parseIdent();
7620 this.checkLVal(node.local, true);
7621 nodes.push(this.finishNode(node, "ImportNamespaceSpecifier"));
7622 return nodes;
7623 }
7624 this.expect(tt.braceL);
7625 while (!this.eat(tt.braceR)) {
7626 if (!first) {
7627 this.expect(tt.comma);
7628 if (this.afterTrailingComma(tt.braceR)) break;
7629 } else first = false;
7630
7631 var node = this.startNode();
7632 node.imported = this.parseIdent(true);
7633 node.local = this.eatContextual("as") ? this.parseIdent() : node.imported;
7634 this.checkLVal(node.local, true);
7635 nodes.push(this.finishNode(node, "ImportSpecifier"));
7636 }
7637 return nodes;
7638};
7639
7640},{"./state":13,"./tokentype":17,"./whitespace":19}],15:[function(_dereq_,module,exports){
7641"use strict";
7642
7643var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } };
7644
7645exports.__esModule = true;
7646// The algorithm used to determine whether a regexp can appear at a
7647// given point in the program is loosely based on sweet.js' approach.
7648// See https://github.com/mozilla/sweet.js/wiki/design
7649
7650var Parser = _dereq_("./state").Parser;
7651
7652var tt = _dereq_("./tokentype").types;
7653
7654var lineBreak = _dereq_("./whitespace").lineBreak;
7655
7656var TokContext = exports.TokContext = function TokContext(token, isExpr, preserveSpace, override) {
7657 _classCallCheck(this, TokContext);
7658
7659 this.token = token;
7660 this.isExpr = isExpr;
7661 this.preserveSpace = preserveSpace;
7662 this.override = override;
7663};
7664
7665var types = {
7666 b_stat: new TokContext("{", false),
7667 b_expr: new TokContext("{", true),
7668 b_tmpl: new TokContext("${", true),
7669 p_stat: new TokContext("(", false),
7670 p_expr: new TokContext("(", true),
7671 q_tmpl: new TokContext("`", true, true, function (p) {
7672 return p.readTmplToken();
7673 }),
7674 f_expr: new TokContext("function", true)
7675};
7676
7677exports.types = types;
7678var pp = Parser.prototype;
7679
7680pp.initialContext = function () {
7681 return [types.b_stat];
7682};
7683
7684pp.braceIsBlock = function (prevType) {
7685 var parent = undefined;
7686 if (prevType === tt.colon && (parent = this.curContext()).token == "{") return !parent.isExpr;
7687 if (prevType === tt._return) return lineBreak.test(this.input.slice(this.lastTokEnd, this.start));
7688 if (prevType === tt._else || prevType === tt.semi || prevType === tt.eof) return true;
7689 if (prevType == tt.braceL) return this.curContext() === types.b_stat;
7690 return !this.exprAllowed;
7691};
7692
7693pp.updateContext = function (prevType) {
7694 var update = undefined,
7695 type = this.type;
7696 if (type.keyword && prevType == tt.dot) this.exprAllowed = false;else if (update = type.updateContext) update.call(this, prevType);else this.exprAllowed = type.beforeExpr;
7697};
7698
7699// Token-specific context update code
7700
7701tt.parenR.updateContext = tt.braceR.updateContext = function () {
7702 if (this.context.length == 1) {
7703 this.exprAllowed = true;
7704 return;
7705 }
7706 var out = this.context.pop();
7707 if (out === types.b_stat && this.curContext() === types.f_expr) {
7708 this.context.pop();
7709 this.exprAllowed = false;
7710 } else if (out === types.b_tmpl) {
7711 this.exprAllowed = true;
7712 } else {
7713 this.exprAllowed = !out.isExpr;
7714 }
7715};
7716
7717tt.braceL.updateContext = function (prevType) {
7718 this.context.push(this.braceIsBlock(prevType) ? types.b_stat : types.b_expr);
7719 this.exprAllowed = true;
7720};
7721
7722tt.dollarBraceL.updateContext = function () {
7723 this.context.push(types.b_tmpl);
7724 this.exprAllowed = true;
7725};
7726
7727tt.parenL.updateContext = function (prevType) {
7728 var statementParens = prevType === tt._if || prevType === tt._for || prevType === tt._with || prevType === tt._while;
7729 this.context.push(statementParens ? types.p_stat : types.p_expr);
7730 this.exprAllowed = true;
7731};
7732
7733tt.incDec.updateContext = function () {};
7734
7735tt._function.updateContext = function () {
7736 if (this.curContext() !== types.b_stat) this.context.push(types.f_expr);
7737 this.exprAllowed = false;
7738};
7739
7740tt.backQuote.updateContext = function () {
7741 if (this.curContext() === types.q_tmpl) this.context.pop();else this.context.push(types.q_tmpl);
7742 this.exprAllowed = false;
7743};
7744
7745// tokExprAllowed stays unchanged
7746
7747},{"./state":13,"./tokentype":17,"./whitespace":19}],16:[function(_dereq_,module,exports){
7748"use strict";
7749
7750var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } };
7751
7752exports.__esModule = true;
7753
7754var _identifier = _dereq_("./identifier");
7755
7756var isIdentifierStart = _identifier.isIdentifierStart;
7757var isIdentifierChar = _identifier.isIdentifierChar;
7758
7759var _tokentype = _dereq_("./tokentype");
7760
7761var tt = _tokentype.types;
7762var keywordTypes = _tokentype.keywords;
7763
7764var Parser = _dereq_("./state").Parser;
7765
7766var SourceLocation = _dereq_("./location").SourceLocation;
7767
7768var _whitespace = _dereq_("./whitespace");
7769
7770var lineBreak = _whitespace.lineBreak;
7771var lineBreakG = _whitespace.lineBreakG;
7772var isNewLine = _whitespace.isNewLine;
7773var nonASCIIwhitespace = _whitespace.nonASCIIwhitespace;
7774
7775// Object type used to represent tokens. Note that normally, tokens
7776// simply exist as properties on the parser object. This is only
7777// used for the onToken callback and the external tokenizer.
7778
7779var Token = exports.Token = function Token(p) {
7780 _classCallCheck(this, Token);
7781
7782 this.type = p.type;
7783 this.value = p.value;
7784 this.start = p.start;
7785 this.end = p.end;
7786 if (p.options.locations) this.loc = new SourceLocation(p, p.startLoc, p.endLoc);
7787 if (p.options.ranges) this.range = [p.start, p.end];
7788};
7789
7790// ## Tokenizer
7791
7792var pp = Parser.prototype;
7793
7794// Are we running under Rhino?
7795var isRhino = typeof Packages !== "undefined";
7796
7797// Move to the next token
7798
7799pp.next = function () {
7800 if (this.options.onToken) this.options.onToken(new Token(this));
7801
7802 this.lastTokEnd = this.end;
7803 this.lastTokStart = this.start;
7804 this.lastTokEndLoc = this.endLoc;
7805 this.lastTokStartLoc = this.startLoc;
7806 this.nextToken();
7807};
7808
7809pp.getToken = function () {
7810 this.next();
7811 return new Token(this);
7812};
7813
7814// If we're in an ES6 environment, make parsers iterable
7815if (typeof Symbol !== "undefined") pp[Symbol.iterator] = function () {
7816 var self = this;
7817 return { next: function next() {
7818 var token = self.getToken();
7819 return {
7820 done: token.type === tt.eof,
7821 value: token
7822 };
7823 } };
7824};
7825
7826// Toggle strict mode. Re-reads the next number or string to please
7827// pedantic tests (`"use strict"; 010;` should fail).
7828
7829pp.setStrict = function (strict) {
7830 this.strict = strict;
7831 if (this.type !== tt.num && this.type !== tt.string) return;
7832 this.pos = this.start;
7833 if (this.options.locations) {
7834 while (this.pos < this.lineStart) {
7835 this.lineStart = this.input.lastIndexOf("\n", this.lineStart - 2) + 1;
7836 --this.curLine;
7837 }
7838 }
7839 this.nextToken();
7840};
7841
7842pp.curContext = function () {
7843 return this.context[this.context.length - 1];
7844};
7845
7846// Read a single token, updating the parser object's token-related
7847// properties.
7848
7849pp.nextToken = function () {
7850 var curContext = this.curContext();
7851 if (!curContext || !curContext.preserveSpace) this.skipSpace();
7852
7853 this.start = this.pos;
7854 if (this.options.locations) this.startLoc = this.curPosition();
7855 if (this.pos >= this.input.length) return this.finishToken(tt.eof);
7856
7857 if (curContext.override) return curContext.override(this);else this.readToken(this.fullCharCodeAtPos());
7858};
7859
7860pp.readToken = function (code) {
7861 // Identifier or keyword. '\uXXXX' sequences are allowed in
7862 // identifiers, so '\' also dispatches to that.
7863 if (isIdentifierStart(code, this.options.ecmaVersion >= 6) || code === 92 /* '\' */) return this.readWord();
7864
7865 return this.getTokenFromCode(code);
7866};
7867
7868pp.fullCharCodeAtPos = function () {
7869 var code = this.input.charCodeAt(this.pos);
7870 if (code <= 55295 || code >= 57344) return code;
7871 var next = this.input.charCodeAt(this.pos + 1);
7872 return (code << 10) + next - 56613888;
7873};
7874
7875pp.skipBlockComment = function () {
7876 var startLoc = this.options.onComment && this.options.locations && this.curPosition();
7877 var start = this.pos,
7878 end = this.input.indexOf("*/", this.pos += 2);
7879 if (end === -1) this.raise(this.pos - 2, "Unterminated comment");
7880 this.pos = end + 2;
7881 if (this.options.locations) {
7882 lineBreakG.lastIndex = start;
7883 var match = undefined;
7884 while ((match = lineBreakG.exec(this.input)) && match.index < this.pos) {
7885 ++this.curLine;
7886 this.lineStart = match.index + match[0].length;
7887 }
7888 }
7889 if (this.options.onComment) this.options.onComment(true, this.input.slice(start + 2, end), start, this.pos, startLoc, this.options.locations && this.curPosition());
7890};
7891
7892pp.skipLineComment = function (startSkip) {
7893 var start = this.pos;
7894 var startLoc = this.options.onComment && this.options.locations && this.curPosition();
7895 var ch = this.input.charCodeAt(this.pos += startSkip);
7896 while (this.pos < this.input.length && ch !== 10 && ch !== 13 && ch !== 8232 && ch !== 8233) {
7897 ++this.pos;
7898 ch = this.input.charCodeAt(this.pos);
7899 }
7900 if (this.options.onComment) this.options.onComment(false, this.input.slice(start + startSkip, this.pos), start, this.pos, startLoc, this.options.locations && this.curPosition());
7901};
7902
7903// Called at the start of the parse and after every token. Skips
7904// whitespace and comments, and.
7905
7906pp.skipSpace = function () {
7907 while (this.pos < this.input.length) {
7908 var ch = this.input.charCodeAt(this.pos);
7909 if (ch === 32) {
7910 // ' '
7911 ++this.pos;
7912 } else if (ch === 13) {
7913 ++this.pos;
7914 var next = this.input.charCodeAt(this.pos);
7915 if (next === 10) {
7916 ++this.pos;
7917 }
7918 if (this.options.locations) {
7919 ++this.curLine;
7920 this.lineStart = this.pos;
7921 }
7922 } else if (ch === 10 || ch === 8232 || ch === 8233) {
7923 ++this.pos;
7924 if (this.options.locations) {
7925 ++this.curLine;
7926 this.lineStart = this.pos;
7927 }
7928 } else if (ch > 8 && ch < 14) {
7929 ++this.pos;
7930 } else if (ch === 47) {
7931 // '/'
7932 var next = this.input.charCodeAt(this.pos + 1);
7933 if (next === 42) {
7934 // '*'
7935 this.skipBlockComment();
7936 } else if (next === 47) {
7937 // '/'
7938 this.skipLineComment(2);
7939 } else break;
7940 } else if (ch === 160) {
7941 // '\xa0'
7942 ++this.pos;
7943 } else if (ch >= 5760 && nonASCIIwhitespace.test(String.fromCharCode(ch))) {
7944 ++this.pos;
7945 } else {
7946 break;
7947 }
7948 }
7949};
7950
7951// Called at the end of every token. Sets `end`, `val`, and
7952// maintains `context` and `exprAllowed`, and skips the space after
7953// the token, so that the next one's `start` will point at the
7954// right position.
7955
7956pp.finishToken = function (type, val) {
7957 this.end = this.pos;
7958 if (this.options.locations) this.endLoc = this.curPosition();
7959 var prevType = this.type;
7960 this.type = type;
7961 this.value = val;
7962
7963 this.updateContext(prevType);
7964};
7965
7966// ### Token reading
7967
7968// This is the function that is called to fetch the next token. It
7969// is somewhat obscure, because it works in character codes rather
7970// than characters, and because operator parsing has been inlined
7971// into it.
7972//
7973// All in the name of speed.
7974//
7975pp.readToken_dot = function () {
7976 var next = this.input.charCodeAt(this.pos + 1);
7977 if (next >= 48 && next <= 57) return this.readNumber(true);
7978 var next2 = this.input.charCodeAt(this.pos + 2);
7979 if (this.options.ecmaVersion >= 6 && next === 46 && next2 === 46) {
7980 // 46 = dot '.'
7981 this.pos += 3;
7982 return this.finishToken(tt.ellipsis);
7983 } else {
7984 ++this.pos;
7985 return this.finishToken(tt.dot);
7986 }
7987};
7988
7989pp.readToken_slash = function () {
7990 // '/'
7991 var next = this.input.charCodeAt(this.pos + 1);
7992 if (this.exprAllowed) {
7993 ++this.pos;return this.readRegexp();
7994 }
7995 if (next === 61) return this.finishOp(tt.assign, 2);
7996 return this.finishOp(tt.slash, 1);
7997};
7998
7999pp.readToken_mult_modulo = function (code) {
8000 // '%*'
8001 var next = this.input.charCodeAt(this.pos + 1);
8002 if (next === 61) return this.finishOp(tt.assign, 2);
8003 return this.finishOp(code === 42 ? tt.star : tt.modulo, 1);
8004};
8005
8006pp.readToken_pipe_amp = function (code) {
8007 // '|&'
8008 var next = this.input.charCodeAt(this.pos + 1);
8009 if (next === code) return this.finishOp(code === 124 ? tt.logicalOR : tt.logicalAND, 2);
8010 if (next === 61) return this.finishOp(tt.assign, 2);
8011 return this.finishOp(code === 124 ? tt.bitwiseOR : tt.bitwiseAND, 1);
8012};
8013
8014pp.readToken_caret = function () {
8015 // '^'
8016 var next = this.input.charCodeAt(this.pos + 1);
8017 if (next === 61) return this.finishOp(tt.assign, 2);
8018 return this.finishOp(tt.bitwiseXOR, 1);
8019};
8020
8021pp.readToken_plus_min = function (code) {
8022 // '+-'
8023 var next = this.input.charCodeAt(this.pos + 1);
8024 if (next === code) {
8025 if (next == 45 && this.input.charCodeAt(this.pos + 2) == 62 && lineBreak.test(this.input.slice(this.lastTokEnd, this.pos))) {
8026 // A `-->` line comment
8027 this.skipLineComment(3);
8028 this.skipSpace();
8029 return this.nextToken();
8030 }
8031 return this.finishOp(tt.incDec, 2);
8032 }
8033 if (next === 61) return this.finishOp(tt.assign, 2);
8034 return this.finishOp(tt.plusMin, 1);
8035};
8036
8037pp.readToken_lt_gt = function (code) {
8038 // '<>'
8039 var next = this.input.charCodeAt(this.pos + 1);
8040 var size = 1;
8041 if (next === code) {
8042 size = code === 62 && this.input.charCodeAt(this.pos + 2) === 62 ? 3 : 2;
8043 if (this.input.charCodeAt(this.pos + size) === 61) return this.finishOp(tt.assign, size + 1);
8044 return this.finishOp(tt.bitShift, size);
8045 }
8046 if (next == 33 && code == 60 && this.input.charCodeAt(this.pos + 2) == 45 && this.input.charCodeAt(this.pos + 3) == 45) {
8047 if (this.inModule) this.unexpected();
8048 // `<!--`, an XML-style comment that should be interpreted as a line comment
8049 this.skipLineComment(4);
8050 this.skipSpace();
8051 return this.nextToken();
8052 }
8053 if (next === 61) size = this.input.charCodeAt(this.pos + 2) === 61 ? 3 : 2;
8054 return this.finishOp(tt.relational, size);
8055};
8056
8057pp.readToken_eq_excl = function (code) {
8058 // '=!'
8059 var next = this.input.charCodeAt(this.pos + 1);
8060 if (next === 61) return this.finishOp(tt.equality, this.input.charCodeAt(this.pos + 2) === 61 ? 3 : 2);
8061 if (code === 61 && next === 62 && this.options.ecmaVersion >= 6) {
8062 // '=>'
8063 this.pos += 2;
8064 return this.finishToken(tt.arrow);
8065 }
8066 return this.finishOp(code === 61 ? tt.eq : tt.prefix, 1);
8067};
8068
8069pp.getTokenFromCode = function (code) {
8070 switch (code) {
8071 // The interpretation of a dot depends on whether it is followed
8072 // by a digit or another two dots.
8073 case 46:
8074 // '.'
8075 return this.readToken_dot();
8076
8077 // Punctuation tokens.
8078 case 40:
8079 ++this.pos;return this.finishToken(tt.parenL);
8080 case 41:
8081 ++this.pos;return this.finishToken(tt.parenR);
8082 case 59:
8083 ++this.pos;return this.finishToken(tt.semi);
8084 case 44:
8085 ++this.pos;return this.finishToken(tt.comma);
8086 case 91:
8087 ++this.pos;return this.finishToken(tt.bracketL);
8088 case 93:
8089 ++this.pos;return this.finishToken(tt.bracketR);
8090 case 123:
8091 ++this.pos;return this.finishToken(tt.braceL);
8092 case 125:
8093 ++this.pos;return this.finishToken(tt.braceR);
8094 case 58:
8095 ++this.pos;return this.finishToken(tt.colon);
8096 case 63:
8097 ++this.pos;return this.finishToken(tt.question);
8098
8099 case 96:
8100 // '`'
8101 if (this.options.ecmaVersion < 6) break;
8102 ++this.pos;
8103 return this.finishToken(tt.backQuote);
8104
8105 case 48:
8106 // '0'
8107 var next = this.input.charCodeAt(this.pos + 1);
8108 if (next === 120 || next === 88) return this.readRadixNumber(16); // '0x', '0X' - hex number
8109 if (this.options.ecmaVersion >= 6) {
8110 if (next === 111 || next === 79) return this.readRadixNumber(8); // '0o', '0O' - octal number
8111 if (next === 98 || next === 66) return this.readRadixNumber(2); // '0b', '0B' - binary number
8112 }
8113 // Anything else beginning with a digit is an integer, octal
8114 // number, or float.
8115 case 49:case 50:case 51:case 52:case 53:case 54:case 55:case 56:case 57:
8116 // 1-9
8117 return this.readNumber(false);
8118
8119 // Quotes produce strings.
8120 case 34:case 39:
8121 // '"', "'"
8122 return this.readString(code);
8123
8124 // Operators are parsed inline in tiny state machines. '=' (61) is
8125 // often referred to. `finishOp` simply skips the amount of
8126 // characters it is given as second argument, and returns a token
8127 // of the type given by its first argument.
8128
8129 case 47:
8130 // '/'
8131 return this.readToken_slash();
8132
8133 case 37:case 42:
8134 // '%*'
8135 return this.readToken_mult_modulo(code);
8136
8137 case 124:case 38:
8138 // '|&'
8139 return this.readToken_pipe_amp(code);
8140
8141 case 94:
8142 // '^'
8143 return this.readToken_caret();
8144
8145 case 43:case 45:
8146 // '+-'
8147 return this.readToken_plus_min(code);
8148
8149 case 60:case 62:
8150 // '<>'
8151 return this.readToken_lt_gt(code);
8152
8153 case 61:case 33:
8154 // '=!'
8155 return this.readToken_eq_excl(code);
8156
8157 case 126:
8158 // '~'
8159 return this.finishOp(tt.prefix, 1);
8160 }
8161
8162 this.raise(this.pos, "Unexpected character '" + codePointToString(code) + "'");
8163};
8164
8165pp.finishOp = function (type, size) {
8166 var str = this.input.slice(this.pos, this.pos + size);
8167 this.pos += size;
8168 return this.finishToken(type, str);
8169};
8170
8171var regexpUnicodeSupport = false;
8172try {
8173 new RegExp("￿", "u");regexpUnicodeSupport = true;
8174} catch (e) {}
8175
8176// Parse a regular expression. Some context-awareness is necessary,
8177// since a '/' inside a '[]' set does not end the expression.
8178
8179pp.readRegexp = function () {
8180 var escaped = undefined,
8181 inClass = undefined,
8182 start = this.pos;
8183 for (;;) {
8184 if (this.pos >= this.input.length) this.raise(start, "Unterminated regular expression");
8185 var ch = this.input.charAt(this.pos);
8186 if (lineBreak.test(ch)) this.raise(start, "Unterminated regular expression");
8187 if (!escaped) {
8188 if (ch === "[") inClass = true;else if (ch === "]" && inClass) inClass = false;else if (ch === "/" && !inClass) break;
8189 escaped = ch === "\\";
8190 } else escaped = false;
8191 ++this.pos;
8192 }
8193 var content = this.input.slice(start, this.pos);
8194 ++this.pos;
8195 // Need to use `readWord1` because '\uXXXX' sequences are allowed
8196 // here (don't ask).
8197 var mods = this.readWord1();
8198 var tmp = content;
8199 if (mods) {
8200 var validFlags = /^[gmsiy]*$/;
8201 if (this.options.ecmaVersion >= 6) validFlags = /^[gmsiyu]*$/;
8202 if (!validFlags.test(mods)) this.raise(start, "Invalid regular expression flag");
8203 if (mods.indexOf("u") >= 0 && !regexpUnicodeSupport) {
8204 // Replace each astral symbol and every Unicode escape sequence that
8205 // possibly represents an astral symbol or a paired surrogate with a
8206 // single ASCII symbol to avoid throwing on regular expressions that
8207 // are only valid in combination with the `/u` flag.
8208 // Note: replacing with the ASCII symbol `x` might cause false
8209 // negatives in unlikely scenarios. For example, `[\u{61}-b]` is a
8210 // perfectly valid pattern that is equivalent to `[a-b]`, but it would
8211 // be replaced by `[x-b]` which throws an error.
8212 tmp = tmp.replace(/\\u([a-fA-F0-9]{4})|\\u\{([0-9a-fA-F]+)\}|[\uD800-\uDBFF][\uDC00-\uDFFF]/g, "x");
8213 }
8214 }
8215 // Detect invalid regular expressions.
8216 var value = null;
8217 // Rhino's regular expression parser is flaky and throws uncatchable exceptions,
8218 // so don't do detection if we are running under Rhino
8219 if (!isRhino) {
8220 try {
8221 new RegExp(tmp);
8222 } catch (e) {
8223 if (e instanceof SyntaxError) this.raise(start, "Error parsing regular expression: " + e.message);
8224 this.raise(e);
8225 }
8226 // Get a regular expression object for this pattern-flag pair, or `null` in
8227 // case the current environment doesn't support the flags it uses.
8228 try {
8229 value = new RegExp(content, mods);
8230 } catch (err) {}
8231 }
8232 return this.finishToken(tt.regexp, { pattern: content, flags: mods, value: value });
8233};
8234
8235// Read an integer in the given radix. Return null if zero digits
8236// were read, the integer value otherwise. When `len` is given, this
8237// will return `null` unless the integer has exactly `len` digits.
8238
8239pp.readInt = function (radix, len) {
8240 var start = this.pos,
8241 total = 0;
8242 for (var i = 0, e = len == null ? Infinity : len; i < e; ++i) {
8243 var code = this.input.charCodeAt(this.pos),
8244 val = undefined;
8245 if (code >= 97) val = code - 97 + 10; // a
8246 else if (code >= 65) val = code - 65 + 10; // A
8247 else if (code >= 48 && code <= 57) val = code - 48; // 0-9
8248 else val = Infinity;
8249 if (val >= radix) break;
8250 ++this.pos;
8251 total = total * radix + val;
8252 }
8253 if (this.pos === start || len != null && this.pos - start !== len) return null;
8254
8255 return total;
8256};
8257
8258pp.readRadixNumber = function (radix) {
8259 this.pos += 2; // 0x
8260 var val = this.readInt(radix);
8261 if (val == null) this.raise(this.start + 2, "Expected number in radix " + radix);
8262 if (isIdentifierStart(this.fullCharCodeAtPos())) this.raise(this.pos, "Identifier directly after number");
8263 return this.finishToken(tt.num, val);
8264};
8265
8266// Read an integer, octal integer, or floating-point number.
8267
8268pp.readNumber = function (startsWithDot) {
8269 var start = this.pos,
8270 isFloat = false,
8271 octal = this.input.charCodeAt(this.pos) === 48;
8272 if (!startsWithDot && this.readInt(10) === null) this.raise(start, "Invalid number");
8273 if (this.input.charCodeAt(this.pos) === 46) {
8274 ++this.pos;
8275 this.readInt(10);
8276 isFloat = true;
8277 }
8278 var next = this.input.charCodeAt(this.pos);
8279 if (next === 69 || next === 101) {
8280 // 'eE'
8281 next = this.input.charCodeAt(++this.pos);
8282 if (next === 43 || next === 45) ++this.pos; // '+-'
8283 if (this.readInt(10) === null) this.raise(start, "Invalid number");
8284 isFloat = true;
8285 }
8286 if (isIdentifierStart(this.fullCharCodeAtPos())) this.raise(this.pos, "Identifier directly after number");
8287
8288 var str = this.input.slice(start, this.pos),
8289 val = undefined;
8290 if (isFloat) val = parseFloat(str);else if (!octal || str.length === 1) val = parseInt(str, 10);else if (/[89]/.test(str) || this.strict) this.raise(start, "Invalid number");else val = parseInt(str, 8);
8291 return this.finishToken(tt.num, val);
8292};
8293
8294// Read a string value, interpreting backslash-escapes.
8295
8296pp.readCodePoint = function () {
8297 var ch = this.input.charCodeAt(this.pos),
8298 code = undefined;
8299
8300 if (ch === 123) {
8301 if (this.options.ecmaVersion < 6) this.unexpected();
8302 ++this.pos;
8303 code = this.readHexChar(this.input.indexOf("}", this.pos) - this.pos);
8304 ++this.pos;
8305 if (code > 1114111) this.unexpected();
8306 } else {
8307 code = this.readHexChar(4);
8308 }
8309 return code;
8310};
8311
8312function codePointToString(code) {
8313 // UTF-16 Decoding
8314 if (code <= 65535) {
8315 return String.fromCharCode(code);
8316 }return String.fromCharCode((code - 65536 >> 10) + 55296, (code - 65536 & 1023) + 56320);
8317}
8318
8319pp.readString = function (quote) {
8320 var out = "",
8321 chunkStart = ++this.pos;
8322 for (;;) {
8323 if (this.pos >= this.input.length) this.raise(this.start, "Unterminated string constant");
8324 var ch = this.input.charCodeAt(this.pos);
8325 if (ch === quote) break;
8326 if (ch === 92) {
8327 // '\'
8328 out += this.input.slice(chunkStart, this.pos);
8329 out += this.readEscapedChar();
8330 chunkStart = this.pos;
8331 } else {
8332 if (isNewLine(ch)) this.raise(this.start, "Unterminated string constant");
8333 ++this.pos;
8334 }
8335 }
8336 out += this.input.slice(chunkStart, this.pos++);
8337 return this.finishToken(tt.string, out);
8338};
8339
8340// Reads template string tokens.
8341
8342pp.readTmplToken = function () {
8343 var out = "",
8344 chunkStart = this.pos;
8345 for (;;) {
8346 if (this.pos >= this.input.length) this.raise(this.start, "Unterminated template");
8347 var ch = this.input.charCodeAt(this.pos);
8348 if (ch === 96 || ch === 36 && this.input.charCodeAt(this.pos + 1) === 123) {
8349 // '`', '${'
8350 if (this.pos === this.start && this.type === tt.template) {
8351 if (ch === 36) {
8352 this.pos += 2;
8353 return this.finishToken(tt.dollarBraceL);
8354 } else {
8355 ++this.pos;
8356 return this.finishToken(tt.backQuote);
8357 }
8358 }
8359 out += this.input.slice(chunkStart, this.pos);
8360 return this.finishToken(tt.template, out);
8361 }
8362 if (ch === 92) {
8363 // '\'
8364 out += this.input.slice(chunkStart, this.pos);
8365 out += this.readEscapedChar();
8366 chunkStart = this.pos;
8367 } else if (isNewLine(ch)) {
8368 out += this.input.slice(chunkStart, this.pos);
8369 ++this.pos;
8370 if (ch === 13 && this.input.charCodeAt(this.pos) === 10) {
8371 ++this.pos;
8372 out += "\n";
8373 } else {
8374 out += String.fromCharCode(ch);
8375 }
8376 if (this.options.locations) {
8377 ++this.curLine;
8378 this.lineStart = this.pos;
8379 }
8380 chunkStart = this.pos;
8381 } else {
8382 ++this.pos;
8383 }
8384 }
8385};
8386
8387// Used to read escaped characters
8388
8389pp.readEscapedChar = function () {
8390 var ch = this.input.charCodeAt(++this.pos);
8391 var octal = /^[0-7]+/.exec(this.input.slice(this.pos, this.pos + 3));
8392 if (octal) octal = octal[0];
8393 while (octal && parseInt(octal, 8) > 255) octal = octal.slice(0, -1);
8394 if (octal === "0") octal = null;
8395 ++this.pos;
8396 if (octal) {
8397 if (this.strict) this.raise(this.pos - 2, "Octal literal in strict mode");
8398 this.pos += octal.length - 1;
8399 return String.fromCharCode(parseInt(octal, 8));
8400 } else {
8401 switch (ch) {
8402 case 110:
8403 return "\n"; // 'n' -> '\n'
8404 case 114:
8405 return "\r"; // 'r' -> '\r'
8406 case 120:
8407 return String.fromCharCode(this.readHexChar(2)); // 'x'
8408 case 117:
8409 return codePointToString(this.readCodePoint()); // 'u'
8410 case 116:
8411 return "\t"; // 't' -> '\t'
8412 case 98:
8413 return "\b"; // 'b' -> '\b'
8414 case 118:
8415 return "\u000b"; // 'v' -> '\u000b'
8416 case 102:
8417 return "\f"; // 'f' -> '\f'
8418 case 48:
8419 return "\u0000"; // 0 -> '\0'
8420 case 13:
8421 if (this.input.charCodeAt(this.pos) === 10) ++this.pos; // '\r\n'
8422 case 10:
8423 // ' \n'
8424 if (this.options.locations) {
8425 this.lineStart = this.pos;++this.curLine;
8426 }
8427 return "";
8428 default:
8429 return String.fromCharCode(ch);
8430 }
8431 }
8432};
8433
8434// Used to read character escape sequences ('\x', '\u', '\U').
8435
8436pp.readHexChar = function (len) {
8437 var n = this.readInt(16, len);
8438 if (n === null) this.raise(this.start, "Bad character escape sequence");
8439 return n;
8440};
8441
8442// Used to signal to callers of `readWord1` whether the word
8443// contained any escape sequences. This is needed because words with
8444// escape sequences must not be interpreted as keywords.
8445
8446var containsEsc;
8447
8448// Read an identifier, and return it as a string. Sets `containsEsc`
8449// to whether the word contained a '\u' escape.
8450//
8451// Incrementally adds only escaped chars, adding other chunks as-is
8452// as a micro-optimization.
8453
8454pp.readWord1 = function () {
8455 containsEsc = false;
8456 var word = "",
8457 first = true,
8458 chunkStart = this.pos;
8459 var astral = this.options.ecmaVersion >= 6;
8460 while (this.pos < this.input.length) {
8461 var ch = this.fullCharCodeAtPos();
8462 if (isIdentifierChar(ch, astral)) {
8463 this.pos += ch <= 65535 ? 1 : 2;
8464 } else if (ch === 92) {
8465 // "\"
8466 containsEsc = true;
8467 word += this.input.slice(chunkStart, this.pos);
8468 var escStart = this.pos;
8469 if (this.input.charCodeAt(++this.pos) != 117) // "u"
8470 this.raise(this.pos, "Expecting Unicode escape sequence \\uXXXX");
8471 ++this.pos;
8472 var esc = this.readCodePoint();
8473 if (!(first ? isIdentifierStart : isIdentifierChar)(esc, astral)) this.raise(escStart, "Invalid Unicode escape");
8474 word += codePointToString(esc);
8475 chunkStart = this.pos;
8476 } else {
8477 break;
8478 }
8479 first = false;
8480 }
8481 return word + this.input.slice(chunkStart, this.pos);
8482};
8483
8484// Read an identifier or keyword token. Will check for reserved
8485// words when necessary.
8486
8487pp.readWord = function () {
8488 var word = this.readWord1();
8489 var type = tt.name;
8490 if ((this.options.ecmaVersion >= 6 || !containsEsc) && this.isKeyword(word)) type = keywordTypes[word];
8491 return this.finishToken(type, word);
8492};
8493
8494},{"./identifier":7,"./location":8,"./state":13,"./tokentype":17,"./whitespace":19}],17:[function(_dereq_,module,exports){
8495"use strict";
8496
8497var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } };
8498
8499exports.__esModule = true;
8500// ## Token types
8501
8502// The assignment of fine-grained, information-carrying type objects
8503// allows the tokenizer to store the information it has about a
8504// token in a way that is very cheap for the parser to look up.
8505
8506// All token type variables start with an underscore, to make them
8507// easy to recognize.
8508
8509// The `beforeExpr` property is used to disambiguate between regular
8510// expressions and divisions. It is set on all token types that can
8511// be followed by an expression (thus, a slash after them would be a
8512// regular expression).
8513//
8514// `isLoop` marks a keyword as starting a loop, which is important
8515// to know when parsing a label, in order to allow or disallow
8516// continue jumps to that label.
8517
8518var TokenType = exports.TokenType = function TokenType(label) {
8519 var conf = arguments[1] === undefined ? {} : arguments[1];
8520
8521 _classCallCheck(this, TokenType);
8522
8523 this.label = label;
8524 this.keyword = conf.keyword;
8525 this.beforeExpr = !!conf.beforeExpr;
8526 this.startsExpr = !!conf.startsExpr;
8527 this.isLoop = !!conf.isLoop;
8528 this.isAssign = !!conf.isAssign;
8529 this.prefix = !!conf.prefix;
8530 this.postfix = !!conf.postfix;
8531 this.binop = conf.binop || null;
8532 this.updateContext = null;
8533};
8534
8535function binop(name, prec) {
8536 return new TokenType(name, { beforeExpr: true, binop: prec });
8537}
8538var beforeExpr = { beforeExpr: true },
8539 startsExpr = { startsExpr: true };
8540
8541var types = {
8542 num: new TokenType("num", startsExpr),
8543 regexp: new TokenType("regexp", startsExpr),
8544 string: new TokenType("string", startsExpr),
8545 name: new TokenType("name", startsExpr),
8546 eof: new TokenType("eof"),
8547
8548 // Punctuation token types.
8549 bracketL: new TokenType("[", { beforeExpr: true, startsExpr: true }),
8550 bracketR: new TokenType("]"),
8551 braceL: new TokenType("{", { beforeExpr: true, startsExpr: true }),
8552 braceR: new TokenType("}"),
8553 parenL: new TokenType("(", { beforeExpr: true, startsExpr: true }),
8554 parenR: new TokenType(")"),
8555 comma: new TokenType(",", beforeExpr),
8556 semi: new TokenType(";", beforeExpr),
8557 colon: new TokenType(":", beforeExpr),
8558 dot: new TokenType("."),
8559 question: new TokenType("?", beforeExpr),
8560 arrow: new TokenType("=>", beforeExpr),
8561 template: new TokenType("template"),
8562 ellipsis: new TokenType("...", beforeExpr),
8563 backQuote: new TokenType("`", startsExpr),
8564 dollarBraceL: new TokenType("${", { beforeExpr: true, startsExpr: true }),
8565
8566 // Operators. These carry several kinds of properties to help the
8567 // parser use them properly (the presence of these properties is
8568 // what categorizes them as operators).
8569 //
8570 // `binop`, when present, specifies that this operator is a binary
8571 // operator, and will refer to its precedence.
8572 //
8573 // `prefix` and `postfix` mark the operator as a prefix or postfix
8574 // unary operator.
8575 //
8576 // `isAssign` marks all of `=`, `+=`, `-=` etcetera, which act as
8577 // binary operators with a very low precedence, that should result
8578 // in AssignmentExpression nodes.
8579
8580 eq: new TokenType("=", { beforeExpr: true, isAssign: true }),
8581 assign: new TokenType("_=", { beforeExpr: true, isAssign: true }),
8582 incDec: new TokenType("++/--", { prefix: true, postfix: true, startsExpr: true }),
8583 prefix: new TokenType("prefix", { beforeExpr: true, prefix: true, startsExpr: true }),
8584 logicalOR: binop("||", 1),
8585 logicalAND: binop("&&", 2),
8586 bitwiseOR: binop("|", 3),
8587 bitwiseXOR: binop("^", 4),
8588 bitwiseAND: binop("&", 5),
8589 equality: binop("==/!=", 6),
8590 relational: binop("</>", 7),
8591 bitShift: binop("<</>>", 8),
8592 plusMin: new TokenType("+/-", { beforeExpr: true, binop: 9, prefix: true, startsExpr: true }),
8593 modulo: binop("%", 10),
8594 star: binop("*", 10),
8595 slash: binop("/", 10)
8596};
8597
8598exports.types = types;
8599// Map keyword names to token types.
8600
8601var keywords = {};
8602
8603exports.keywords = keywords;
8604// Succinct definitions of keyword token types
8605function kw(name) {
8606 var options = arguments[1] === undefined ? {} : arguments[1];
8607
8608 options.keyword = name;
8609 keywords[name] = types["_" + name] = new TokenType(name, options);
8610}
8611
8612kw("break");
8613kw("case", beforeExpr);
8614kw("catch");
8615kw("continue");
8616kw("debugger");
8617kw("default");
8618kw("do", { isLoop: true });
8619kw("else", beforeExpr);
8620kw("finally");
8621kw("for", { isLoop: true });
8622kw("function", startsExpr);
8623kw("if");
8624kw("return", beforeExpr);
8625kw("switch");
8626kw("throw", beforeExpr);
8627kw("try");
8628kw("var");
8629kw("let");
8630kw("const");
8631kw("while", { isLoop: true });
8632kw("with");
8633kw("new", { beforeExpr: true, startsExpr: true });
8634kw("this", startsExpr);
8635kw("super", startsExpr);
8636kw("class");
8637kw("extends", beforeExpr);
8638kw("export");
8639kw("import");
8640kw("yield", { beforeExpr: true, startsExpr: true });
8641kw("null", startsExpr);
8642kw("true", startsExpr);
8643kw("false", startsExpr);
8644kw("in", { beforeExpr: true, binop: 7 });
8645kw("instanceof", { beforeExpr: true, binop: 7 });
8646kw("typeof", { beforeExpr: true, prefix: true, startsExpr: true });
8647kw("void", { beforeExpr: true, prefix: true, startsExpr: true });
8648kw("delete", { beforeExpr: true, prefix: true, startsExpr: true });
8649
8650},{}],18:[function(_dereq_,module,exports){
8651"use strict";
8652
8653exports.isArray = isArray;
8654
8655// Checks if an object has a property.
8656
8657exports.has = has;
8658exports.__esModule = true;
8659
8660function isArray(obj) {
8661 return Object.prototype.toString.call(obj) === "[object Array]";
8662}
8663
8664function has(obj, propName) {
8665 return Object.prototype.hasOwnProperty.call(obj, propName);
8666}
8667
8668},{}],19:[function(_dereq_,module,exports){
8669"use strict";
8670
8671exports.isNewLine = isNewLine;
8672exports.__esModule = true;
8673// Matches a whole line break (where CRLF is considered a single
8674// line break). Used to count lines.
8675
8676var lineBreak = /\r\n?|\n|\u2028|\u2029/;
8677exports.lineBreak = lineBreak;
8678var lineBreakG = new RegExp(lineBreak.source, "g");
8679
8680exports.lineBreakG = lineBreakG;
8681
8682function isNewLine(code) {
8683 return code === 10 || code === 13 || code === 8232 || code == 8233;
8684}
8685
8686var nonASCIIwhitespace = /[\u1680\u180e\u2000-\u200a\u202f\u205f\u3000\ufeff]/;
8687exports.nonASCIIwhitespace = nonASCIIwhitespace;
8688
8689},{}]},{},[1])(1)
8690});
8691}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
8692},{}],33:[function(require,module,exports){
8693(function (global){
8694(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.acorn || (g.acorn = {})).walk = 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){
8695"use strict";
8696
8697var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } };
8698
8699// AST walker module for Mozilla Parser API compatible trees
8700
8701// A simple walk is one where you simply specify callbacks to be
8702// called on specific nodes. The last two arguments are optional. A
8703// simple use would be
8704//
8705// walk.simple(myTree, {
8706// Expression: function(node) { ... }
8707// });
8708//
8709// to do something with all expressions. All Parser API node types
8710// can be used to identify node types, as well as Expression,
8711// Statement, and ScopeBody, which denote categories of nodes.
8712//
8713// The base argument can be used to pass a custom (recursive)
8714// walker, and state can be used to give this walked an initial
8715// state.
8716
8717exports.simple = simple;
8718
8719// An ancestor walk builds up an array of ancestor nodes (including
8720// the current node) and passes them to the callback as the state parameter.
8721exports.ancestor = ancestor;
8722
8723// A recursive walk is one where your functions override the default
8724// walkers. They can modify and replace the state parameter that's
8725// threaded through the walk, and can opt how and whether to walk
8726// their child nodes (by calling their third argument on these
8727// nodes).
8728exports.recursive = recursive;
8729
8730// Find a node with a given start, end, and type (all are optional,
8731// null can be used as wildcard). Returns a {node, state} object, or
8732// undefined when it doesn't find a matching node.
8733exports.findNodeAt = findNodeAt;
8734
8735// Find the innermost node of a given type that contains the given
8736// position. Interface similar to findNodeAt.
8737exports.findNodeAround = findNodeAround;
8738
8739// Find the outermost matching node after a given position.
8740exports.findNodeAfter = findNodeAfter;
8741
8742// Find the outermost matching node before a given position.
8743exports.findNodeBefore = findNodeBefore;
8744
8745// Used to create a custom walker. Will fill in all missing node
8746// type properties with the defaults.
8747exports.make = make;
8748exports.__esModule = true;
8749
8750function simple(node, visitors, base, state) {
8751 if (!base) base = exports.base;(function c(node, st, override) {
8752 var type = override || node.type,
8753 found = visitors[type];
8754 base[type](node, st, c);
8755 if (found) found(node, st);
8756 })(node, state);
8757}
8758
8759function ancestor(node, visitors, base, state) {
8760 if (!base) base = exports.base;
8761 if (!state) state = [];(function c(node, st, override) {
8762 var type = override || node.type,
8763 found = visitors[type];
8764 if (node != st[st.length - 1]) {
8765 st = st.slice();
8766 st.push(node);
8767 }
8768 base[type](node, st, c);
8769 if (found) found(node, st);
8770 })(node, state);
8771}
8772
8773function recursive(node, state, funcs, base) {
8774 var visitor = funcs ? exports.make(funcs, base) : base;(function c(node, st, override) {
8775 visitor[override || node.type](node, st, c);
8776 })(node, state);
8777}
8778
8779function makeTest(test) {
8780 if (typeof test == "string") {
8781 return function (type) {
8782 return type == test;
8783 };
8784 } else if (!test) {
8785 return function () {
8786 return true;
8787 };
8788 } else {
8789 return test;
8790 }
8791}
8792
8793var Found = function Found(node, state) {
8794 _classCallCheck(this, Found);
8795
8796 this.node = node;this.state = state;
8797};
8798
8799function findNodeAt(node, start, end, test, base, state) {
8800 test = makeTest(test);
8801 if (!base) base = exports.base;
8802 try {
8803 ;(function c(node, st, override) {
8804 var type = override || node.type;
8805 if ((start == null || node.start <= start) && (end == null || node.end >= end)) base[type](node, st, c);
8806 if (test(type, node) && (start == null || node.start == start) && (end == null || node.end == end)) throw new Found(node, st);
8807 })(node, state);
8808 } catch (e) {
8809 if (e instanceof Found) {
8810 return e;
8811 }throw e;
8812 }
8813}
8814
8815function findNodeAround(node, pos, test, base, state) {
8816 test = makeTest(test);
8817 if (!base) base = exports.base;
8818 try {
8819 ;(function c(node, st, override) {
8820 var type = override || node.type;
8821 if (node.start > pos || node.end < pos) {
8822 return;
8823 }base[type](node, st, c);
8824 if (test(type, node)) throw new Found(node, st);
8825 })(node, state);
8826 } catch (e) {
8827 if (e instanceof Found) {
8828 return e;
8829 }throw e;
8830 }
8831}
8832
8833function findNodeAfter(node, pos, test, base, state) {
8834 test = makeTest(test);
8835 if (!base) base = exports.base;
8836 try {
8837 ;(function c(node, st, override) {
8838 if (node.end < pos) {
8839 return;
8840 }var type = override || node.type;
8841 if (node.start >= pos && test(type, node)) throw new Found(node, st);
8842 base[type](node, st, c);
8843 })(node, state);
8844 } catch (e) {
8845 if (e instanceof Found) {
8846 return e;
8847 }throw e;
8848 }
8849}
8850
8851function findNodeBefore(node, pos, test, base, state) {
8852 test = makeTest(test);
8853 if (!base) base = exports.base;
8854 var max = undefined;(function c(node, st, override) {
8855 if (node.start > pos) {
8856 return;
8857 }var type = override || node.type;
8858 if (node.end <= pos && (!max || max.node.end < node.end) && test(type, node)) max = new Found(node, st);
8859 base[type](node, st, c);
8860 })(node, state);
8861 return max;
8862}
8863
8864function make(funcs, base) {
8865 if (!base) base = exports.base;
8866 var visitor = {};
8867 for (var type in base) visitor[type] = base[type];
8868 for (var type in funcs) visitor[type] = funcs[type];
8869 return visitor;
8870}
8871
8872function skipThrough(node, st, c) {
8873 c(node, st);
8874}
8875function ignore(_node, _st, _c) {}
8876
8877// Node walkers.
8878
8879var base = {};
8880
8881exports.base = base;
8882base.Program = base.BlockStatement = function (node, st, c) {
8883 for (var i = 0; i < node.body.length; ++i) {
8884 c(node.body[i], st, "Statement");
8885 }
8886};
8887base.Statement = skipThrough;
8888base.EmptyStatement = ignore;
8889base.ExpressionStatement = base.ParenthesizedExpression = function (node, st, c) {
8890 return c(node.expression, st, "Expression");
8891};
8892base.IfStatement = function (node, st, c) {
8893 c(node.test, st, "Expression");
8894 c(node.consequent, st, "Statement");
8895 if (node.alternate) c(node.alternate, st, "Statement");
8896};
8897base.LabeledStatement = function (node, st, c) {
8898 return c(node.body, st, "Statement");
8899};
8900base.BreakStatement = base.ContinueStatement = ignore;
8901base.WithStatement = function (node, st, c) {
8902 c(node.object, st, "Expression");
8903 c(node.body, st, "Statement");
8904};
8905base.SwitchStatement = function (node, st, c) {
8906 c(node.discriminant, st, "Expression");
8907 for (var i = 0; i < node.cases.length; ++i) {
8908 var cs = node.cases[i];
8909 if (cs.test) c(cs.test, st, "Expression");
8910 for (var j = 0; j < cs.consequent.length; ++j) {
8911 c(cs.consequent[j], st, "Statement");
8912 }
8913 }
8914};
8915base.ReturnStatement = base.YieldExpression = function (node, st, c) {
8916 if (node.argument) c(node.argument, st, "Expression");
8917};
8918base.ThrowStatement = base.SpreadElement = base.RestElement = function (node, st, c) {
8919 return c(node.argument, st, "Expression");
8920};
8921base.TryStatement = function (node, st, c) {
8922 c(node.block, st, "Statement");
8923 if (node.handler) c(node.handler.body, st, "ScopeBody");
8924 if (node.finalizer) c(node.finalizer, st, "Statement");
8925};
8926base.WhileStatement = base.DoWhileStatement = function (node, st, c) {
8927 c(node.test, st, "Expression");
8928 c(node.body, st, "Statement");
8929};
8930base.ForStatement = function (node, st, c) {
8931 if (node.init) c(node.init, st, "ForInit");
8932 if (node.test) c(node.test, st, "Expression");
8933 if (node.update) c(node.update, st, "Expression");
8934 c(node.body, st, "Statement");
8935};
8936base.ForInStatement = base.ForOfStatement = function (node, st, c) {
8937 c(node.left, st, "ForInit");
8938 c(node.right, st, "Expression");
8939 c(node.body, st, "Statement");
8940};
8941base.ForInit = function (node, st, c) {
8942 if (node.type == "VariableDeclaration") c(node, st);else c(node, st, "Expression");
8943};
8944base.DebuggerStatement = ignore;
8945
8946base.FunctionDeclaration = function (node, st, c) {
8947 return c(node, st, "Function");
8948};
8949base.VariableDeclaration = function (node, st, c) {
8950 for (var i = 0; i < node.declarations.length; ++i) {
8951 var decl = node.declarations[i];
8952 if (decl.init) c(decl.init, st, "Expression");
8953 }
8954};
8955
8956base.Function = function (node, st, c) {
8957 return c(node.body, st, "ScopeBody");
8958};
8959base.ScopeBody = function (node, st, c) {
8960 return c(node, st, "Statement");
8961};
8962
8963base.Expression = skipThrough;
8964base.ThisExpression = base.Super = base.MetaProperty = ignore;
8965base.ArrayExpression = base.ArrayPattern = function (node, st, c) {
8966 for (var i = 0; i < node.elements.length; ++i) {
8967 var elt = node.elements[i];
8968 if (elt) c(elt, st, "Expression");
8969 }
8970};
8971base.ObjectExpression = base.ObjectPattern = function (node, st, c) {
8972 for (var i = 0; i < node.properties.length; ++i) {
8973 c(node.properties[i], st);
8974 }
8975};
8976base.FunctionExpression = base.ArrowFunctionExpression = base.FunctionDeclaration;
8977base.SequenceExpression = base.TemplateLiteral = function (node, st, c) {
8978 for (var i = 0; i < node.expressions.length; ++i) {
8979 c(node.expressions[i], st, "Expression");
8980 }
8981};
8982base.UnaryExpression = base.UpdateExpression = function (node, st, c) {
8983 c(node.argument, st, "Expression");
8984};
8985base.BinaryExpression = base.AssignmentExpression = base.AssignmentPattern = base.LogicalExpression = function (node, st, c) {
8986 c(node.left, st, "Expression");
8987 c(node.right, st, "Expression");
8988};
8989base.ConditionalExpression = function (node, st, c) {
8990 c(node.test, st, "Expression");
8991 c(node.consequent, st, "Expression");
8992 c(node.alternate, st, "Expression");
8993};
8994base.NewExpression = base.CallExpression = function (node, st, c) {
8995 c(node.callee, st, "Expression");
8996 if (node.arguments) for (var i = 0; i < node.arguments.length; ++i) {
8997 c(node.arguments[i], st, "Expression");
8998 }
8999};
9000base.MemberExpression = function (node, st, c) {
9001 c(node.object, st, "Expression");
9002 if (node.computed) c(node.property, st, "Expression");
9003};
9004base.ExportNamedDeclaration = base.ExportDefaultDeclaration = function (node, st, c) {
9005 return c(node.declaration, st);
9006};
9007base.ImportDeclaration = function (node, st, c) {
9008 for (var i = 0; i < node.specifiers.length; i++) {
9009 c(node.specifiers[i], st);
9010 }
9011};
9012base.ImportSpecifier = base.ImportDefaultSpecifier = base.ImportNamespaceSpecifier = base.Identifier = base.Literal = ignore;
9013
9014base.TaggedTemplateExpression = function (node, st, c) {
9015 c(node.tag, st, "Expression");
9016 c(node.quasi, st);
9017};
9018base.ClassDeclaration = base.ClassExpression = function (node, st, c) {
9019 if (node.superClass) c(node.superClass, st, "Expression");
9020 for (var i = 0; i < node.body.body.length; i++) {
9021 c(node.body.body[i], st);
9022 }
9023};
9024base.MethodDefinition = base.Property = function (node, st, c) {
9025 if (node.computed) c(node.key, st, "Expression");
9026 c(node.value, st, "Expression");
9027};
9028base.ComprehensionExpression = function (node, st, c) {
9029 for (var i = 0; i < node.blocks.length; i++) {
9030 c(node.blocks[i].right, st, "Expression");
9031 }c(node.body, st, "Expression");
9032};
9033
9034},{}]},{},[1])(1)
9035});
9036}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
9037},{}],34:[function(require,module,exports){
9038/**
9039 * This file automatically generated from `pre-publish.js`.
9040 * Do not manually edit.
9041 */
9042
9043module.exports = {
9044 "area": true,
9045 "base": true,
9046 "br": true,
9047 "col": true,
9048 "embed": true,
9049 "hr": true,
9050 "img": true,
9051 "input": true,
9052 "keygen": true,
9053 "link": true,
9054 "menuitem": true,
9055 "meta": true,
9056 "param": true,
9057 "source": true,
9058 "track": true,
9059 "wbr": true
9060};
9061
9062},{}],35:[function(require,module,exports){
9063'use strict';
9064
9065var detect = require('acorn-globals');
9066var acorn = require('acorn');
9067var walk = require('acorn/dist/walk');
9068
9069// polyfill for https://github.com/marijnh/acorn/pull/231
9070walk.base.ExportNamedDeclaration = walk.base.ExportDefaultDeclaration = function (node, st, c) {
9071 return c(node.declaration, st);
9072};
9073walk.base.ImportDefaultSpecifier = walk.base.ImportNamespaceSpecifier = function () {};
9074
9075// hacky fix for https://github.com/marijnh/acorn/issues/227
9076function reallyParse(source) {
9077 try {
9078 return acorn.parse(source, {
9079 ecmaVersion: 5,
9080 allowReturnOutsideFunction: true
9081 });
9082 } catch (ex) {
9083 if (ex.name !== 'SyntaxError') {
9084 throw ex;
9085 }
9086 return acorn.parse(source, {
9087 ecmaVersion: 6,
9088 allowReturnOutsideFunction: true
9089 });
9090 }
9091}
9092
9093module.exports = addWith
9094
9095/**
9096 * Mimic `with` as far as possible but at compile time
9097 *
9098 * @param {String} obj The object part of a with expression
9099 * @param {String} src The body of the with expression
9100 * @param {Array.<String>} exclude A list of variable names to explicitly exclude
9101 */
9102function addWith(obj, src, exclude) {
9103 obj = obj + ''
9104 src = src + ''
9105 exclude = exclude || []
9106 exclude = exclude.concat(detect(obj).map(function (global) { return global.name; }))
9107 var vars = detect(src).map(function (global) { return global.name; })
9108 .filter(function (v) {
9109 return exclude.indexOf(v) === -1
9110 })
9111
9112 if (vars.length === 0) return src
9113
9114 var declareLocal = ''
9115 var local = 'locals_for_with'
9116 var result = 'result_of_with'
9117 if (/^[a-zA-Z0-9$_]+$/.test(obj)) {
9118 local = obj
9119 } else {
9120 while (vars.indexOf(local) != -1 || exclude.indexOf(local) != -1) {
9121 local += '_'
9122 }
9123 declareLocal = 'var ' + local + ' = (' + obj + ')'
9124 }
9125 while (vars.indexOf(result) != -1 || exclude.indexOf(result) != -1) {
9126 result += '_'
9127 }
9128
9129 var inputVars = vars.map(function (v) {
9130 return JSON.stringify(v) + ' in ' + local + '?' +
9131 local + '.' + v + ':' +
9132 'typeof ' + v + '!=="undefined"?' + v + ':undefined'
9133 })
9134
9135 src = '(function (' + vars.join(', ') + ') {' +
9136 src +
9137 '}.call(this' + inputVars.map(function (v) { return ',' + v; }).join('') + '))'
9138
9139 return ';' + declareLocal + ';' + unwrapReturns(src, result) + ';'
9140}
9141
9142/**
9143 * Take a self calling function, and unwrap it such that return inside the function
9144 * results in return outside the function
9145 *
9146 * @param {String} src Some JavaScript code representing a self-calling function
9147 * @param {String} result A temporary variable to store the result in
9148 */
9149function unwrapReturns(src, result) {
9150 var originalSource = src
9151 var hasReturn = false
9152 var ast = reallyParse(src)
9153 var ref
9154 src = src.split('')
9155
9156 // get a reference to the function that was inserted to add an inner context
9157 if ((ref = ast.body).length !== 1
9158 || (ref = ref[0]).type !== 'ExpressionStatement'
9159 || (ref = ref.expression).type !== 'CallExpression'
9160 || (ref = ref.callee).type !== 'MemberExpression' || ref.computed !== false || ref.property.name !== 'call'
9161 || (ref = ref.object).type !== 'FunctionExpression')
9162 throw new Error('AST does not seem to represent a self-calling function')
9163 var fn = ref
9164
9165 walk.recursive(ast, null, {
9166 Function: function (node, st, c) {
9167 if (node === fn) {
9168 c(node.body, st, "ScopeBody");
9169 }
9170 },
9171 ReturnStatement: function (node) {
9172 hasReturn = true
9173 replace(node, 'return {value: ' + source(node.argument) + '};');
9174 }
9175 });
9176 function source(node) {
9177 return src.slice(node.start, node.end).join('')
9178 }
9179 function replace(node, str) {
9180 for (var i = node.start; i < node.end; i++) {
9181 src[i] = ''
9182 }
9183 src[node.start] = str
9184 }
9185 if (!hasReturn) return originalSource
9186 else return 'var ' + result + '=' + src.join('') + ';if (' + result + ') return ' + result + '.value'
9187}
9188
9189},{"acorn":37,"acorn-globals":36,"acorn/dist/walk":38}],36:[function(require,module,exports){
9190arguments[4][31][0].apply(exports,arguments)
9191},{"acorn":37,"acorn/dist/walk":38,"dup":31}],37:[function(require,module,exports){
9192arguments[4][32][0].apply(exports,arguments)
9193},{"dup":32}],38:[function(require,module,exports){
9194arguments[4][33][0].apply(exports,arguments)
9195},{"dup":33}]},{},[1])(1)
9196});
\No newline at end of file