source: frontend/node_modules/jsonpath/jsonpath.js

Last change on this file was 9af201e, checked in by MBK <marija.karapandzova@…>, 11 days ago

Fix frontend appearance

  • Property mode set to 100644
File size: 222.1 KB
Line 
1/*! jsonpath 1.3.0 */
2
3(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.jsonpath = 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})({"./aesprim":[function(require,module,exports){
4/*
5 Copyright (C) 2013 Ariya Hidayat <ariya.hidayat@gmail.com>
6 Copyright (C) 2013 Thaddee Tyl <thaddee.tyl@gmail.com>
7 Copyright (C) 2013 Mathias Bynens <mathias@qiwi.be>
8 Copyright (C) 2012 Ariya Hidayat <ariya.hidayat@gmail.com>
9 Copyright (C) 2012 Mathias Bynens <mathias@qiwi.be>
10 Copyright (C) 2012 Joost-Wim Boekesteijn <joost-wim@boekesteijn.nl>
11 Copyright (C) 2012 Kris Kowal <kris.kowal@cixar.com>
12 Copyright (C) 2012 Yusuke Suzuki <utatane.tea@gmail.com>
13 Copyright (C) 2012 Arpad Borsos <arpad.borsos@googlemail.com>
14 Copyright (C) 2011 Ariya Hidayat <ariya.hidayat@gmail.com>
15
16 Redistribution and use in source and binary forms, with or without
17 modification, are permitted provided that the following conditions are met:
18
19 * Redistributions of source code must retain the above copyright
20 notice, this list of conditions and the following disclaimer.
21 * Redistributions in binary form must reproduce the above copyright
22 notice, this list of conditions and the following disclaimer in the
23 documentation and/or other materials provided with the distribution.
24
25 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
29 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
30 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
31 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
32 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
34 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35*/
36
37/*jslint bitwise:true plusplus:true */
38/*global esprima:true, define:true, exports:true, window: true,
39throwErrorTolerant: true,
40throwError: true, generateStatement: true, peek: true,
41parseAssignmentExpression: true, parseBlock: true, parseExpression: true,
42parseFunctionDeclaration: true, parseFunctionExpression: true,
43parseFunctionSourceElements: true, parseVariableIdentifier: true,
44parseLeftHandSideExpression: true,
45parseUnaryExpression: true,
46parseStatement: true, parseSourceElement: true */
47
48(function (root, factory) {
49 'use strict';
50
51 // Universal Module Definition (UMD) to support AMD, CommonJS/Node.js,
52 // Rhino, and plain browser loading.
53
54 /* istanbul ignore next */
55 if (typeof define === 'function' && define.amd) {
56 define(['exports'], factory);
57 } else if (typeof exports !== 'undefined') {
58 factory(exports);
59 } else {
60 factory((root.esprima = {}));
61 }
62}(this, function (exports) {
63 'use strict';
64
65 var Token,
66 TokenName,
67 FnExprTokens,
68 Syntax,
69 PropertyKind,
70 Messages,
71 Regex,
72 SyntaxTreeDelegate,
73 source,
74 strict,
75 index,
76 lineNumber,
77 lineStart,
78 length,
79 delegate,
80 lookahead,
81 state,
82 extra;
83
84 Token = {
85 BooleanLiteral: 1,
86 EOF: 2,
87 Identifier: 3,
88 Keyword: 4,
89 NullLiteral: 5,
90 NumericLiteral: 6,
91 Punctuator: 7,
92 StringLiteral: 8,
93 RegularExpression: 9
94 };
95
96 TokenName = {};
97 TokenName[Token.BooleanLiteral] = 'Boolean';
98 TokenName[Token.EOF] = '<end>';
99 TokenName[Token.Identifier] = 'Identifier';
100 TokenName[Token.Keyword] = 'Keyword';
101 TokenName[Token.NullLiteral] = 'Null';
102 TokenName[Token.NumericLiteral] = 'Numeric';
103 TokenName[Token.Punctuator] = 'Punctuator';
104 TokenName[Token.StringLiteral] = 'String';
105 TokenName[Token.RegularExpression] = 'RegularExpression';
106
107 // A function following one of those tokens is an expression.
108 FnExprTokens = ['(', '{', '[', 'in', 'typeof', 'instanceof', 'new',
109 'return', 'case', 'delete', 'throw', 'void',
110 // assignment operators
111 '=', '+=', '-=', '*=', '/=', '%=', '<<=', '>>=', '>>>=',
112 '&=', '|=', '^=', ',',
113 // binary/unary operators
114 '+', '-', '*', '/', '%', '++', '--', '<<', '>>', '>>>', '&',
115 '|', '^', '!', '~', '&&', '||', '?', ':', '===', '==', '>=',
116 '<=', '<', '>', '!=', '!=='];
117
118 Syntax = {
119 AssignmentExpression: 'AssignmentExpression',
120 ArrayExpression: 'ArrayExpression',
121 BlockStatement: 'BlockStatement',
122 BinaryExpression: 'BinaryExpression',
123 BreakStatement: 'BreakStatement',
124 CallExpression: 'CallExpression',
125 CatchClause: 'CatchClause',
126 ConditionalExpression: 'ConditionalExpression',
127 ContinueStatement: 'ContinueStatement',
128 DoWhileStatement: 'DoWhileStatement',
129 DebuggerStatement: 'DebuggerStatement',
130 EmptyStatement: 'EmptyStatement',
131 ExpressionStatement: 'ExpressionStatement',
132 ForStatement: 'ForStatement',
133 ForInStatement: 'ForInStatement',
134 FunctionDeclaration: 'FunctionDeclaration',
135 FunctionExpression: 'FunctionExpression',
136 Identifier: 'Identifier',
137 IfStatement: 'IfStatement',
138 Literal: 'Literal',
139 LabeledStatement: 'LabeledStatement',
140 LogicalExpression: 'LogicalExpression',
141 MemberExpression: 'MemberExpression',
142 NewExpression: 'NewExpression',
143 ObjectExpression: 'ObjectExpression',
144 Program: 'Program',
145 Property: 'Property',
146 ReturnStatement: 'ReturnStatement',
147 SequenceExpression: 'SequenceExpression',
148 SwitchStatement: 'SwitchStatement',
149 SwitchCase: 'SwitchCase',
150 ThisExpression: 'ThisExpression',
151 ThrowStatement: 'ThrowStatement',
152 TryStatement: 'TryStatement',
153 UnaryExpression: 'UnaryExpression',
154 UpdateExpression: 'UpdateExpression',
155 VariableDeclaration: 'VariableDeclaration',
156 VariableDeclarator: 'VariableDeclarator',
157 WhileStatement: 'WhileStatement',
158 WithStatement: 'WithStatement'
159 };
160
161 PropertyKind = {
162 Data: 1,
163 Get: 2,
164 Set: 4
165 };
166
167 // Error messages should be identical to V8.
168 Messages = {
169 UnexpectedToken: 'Unexpected token %0',
170 UnexpectedNumber: 'Unexpected number',
171 UnexpectedString: 'Unexpected string',
172 UnexpectedIdentifier: 'Unexpected identifier',
173 UnexpectedReserved: 'Unexpected reserved word',
174 UnexpectedEOS: 'Unexpected end of input',
175 NewlineAfterThrow: 'Illegal newline after throw',
176 InvalidRegExp: 'Invalid regular expression',
177 UnterminatedRegExp: 'Invalid regular expression: missing /',
178 InvalidLHSInAssignment: 'Invalid left-hand side in assignment',
179 InvalidLHSInForIn: 'Invalid left-hand side in for-in',
180 MultipleDefaultsInSwitch: 'More than one default clause in switch statement',
181 NoCatchOrFinally: 'Missing catch or finally after try',
182 UnknownLabel: 'Undefined label \'%0\'',
183 Redeclaration: '%0 \'%1\' has already been declared',
184 IllegalContinue: 'Illegal continue statement',
185 IllegalBreak: 'Illegal break statement',
186 IllegalReturn: 'Illegal return statement',
187 StrictModeWith: 'Strict mode code may not include a with statement',
188 StrictCatchVariable: 'Catch variable may not be eval or arguments in strict mode',
189 StrictVarName: 'Variable name may not be eval or arguments in strict mode',
190 StrictParamName: 'Parameter name eval or arguments is not allowed in strict mode',
191 StrictParamDupe: 'Strict mode function may not have duplicate parameter names',
192 StrictFunctionName: 'Function name may not be eval or arguments in strict mode',
193 StrictOctalLiteral: 'Octal literals are not allowed in strict mode.',
194 StrictDelete: 'Delete of an unqualified identifier in strict mode.',
195 StrictDuplicateProperty: 'Duplicate data property in object literal not allowed in strict mode',
196 AccessorDataProperty: 'Object literal may not have data and accessor property with the same name',
197 AccessorGetSet: 'Object literal may not have multiple get/set accessors with the same name',
198 StrictLHSAssignment: 'Assignment to eval or arguments is not allowed in strict mode',
199 StrictLHSPostfix: 'Postfix increment/decrement may not have eval or arguments operand in strict mode',
200 StrictLHSPrefix: 'Prefix increment/decrement may not have eval or arguments operand in strict mode',
201 StrictReservedWord: 'Use of future reserved word in strict mode'
202 };
203
204 // See also tools/generate-unicode-regex.py.
205 Regex = {
206 NonAsciiIdentifierStart: new RegExp('[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0\u08A2-\u08AC\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0977\u0979-\u097F\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C3D\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F0\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191C\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA697\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA793\uA7A0-\uA7AA\uA7F8-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA80-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]'),
207 NonAsciiIdentifierPart: new RegExp('[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u0527\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u05D0-\u05EA\u05F0-\u05F2\u0610-\u061A\u0620-\u0669\u066E-\u06D3\u06D5-\u06DC\u06DF-\u06E8\u06EA-\u06FC\u06FF\u0710-\u074A\u074D-\u07B1\u07C0-\u07F5\u07FA\u0800-\u082D\u0840-\u085B\u08A0\u08A2-\u08AC\u08E4-\u08FE\u0900-\u0963\u0966-\u096F\u0971-\u0977\u0979-\u097F\u0981-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BC-\u09C4\u09C7\u09C8\u09CB-\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09E6-\u09F1\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A59-\u0A5C\u0A5E\u0A66-\u0A75\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABC-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AD0\u0AE0-\u0AE3\u0AE6-\u0AEF\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3C-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B66-\u0B6F\u0B71\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD0\u0BD7\u0BE6-\u0BEF\u0C01-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58\u0C59\u0C60-\u0C63\u0C66-\u0C6F\u0C82\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBC-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CDE\u0CE0-\u0CE3\u0CE6-\u0CEF\u0CF1\u0CF2\u0D02\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D-\u0D44\u0D46-\u0D48\u0D4A-\u0D4E\u0D57\u0D60-\u0D63\u0D66-\u0D6F\u0D7A-\u0D7F\u0D82\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DF2\u0DF3\u0E01-\u0E3A\u0E40-\u0E4E\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB9\u0EBB-\u0EBD\u0EC0-\u0EC4\u0EC6\u0EC8-\u0ECD\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E-\u0F47\u0F49-\u0F6C\u0F71-\u0F84\u0F86-\u0F97\u0F99-\u0FBC\u0FC6\u1000-\u1049\u1050-\u109D\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u135D-\u135F\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F0\u1700-\u170C\u170E-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176C\u176E-\u1770\u1772\u1773\u1780-\u17D3\u17D7\u17DC\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u1820-\u1877\u1880-\u18AA\u18B0-\u18F5\u1900-\u191C\u1920-\u192B\u1930-\u193B\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19D9\u1A00-\u1A1B\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA7\u1B00-\u1B4B\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1BF3\u1C00-\u1C37\u1C40-\u1C49\u1C4D-\u1C7D\u1CD0-\u1CD2\u1CD4-\u1CF6\u1D00-\u1DE6\u1DFC-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u200C\u200D\u203F\u2040\u2054\u2071\u207F\u2090-\u209C\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D7F-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2DE0-\u2DFF\u2E2F\u3005-\u3007\u3021-\u302F\u3031-\u3035\u3038-\u303C\u3041-\u3096\u3099\u309A\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66F\uA674-\uA67D\uA67F-\uA697\uA69F-\uA6F1\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA793\uA7A0-\uA7AA\uA7F8-\uA827\uA840-\uA873\uA880-\uA8C4\uA8D0-\uA8D9\uA8E0-\uA8F7\uA8FB\uA900-\uA92D\uA930-\uA953\uA960-\uA97C\uA980-\uA9C0\uA9CF-\uA9D9\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA60-\uAA76\uAA7A\uAA7B\uAA80-\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF6\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uABC0-\uABEA\uABEC\uABED\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE00-\uFE0F\uFE20-\uFE26\uFE33\uFE34\uFE4D-\uFE4F\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF3F\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]')
208 };
209
210 // Ensure the condition is true, otherwise throw an error.
211 // This is only to have a better contract semantic, i.e. another safety net
212 // to catch a logic error. The condition shall be fulfilled in normal case.
213 // Do NOT use this to enforce a certain condition on any user input.
214
215 function assert(condition, message) {
216 /* istanbul ignore if */
217 if (!condition) {
218 throw new Error('ASSERT: ' + message);
219 }
220 }
221
222 function isDecimalDigit(ch) {
223 return (ch >= 48 && ch <= 57); // 0..9
224 }
225
226 function isHexDigit(ch) {
227 return '0123456789abcdefABCDEF'.indexOf(ch) >= 0;
228 }
229
230 function isOctalDigit(ch) {
231 return '01234567'.indexOf(ch) >= 0;
232 }
233
234
235 // 7.2 White Space
236
237 function isWhiteSpace(ch) {
238 return (ch === 0x20) || (ch === 0x09) || (ch === 0x0B) || (ch === 0x0C) || (ch === 0xA0) ||
239 (ch >= 0x1680 && [0x1680, 0x180E, 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006, 0x2007, 0x2008, 0x2009, 0x200A, 0x202F, 0x205F, 0x3000, 0xFEFF].indexOf(ch) >= 0);
240 }
241
242 // 7.3 Line Terminators
243
244 function isLineTerminator(ch) {
245 return (ch === 0x0A) || (ch === 0x0D) || (ch === 0x2028) || (ch === 0x2029);
246 }
247
248 // 7.6 Identifier Names and Identifiers
249
250 function isIdentifierStart(ch) {
251 return (ch == 0x40) || (ch === 0x24) || (ch === 0x5F) || // $ (dollar) and _ (underscore)
252 (ch >= 0x41 && ch <= 0x5A) || // A..Z
253 (ch >= 0x61 && ch <= 0x7A) || // a..z
254 (ch === 0x5C) || // \ (backslash)
255 ((ch >= 0x80) && Regex.NonAsciiIdentifierStart.test(String.fromCharCode(ch)));
256 }
257
258 function isIdentifierPart(ch) {
259 return (ch === 0x24) || (ch === 0x5F) || // $ (dollar) and _ (underscore)
260 (ch >= 0x41 && ch <= 0x5A) || // A..Z
261 (ch >= 0x61 && ch <= 0x7A) || // a..z
262 (ch >= 0x30 && ch <= 0x39) || // 0..9
263 (ch === 0x5C) || // \ (backslash)
264 ((ch >= 0x80) && Regex.NonAsciiIdentifierPart.test(String.fromCharCode(ch)));
265 }
266
267 // 7.6.1.2 Future Reserved Words
268
269 function isFutureReservedWord(id) {
270 switch (id) {
271 case 'class':
272 case 'enum':
273 case 'export':
274 case 'extends':
275 case 'import':
276 case 'super':
277 return true;
278 default:
279 return false;
280 }
281 }
282
283 function isStrictModeReservedWord(id) {
284 switch (id) {
285 case 'implements':
286 case 'interface':
287 case 'package':
288 case 'private':
289 case 'protected':
290 case 'public':
291 case 'static':
292 case 'yield':
293 case 'let':
294 return true;
295 default:
296 return false;
297 }
298 }
299
300 function isRestrictedWord(id) {
301 return id === 'eval' || id === 'arguments';
302 }
303
304 // 7.6.1.1 Keywords
305
306 function isKeyword(id) {
307 if (strict && isStrictModeReservedWord(id)) {
308 return true;
309 }
310
311 // 'const' is specialized as Keyword in V8.
312 // 'yield' and 'let' are for compatiblity with SpiderMonkey and ES.next.
313 // Some others are from future reserved words.
314
315 switch (id.length) {
316 case 2:
317 return (id === 'if') || (id === 'in') || (id === 'do');
318 case 3:
319 return (id === 'var') || (id === 'for') || (id === 'new') ||
320 (id === 'try') || (id === 'let');
321 case 4:
322 return (id === 'this') || (id === 'else') || (id === 'case') ||
323 (id === 'void') || (id === 'with') || (id === 'enum');
324 case 5:
325 return (id === 'while') || (id === 'break') || (id === 'catch') ||
326 (id === 'throw') || (id === 'const') || (id === 'yield') ||
327 (id === 'class') || (id === 'super');
328 case 6:
329 return (id === 'return') || (id === 'typeof') || (id === 'delete') ||
330 (id === 'switch') || (id === 'export') || (id === 'import');
331 case 7:
332 return (id === 'default') || (id === 'finally') || (id === 'extends');
333 case 8:
334 return (id === 'function') || (id === 'continue') || (id === 'debugger');
335 case 10:
336 return (id === 'instanceof');
337 default:
338 return false;
339 }
340 }
341
342 // 7.4 Comments
343
344 function addComment(type, value, start, end, loc) {
345 var comment, attacher;
346
347 assert(typeof start === 'number', 'Comment must have valid position');
348
349 // Because the way the actual token is scanned, often the comments
350 // (if any) are skipped twice during the lexical analysis.
351 // Thus, we need to skip adding a comment if the comment array already
352 // handled it.
353 if (state.lastCommentStart >= start) {
354 return;
355 }
356 state.lastCommentStart = start;
357
358 comment = {
359 type: type,
360 value: value
361 };
362 if (extra.range) {
363 comment.range = [start, end];
364 }
365 if (extra.loc) {
366 comment.loc = loc;
367 }
368 extra.comments.push(comment);
369 if (extra.attachComment) {
370 extra.leadingComments.push(comment);
371 extra.trailingComments.push(comment);
372 }
373 }
374
375 function skipSingleLineComment(offset) {
376 var start, loc, ch, comment;
377
378 start = index - offset;
379 loc = {
380 start: {
381 line: lineNumber,
382 column: index - lineStart - offset
383 }
384 };
385
386 while (index < length) {
387 ch = source.charCodeAt(index);
388 ++index;
389 if (isLineTerminator(ch)) {
390 if (extra.comments) {
391 comment = source.slice(start + offset, index - 1);
392 loc.end = {
393 line: lineNumber,
394 column: index - lineStart - 1
395 };
396 addComment('Line', comment, start, index - 1, loc);
397 }
398 if (ch === 13 && source.charCodeAt(index) === 10) {
399 ++index;
400 }
401 ++lineNumber;
402 lineStart = index;
403 return;
404 }
405 }
406
407 if (extra.comments) {
408 comment = source.slice(start + offset, index);
409 loc.end = {
410 line: lineNumber,
411 column: index - lineStart
412 };
413 addComment('Line', comment, start, index, loc);
414 }
415 }
416
417 function skipMultiLineComment() {
418 var start, loc, ch, comment;
419
420 if (extra.comments) {
421 start = index - 2;
422 loc = {
423 start: {
424 line: lineNumber,
425 column: index - lineStart - 2
426 }
427 };
428 }
429
430 while (index < length) {
431 ch = source.charCodeAt(index);
432 if (isLineTerminator(ch)) {
433 if (ch === 0x0D && source.charCodeAt(index + 1) === 0x0A) {
434 ++index;
435 }
436 ++lineNumber;
437 ++index;
438 lineStart = index;
439 if (index >= length) {
440 throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
441 }
442 } else if (ch === 0x2A) {
443 // Block comment ends with '*/'.
444 if (source.charCodeAt(index + 1) === 0x2F) {
445 ++index;
446 ++index;
447 if (extra.comments) {
448 comment = source.slice(start + 2, index - 2);
449 loc.end = {
450 line: lineNumber,
451 column: index - lineStart
452 };
453 addComment('Block', comment, start, index, loc);
454 }
455 return;
456 }
457 ++index;
458 } else {
459 ++index;
460 }
461 }
462
463 throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
464 }
465
466 function skipComment() {
467 var ch, start;
468
469 start = (index === 0);
470 while (index < length) {
471 ch = source.charCodeAt(index);
472
473 if (isWhiteSpace(ch)) {
474 ++index;
475 } else if (isLineTerminator(ch)) {
476 ++index;
477 if (ch === 0x0D && source.charCodeAt(index) === 0x0A) {
478 ++index;
479 }
480 ++lineNumber;
481 lineStart = index;
482 start = true;
483 } else if (ch === 0x2F) { // U+002F is '/'
484 ch = source.charCodeAt(index + 1);
485 if (ch === 0x2F) {
486 ++index;
487 ++index;
488 skipSingleLineComment(2);
489 start = true;
490 } else if (ch === 0x2A) { // U+002A is '*'
491 ++index;
492 ++index;
493 skipMultiLineComment();
494 } else {
495 break;
496 }
497 } else if (start && ch === 0x2D) { // U+002D is '-'
498 // U+003E is '>'
499 if ((source.charCodeAt(index + 1) === 0x2D) && (source.charCodeAt(index + 2) === 0x3E)) {
500 // '-->' is a single-line comment
501 index += 3;
502 skipSingleLineComment(3);
503 } else {
504 break;
505 }
506 } else if (ch === 0x3C) { // U+003C is '<'
507 if (source.slice(index + 1, index + 4) === '!--') {
508 ++index; // `<`
509 ++index; // `!`
510 ++index; // `-`
511 ++index; // `-`
512 skipSingleLineComment(4);
513 } else {
514 break;
515 }
516 } else {
517 break;
518 }
519 }
520 }
521
522 function scanHexEscape(prefix) {
523 var i, len, ch, code = 0;
524
525 len = (prefix === 'u') ? 4 : 2;
526 for (i = 0; i < len; ++i) {
527 if (index < length && isHexDigit(source[index])) {
528 ch = source[index++];
529 code = code * 16 + '0123456789abcdef'.indexOf(ch.toLowerCase());
530 } else {
531 return '';
532 }
533 }
534 return String.fromCharCode(code);
535 }
536
537 function getEscapedIdentifier() {
538 var ch, id;
539
540 ch = source.charCodeAt(index++);
541 id = String.fromCharCode(ch);
542
543 // '\u' (U+005C, U+0075) denotes an escaped character.
544 if (ch === 0x5C) {
545 if (source.charCodeAt(index) !== 0x75) {
546 throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
547 }
548 ++index;
549 ch = scanHexEscape('u');
550 if (!ch || ch === '\\' || !isIdentifierStart(ch.charCodeAt(0))) {
551 throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
552 }
553 id = ch;
554 }
555
556 while (index < length) {
557 ch = source.charCodeAt(index);
558 if (!isIdentifierPart(ch)) {
559 break;
560 }
561 ++index;
562 id += String.fromCharCode(ch);
563
564 // '\u' (U+005C, U+0075) denotes an escaped character.
565 if (ch === 0x5C) {
566 id = id.substr(0, id.length - 1);
567 if (source.charCodeAt(index) !== 0x75) {
568 throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
569 }
570 ++index;
571 ch = scanHexEscape('u');
572 if (!ch || ch === '\\' || !isIdentifierPart(ch.charCodeAt(0))) {
573 throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
574 }
575 id += ch;
576 }
577 }
578
579 return id;
580 }
581
582 function getIdentifier() {
583 var start, ch;
584
585 start = index++;
586 while (index < length) {
587 ch = source.charCodeAt(index);
588 if (ch === 0x5C) {
589 // Blackslash (U+005C) marks Unicode escape sequence.
590 index = start;
591 return getEscapedIdentifier();
592 }
593 if (isIdentifierPart(ch)) {
594 ++index;
595 } else {
596 break;
597 }
598 }
599
600 return source.slice(start, index);
601 }
602
603 function scanIdentifier() {
604 var start, id, type;
605
606 start = index;
607
608 // Backslash (U+005C) starts an escaped character.
609 id = (source.charCodeAt(index) === 0x5C) ? getEscapedIdentifier() : getIdentifier();
610
611 // There is no keyword or literal with only one character.
612 // Thus, it must be an identifier.
613 if (id.length === 1) {
614 type = Token.Identifier;
615 } else if (isKeyword(id)) {
616 type = Token.Keyword;
617 } else if (id === 'null') {
618 type = Token.NullLiteral;
619 } else if (id === 'true' || id === 'false') {
620 type = Token.BooleanLiteral;
621 } else {
622 type = Token.Identifier;
623 }
624
625 return {
626 type: type,
627 value: id,
628 lineNumber: lineNumber,
629 lineStart: lineStart,
630 start: start,
631 end: index
632 };
633 }
634
635
636 // 7.7 Punctuators
637
638 function scanPunctuator() {
639 var start = index,
640 code = source.charCodeAt(index),
641 code2,
642 ch1 = source[index],
643 ch2,
644 ch3,
645 ch4;
646
647 switch (code) {
648
649 // Check for most common single-character punctuators.
650 case 0x2E: // . dot
651 case 0x28: // ( open bracket
652 case 0x29: // ) close bracket
653 case 0x3B: // ; semicolon
654 case 0x2C: // , comma
655 case 0x7B: // { open curly brace
656 case 0x7D: // } close curly brace
657 case 0x5B: // [
658 case 0x5D: // ]
659 case 0x3A: // :
660 case 0x3F: // ?
661 case 0x7E: // ~
662 ++index;
663 if (extra.tokenize) {
664 if (code === 0x28) {
665 extra.openParenToken = extra.tokens.length;
666 } else if (code === 0x7B) {
667 extra.openCurlyToken = extra.tokens.length;
668 }
669 }
670 return {
671 type: Token.Punctuator,
672 value: String.fromCharCode(code),
673 lineNumber: lineNumber,
674 lineStart: lineStart,
675 start: start,
676 end: index
677 };
678
679 default:
680 code2 = source.charCodeAt(index + 1);
681
682 // '=' (U+003D) marks an assignment or comparison operator.
683 if (code2 === 0x3D) {
684 switch (code) {
685 case 0x2B: // +
686 case 0x2D: // -
687 case 0x2F: // /
688 case 0x3C: // <
689 case 0x3E: // >
690 case 0x5E: // ^
691 case 0x7C: // |
692 case 0x25: // %
693 case 0x26: // &
694 case 0x2A: // *
695 index += 2;
696 return {
697 type: Token.Punctuator,
698 value: String.fromCharCode(code) + String.fromCharCode(code2),
699 lineNumber: lineNumber,
700 lineStart: lineStart,
701 start: start,
702 end: index
703 };
704
705 case 0x21: // !
706 case 0x3D: // =
707 index += 2;
708
709 // !== and ===
710 if (source.charCodeAt(index) === 0x3D) {
711 ++index;
712 }
713 return {
714 type: Token.Punctuator,
715 value: source.slice(start, index),
716 lineNumber: lineNumber,
717 lineStart: lineStart,
718 start: start,
719 end: index
720 };
721 }
722 }
723 }
724
725 // 4-character punctuator: >>>=
726
727 ch4 = source.substr(index, 4);
728
729 if (ch4 === '>>>=') {
730 index += 4;
731 return {
732 type: Token.Punctuator,
733 value: ch4,
734 lineNumber: lineNumber,
735 lineStart: lineStart,
736 start: start,
737 end: index
738 };
739 }
740
741 // 3-character punctuators: === !== >>> <<= >>=
742
743 ch3 = ch4.substr(0, 3);
744
745 if (ch3 === '>>>' || ch3 === '<<=' || ch3 === '>>=') {
746 index += 3;
747 return {
748 type: Token.Punctuator,
749 value: ch3,
750 lineNumber: lineNumber,
751 lineStart: lineStart,
752 start: start,
753 end: index
754 };
755 }
756
757 // Other 2-character punctuators: ++ -- << >> && ||
758 ch2 = ch3.substr(0, 2);
759
760 if ((ch1 === ch2[1] && ('+-<>&|'.indexOf(ch1) >= 0)) || ch2 === '=>') {
761 index += 2;
762 return {
763 type: Token.Punctuator,
764 value: ch2,
765 lineNumber: lineNumber,
766 lineStart: lineStart,
767 start: start,
768 end: index
769 };
770 }
771
772 // 1-character punctuators: < > = ! + - * % & | ^ /
773 if ('<>=!+-*%&|^/'.indexOf(ch1) >= 0) {
774 ++index;
775 return {
776 type: Token.Punctuator,
777 value: ch1,
778 lineNumber: lineNumber,
779 lineStart: lineStart,
780 start: start,
781 end: index
782 };
783 }
784
785 throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
786 }
787
788 // 7.8.3 Numeric Literals
789
790 function scanHexLiteral(start) {
791 var number = '';
792
793 while (index < length) {
794 if (!isHexDigit(source[index])) {
795 break;
796 }
797 number += source[index++];
798 }
799
800 if (number.length === 0) {
801 throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
802 }
803
804 if (isIdentifierStart(source.charCodeAt(index))) {
805 throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
806 }
807
808 return {
809 type: Token.NumericLiteral,
810 value: parseInt('0x' + number, 16),
811 lineNumber: lineNumber,
812 lineStart: lineStart,
813 start: start,
814 end: index
815 };
816 }
817
818 function scanOctalLiteral(start) {
819 var number = '0' + source[index++];
820 while (index < length) {
821 if (!isOctalDigit(source[index])) {
822 break;
823 }
824 number += source[index++];
825 }
826
827 if (isIdentifierStart(source.charCodeAt(index)) || isDecimalDigit(source.charCodeAt(index))) {
828 throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
829 }
830
831 return {
832 type: Token.NumericLiteral,
833 value: parseInt(number, 8),
834 octal: true,
835 lineNumber: lineNumber,
836 lineStart: lineStart,
837 start: start,
838 end: index
839 };
840 }
841
842 function isImplicitOctalLiteral() {
843 var i, ch;
844
845 // Implicit octal, unless there is a non-octal digit.
846 // (Annex B.1.1 on Numeric Literals)
847 for (i = index + 1; i < length; ++i) {
848 ch = source[i];
849 if (ch === '8' || ch === '9') {
850 return false;
851 }
852 if (!isOctalDigit(ch)) {
853 return true;
854 }
855 }
856
857 return true;
858 }
859
860 function scanNumericLiteral() {
861 var number, start, ch;
862
863 ch = source[index];
864 assert(isDecimalDigit(ch.charCodeAt(0)) || (ch === '.'),
865 'Numeric literal must start with a decimal digit or a decimal point');
866
867 start = index;
868 number = '';
869 if (ch !== '.') {
870 number = source[index++];
871 ch = source[index];
872
873 // Hex number starts with '0x'.
874 // Octal number starts with '0'.
875 if (number === '0') {
876 if (ch === 'x' || ch === 'X') {
877 ++index;
878 return scanHexLiteral(start);
879 }
880 if (isOctalDigit(ch)) {
881 if (isImplicitOctalLiteral()) {
882 return scanOctalLiteral(start);
883 }
884 }
885 }
886
887 while (isDecimalDigit(source.charCodeAt(index))) {
888 number += source[index++];
889 }
890 ch = source[index];
891 }
892
893 if (ch === '.') {
894 number += source[index++];
895 while (isDecimalDigit(source.charCodeAt(index))) {
896 number += source[index++];
897 }
898 ch = source[index];
899 }
900
901 if (ch === 'e' || ch === 'E') {
902 number += source[index++];
903
904 ch = source[index];
905 if (ch === '+' || ch === '-') {
906 number += source[index++];
907 }
908 if (isDecimalDigit(source.charCodeAt(index))) {
909 while (isDecimalDigit(source.charCodeAt(index))) {
910 number += source[index++];
911 }
912 } else {
913 throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
914 }
915 }
916
917 if (isIdentifierStart(source.charCodeAt(index))) {
918 throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
919 }
920
921 return {
922 type: Token.NumericLiteral,
923 value: parseFloat(number),
924 lineNumber: lineNumber,
925 lineStart: lineStart,
926 start: start,
927 end: index
928 };
929 }
930
931 // 7.8.4 String Literals
932
933 function scanStringLiteral() {
934 var str = '', quote, start, ch, code, unescaped, restore, octal = false, startLineNumber, startLineStart;
935 startLineNumber = lineNumber;
936 startLineStart = lineStart;
937
938 quote = source[index];
939 assert((quote === '\'' || quote === '"'),
940 'String literal must starts with a quote');
941
942 start = index;
943 ++index;
944
945 while (index < length) {
946 ch = source[index++];
947
948 if (ch === quote) {
949 quote = '';
950 break;
951 } else if (ch === '\\') {
952 ch = source[index++];
953 if (!ch || !isLineTerminator(ch.charCodeAt(0))) {
954 switch (ch) {
955 case 'u':
956 case 'x':
957 restore = index;
958 unescaped = scanHexEscape(ch);
959 if (unescaped) {
960 str += unescaped;
961 } else {
962 index = restore;
963 str += ch;
964 }
965 break;
966 case 'n':
967 str += '\n';
968 break;
969 case 'r':
970 str += '\r';
971 break;
972 case 't':
973 str += '\t';
974 break;
975 case 'b':
976 str += '\b';
977 break;
978 case 'f':
979 str += '\f';
980 break;
981 case 'v':
982 str += '\x0B';
983 break;
984
985 default:
986 if (isOctalDigit(ch)) {
987 code = '01234567'.indexOf(ch);
988
989 // \0 is not octal escape sequence
990 if (code !== 0) {
991 octal = true;
992 }
993
994 if (index < length && isOctalDigit(source[index])) {
995 octal = true;
996 code = code * 8 + '01234567'.indexOf(source[index++]);
997
998 // 3 digits are only allowed when string starts
999 // with 0, 1, 2, 3
1000 if ('0123'.indexOf(ch) >= 0 &&
1001 index < length &&
1002 isOctalDigit(source[index])) {
1003 code = code * 8 + '01234567'.indexOf(source[index++]);
1004 }
1005 }
1006 str += String.fromCharCode(code);
1007 } else {
1008 str += ch;
1009 }
1010 break;
1011 }
1012 } else {
1013 ++lineNumber;
1014 if (ch === '\r' && source[index] === '\n') {
1015 ++index;
1016 }
1017 lineStart = index;
1018 }
1019 } else if (isLineTerminator(ch.charCodeAt(0))) {
1020 break;
1021 } else {
1022 str += ch;
1023 }
1024 }
1025
1026 if (quote !== '') {
1027 throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
1028 }
1029
1030 return {
1031 type: Token.StringLiteral,
1032 value: str,
1033 octal: octal,
1034 startLineNumber: startLineNumber,
1035 startLineStart: startLineStart,
1036 lineNumber: lineNumber,
1037 lineStart: lineStart,
1038 start: start,
1039 end: index
1040 };
1041 }
1042
1043 function testRegExp(pattern, flags) {
1044 var value;
1045 try {
1046 value = new RegExp(pattern, flags);
1047 } catch (e) {
1048 throwError({}, Messages.InvalidRegExp);
1049 }
1050 return value;
1051 }
1052
1053 function scanRegExpBody() {
1054 var ch, str, classMarker, terminated, body;
1055
1056 ch = source[index];
1057 assert(ch === '/', 'Regular expression literal must start with a slash');
1058 str = source[index++];
1059
1060 classMarker = false;
1061 terminated = false;
1062 while (index < length) {
1063 ch = source[index++];
1064 str += ch;
1065 if (ch === '\\') {
1066 ch = source[index++];
1067 // ECMA-262 7.8.5
1068 if (isLineTerminator(ch.charCodeAt(0))) {
1069 throwError({}, Messages.UnterminatedRegExp);
1070 }
1071 str += ch;
1072 } else if (isLineTerminator(ch.charCodeAt(0))) {
1073 throwError({}, Messages.UnterminatedRegExp);
1074 } else if (classMarker) {
1075 if (ch === ']') {
1076 classMarker = false;
1077 }
1078 } else {
1079 if (ch === '/') {
1080 terminated = true;
1081 break;
1082 } else if (ch === '[') {
1083 classMarker = true;
1084 }
1085 }
1086 }
1087
1088 if (!terminated) {
1089 throwError({}, Messages.UnterminatedRegExp);
1090 }
1091
1092 // Exclude leading and trailing slash.
1093 body = str.substr(1, str.length - 2);
1094 return {
1095 value: body,
1096 literal: str
1097 };
1098 }
1099
1100 function scanRegExpFlags() {
1101 var ch, str, flags, restore;
1102
1103 str = '';
1104 flags = '';
1105 while (index < length) {
1106 ch = source[index];
1107 if (!isIdentifierPart(ch.charCodeAt(0))) {
1108 break;
1109 }
1110
1111 ++index;
1112 if (ch === '\\' && index < length) {
1113 ch = source[index];
1114 if (ch === 'u') {
1115 ++index;
1116 restore = index;
1117 ch = scanHexEscape('u');
1118 if (ch) {
1119 flags += ch;
1120 for (str += '\\u'; restore < index; ++restore) {
1121 str += source[restore];
1122 }
1123 } else {
1124 index = restore;
1125 flags += 'u';
1126 str += '\\u';
1127 }
1128 throwErrorTolerant({}, Messages.UnexpectedToken, 'ILLEGAL');
1129 } else {
1130 str += '\\';
1131 throwErrorTolerant({}, Messages.UnexpectedToken, 'ILLEGAL');
1132 }
1133 } else {
1134 flags += ch;
1135 str += ch;
1136 }
1137 }
1138
1139 return {
1140 value: flags,
1141 literal: str
1142 };
1143 }
1144
1145 function scanRegExp() {
1146 var start, body, flags, pattern, value;
1147
1148 lookahead = null;
1149 skipComment();
1150 start = index;
1151
1152 body = scanRegExpBody();
1153 flags = scanRegExpFlags();
1154 value = testRegExp(body.value, flags.value);
1155
1156 if (extra.tokenize) {
1157 return {
1158 type: Token.RegularExpression,
1159 value: value,
1160 lineNumber: lineNumber,
1161 lineStart: lineStart,
1162 start: start,
1163 end: index
1164 };
1165 }
1166
1167 return {
1168 literal: body.literal + flags.literal,
1169 value: value,
1170 start: start,
1171 end: index
1172 };
1173 }
1174
1175 function collectRegex() {
1176 var pos, loc, regex, token;
1177
1178 skipComment();
1179
1180 pos = index;
1181 loc = {
1182 start: {
1183 line: lineNumber,
1184 column: index - lineStart
1185 }
1186 };
1187
1188 regex = scanRegExp();
1189 loc.end = {
1190 line: lineNumber,
1191 column: index - lineStart
1192 };
1193
1194 /* istanbul ignore next */
1195 if (!extra.tokenize) {
1196 // Pop the previous token, which is likely '/' or '/='
1197 if (extra.tokens.length > 0) {
1198 token = extra.tokens[extra.tokens.length - 1];
1199 if (token.range[0] === pos && token.type === 'Punctuator') {
1200 if (token.value === '/' || token.value === '/=') {
1201 extra.tokens.pop();
1202 }
1203 }
1204 }
1205
1206 extra.tokens.push({
1207 type: 'RegularExpression',
1208 value: regex.literal,
1209 range: [pos, index],
1210 loc: loc
1211 });
1212 }
1213
1214 return regex;
1215 }
1216
1217 function isIdentifierName(token) {
1218 return token.type === Token.Identifier ||
1219 token.type === Token.Keyword ||
1220 token.type === Token.BooleanLiteral ||
1221 token.type === Token.NullLiteral;
1222 }
1223
1224 function advanceSlash() {
1225 var prevToken,
1226 checkToken;
1227 // Using the following algorithm:
1228 // https://github.com/mozilla/sweet.js/wiki/design
1229 prevToken = extra.tokens[extra.tokens.length - 1];
1230 if (!prevToken) {
1231 // Nothing before that: it cannot be a division.
1232 return collectRegex();
1233 }
1234 if (prevToken.type === 'Punctuator') {
1235 if (prevToken.value === ']') {
1236 return scanPunctuator();
1237 }
1238 if (prevToken.value === ')') {
1239 checkToken = extra.tokens[extra.openParenToken - 1];
1240 if (checkToken &&
1241 checkToken.type === 'Keyword' &&
1242 (checkToken.value === 'if' ||
1243 checkToken.value === 'while' ||
1244 checkToken.value === 'for' ||
1245 checkToken.value === 'with')) {
1246 return collectRegex();
1247 }
1248 return scanPunctuator();
1249 }
1250 if (prevToken.value === '}') {
1251 // Dividing a function by anything makes little sense,
1252 // but we have to check for that.
1253 if (extra.tokens[extra.openCurlyToken - 3] &&
1254 extra.tokens[extra.openCurlyToken - 3].type === 'Keyword') {
1255 // Anonymous function.
1256 checkToken = extra.tokens[extra.openCurlyToken - 4];
1257 if (!checkToken) {
1258 return scanPunctuator();
1259 }
1260 } else if (extra.tokens[extra.openCurlyToken - 4] &&
1261 extra.tokens[extra.openCurlyToken - 4].type === 'Keyword') {
1262 // Named function.
1263 checkToken = extra.tokens[extra.openCurlyToken - 5];
1264 if (!checkToken) {
1265 return collectRegex();
1266 }
1267 } else {
1268 return scanPunctuator();
1269 }
1270 // checkToken determines whether the function is
1271 // a declaration or an expression.
1272 if (FnExprTokens.indexOf(checkToken.value) >= 0) {
1273 // It is an expression.
1274 return scanPunctuator();
1275 }
1276 // It is a declaration.
1277 return collectRegex();
1278 }
1279 return collectRegex();
1280 }
1281 if (prevToken.type === 'Keyword' && prevToken.value !== 'this') {
1282 return collectRegex();
1283 }
1284 return scanPunctuator();
1285 }
1286
1287 function advance() {
1288 var ch;
1289
1290 skipComment();
1291
1292 if (index >= length) {
1293 return {
1294 type: Token.EOF,
1295 lineNumber: lineNumber,
1296 lineStart: lineStart,
1297 start: index,
1298 end: index
1299 };
1300 }
1301
1302 ch = source.charCodeAt(index);
1303
1304 if (isIdentifierStart(ch)) {
1305 return scanIdentifier();
1306 }
1307
1308 // Very common: ( and ) and ;
1309 if (ch === 0x28 || ch === 0x29 || ch === 0x3B) {
1310 return scanPunctuator();
1311 }
1312
1313 // String literal starts with single quote (U+0027) or double quote (U+0022).
1314 if (ch === 0x27 || ch === 0x22) {
1315 return scanStringLiteral();
1316 }
1317
1318
1319 // Dot (.) U+002E can also start a floating-point number, hence the need
1320 // to check the next character.
1321 if (ch === 0x2E) {
1322 if (isDecimalDigit(source.charCodeAt(index + 1))) {
1323 return scanNumericLiteral();
1324 }
1325 return scanPunctuator();
1326 }
1327
1328 if (isDecimalDigit(ch)) {
1329 return scanNumericLiteral();
1330 }
1331
1332 // Slash (/) U+002F can also start a regex.
1333 if (extra.tokenize && ch === 0x2F) {
1334 return advanceSlash();
1335 }
1336
1337 return scanPunctuator();
1338 }
1339
1340 function collectToken() {
1341 var loc, token, range, value;
1342
1343 skipComment();
1344 loc = {
1345 start: {
1346 line: lineNumber,
1347 column: index - lineStart
1348 }
1349 };
1350
1351 token = advance();
1352 loc.end = {
1353 line: lineNumber,
1354 column: index - lineStart
1355 };
1356
1357 if (token.type !== Token.EOF) {
1358 value = source.slice(token.start, token.end);
1359 extra.tokens.push({
1360 type: TokenName[token.type],
1361 value: value,
1362 range: [token.start, token.end],
1363 loc: loc
1364 });
1365 }
1366
1367 return token;
1368 }
1369
1370 function lex() {
1371 var token;
1372
1373 token = lookahead;
1374 index = token.end;
1375 lineNumber = token.lineNumber;
1376 lineStart = token.lineStart;
1377
1378 lookahead = (typeof extra.tokens !== 'undefined') ? collectToken() : advance();
1379
1380 index = token.end;
1381 lineNumber = token.lineNumber;
1382 lineStart = token.lineStart;
1383
1384 return token;
1385 }
1386
1387 function peek() {
1388 var pos, line, start;
1389
1390 pos = index;
1391 line = lineNumber;
1392 start = lineStart;
1393 lookahead = (typeof extra.tokens !== 'undefined') ? collectToken() : advance();
1394 index = pos;
1395 lineNumber = line;
1396 lineStart = start;
1397 }
1398
1399 function Position(line, column) {
1400 this.line = line;
1401 this.column = column;
1402 }
1403
1404 function SourceLocation(startLine, startColumn, line, column) {
1405 this.start = new Position(startLine, startColumn);
1406 this.end = new Position(line, column);
1407 }
1408
1409 SyntaxTreeDelegate = {
1410
1411 name: 'SyntaxTree',
1412
1413 processComment: function (node) {
1414 var lastChild, trailingComments;
1415
1416 if (node.type === Syntax.Program) {
1417 if (node.body.length > 0) {
1418 return;
1419 }
1420 }
1421
1422 if (extra.trailingComments.length > 0) {
1423 if (extra.trailingComments[0].range[0] >= node.range[1]) {
1424 trailingComments = extra.trailingComments;
1425 extra.trailingComments = [];
1426 } else {
1427 extra.trailingComments.length = 0;
1428 }
1429 } else {
1430 if (extra.bottomRightStack.length > 0 &&
1431 extra.bottomRightStack[extra.bottomRightStack.length - 1].trailingComments &&
1432 extra.bottomRightStack[extra.bottomRightStack.length - 1].trailingComments[0].range[0] >= node.range[1]) {
1433 trailingComments = extra.bottomRightStack[extra.bottomRightStack.length - 1].trailingComments;
1434 delete extra.bottomRightStack[extra.bottomRightStack.length - 1].trailingComments;
1435 }
1436 }
1437
1438 // Eating the stack.
1439 while (extra.bottomRightStack.length > 0 && extra.bottomRightStack[extra.bottomRightStack.length - 1].range[0] >= node.range[0]) {
1440 lastChild = extra.bottomRightStack.pop();
1441 }
1442
1443 if (lastChild) {
1444 if (lastChild.leadingComments && lastChild.leadingComments[lastChild.leadingComments.length - 1].range[1] <= node.range[0]) {
1445 node.leadingComments = lastChild.leadingComments;
1446 delete lastChild.leadingComments;
1447 }
1448 } else if (extra.leadingComments.length > 0 && extra.leadingComments[extra.leadingComments.length - 1].range[1] <= node.range[0]) {
1449 node.leadingComments = extra.leadingComments;
1450 extra.leadingComments = [];
1451 }
1452
1453
1454 if (trailingComments) {
1455 node.trailingComments = trailingComments;
1456 }
1457
1458 extra.bottomRightStack.push(node);
1459 },
1460
1461 markEnd: function (node, startToken) {
1462 if (extra.range) {
1463 node.range = [startToken.start, index];
1464 }
1465 if (extra.loc) {
1466 node.loc = new SourceLocation(
1467 startToken.startLineNumber === undefined ? startToken.lineNumber : startToken.startLineNumber,
1468 startToken.start - (startToken.startLineStart === undefined ? startToken.lineStart : startToken.startLineStart),
1469 lineNumber,
1470 index - lineStart
1471 );
1472 this.postProcess(node);
1473 }
1474
1475 if (extra.attachComment) {
1476 this.processComment(node);
1477 }
1478 return node;
1479 },
1480
1481 postProcess: function (node) {
1482 if (extra.source) {
1483 node.loc.source = extra.source;
1484 }
1485 return node;
1486 },
1487
1488 createArrayExpression: function (elements) {
1489 return {
1490 type: Syntax.ArrayExpression,
1491 elements: elements
1492 };
1493 },
1494
1495 createAssignmentExpression: function (operator, left, right) {
1496 return {
1497 type: Syntax.AssignmentExpression,
1498 operator: operator,
1499 left: left,
1500 right: right
1501 };
1502 },
1503
1504 createBinaryExpression: function (operator, left, right) {
1505 var type = (operator === '||' || operator === '&&') ? Syntax.LogicalExpression :
1506 Syntax.BinaryExpression;
1507 return {
1508 type: type,
1509 operator: operator,
1510 left: left,
1511 right: right
1512 };
1513 },
1514
1515 createBlockStatement: function (body) {
1516 return {
1517 type: Syntax.BlockStatement,
1518 body: body
1519 };
1520 },
1521
1522 createBreakStatement: function (label) {
1523 return {
1524 type: Syntax.BreakStatement,
1525 label: label
1526 };
1527 },
1528
1529 createCallExpression: function (callee, args) {
1530 return {
1531 type: Syntax.CallExpression,
1532 callee: callee,
1533 'arguments': args
1534 };
1535 },
1536
1537 createCatchClause: function (param, body) {
1538 return {
1539 type: Syntax.CatchClause,
1540 param: param,
1541 body: body
1542 };
1543 },
1544
1545 createConditionalExpression: function (test, consequent, alternate) {
1546 return {
1547 type: Syntax.ConditionalExpression,
1548 test: test,
1549 consequent: consequent,
1550 alternate: alternate
1551 };
1552 },
1553
1554 createContinueStatement: function (label) {
1555 return {
1556 type: Syntax.ContinueStatement,
1557 label: label
1558 };
1559 },
1560
1561 createDebuggerStatement: function () {
1562 return {
1563 type: Syntax.DebuggerStatement
1564 };
1565 },
1566
1567 createDoWhileStatement: function (body, test) {
1568 return {
1569 type: Syntax.DoWhileStatement,
1570 body: body,
1571 test: test
1572 };
1573 },
1574
1575 createEmptyStatement: function () {
1576 return {
1577 type: Syntax.EmptyStatement
1578 };
1579 },
1580
1581 createExpressionStatement: function (expression) {
1582 return {
1583 type: Syntax.ExpressionStatement,
1584 expression: expression
1585 };
1586 },
1587
1588 createForStatement: function (init, test, update, body) {
1589 return {
1590 type: Syntax.ForStatement,
1591 init: init,
1592 test: test,
1593 update: update,
1594 body: body
1595 };
1596 },
1597
1598 createForInStatement: function (left, right, body) {
1599 return {
1600 type: Syntax.ForInStatement,
1601 left: left,
1602 right: right,
1603 body: body,
1604 each: false
1605 };
1606 },
1607
1608 createFunctionDeclaration: function (id, params, defaults, body) {
1609 return {
1610 type: Syntax.FunctionDeclaration,
1611 id: id,
1612 params: params,
1613 defaults: defaults,
1614 body: body,
1615 rest: null,
1616 generator: false,
1617 expression: false
1618 };
1619 },
1620
1621 createFunctionExpression: function (id, params, defaults, body) {
1622 return {
1623 type: Syntax.FunctionExpression,
1624 id: id,
1625 params: params,
1626 defaults: defaults,
1627 body: body,
1628 rest: null,
1629 generator: false,
1630 expression: false
1631 };
1632 },
1633
1634 createIdentifier: function (name) {
1635 return {
1636 type: Syntax.Identifier,
1637 name: name
1638 };
1639 },
1640
1641 createIfStatement: function (test, consequent, alternate) {
1642 return {
1643 type: Syntax.IfStatement,
1644 test: test,
1645 consequent: consequent,
1646 alternate: alternate
1647 };
1648 },
1649
1650 createLabeledStatement: function (label, body) {
1651 return {
1652 type: Syntax.LabeledStatement,
1653 label: label,
1654 body: body
1655 };
1656 },
1657
1658 createLiteral: function (token) {
1659 return {
1660 type: Syntax.Literal,
1661 value: token.value,
1662 raw: source.slice(token.start, token.end)
1663 };
1664 },
1665
1666 createMemberExpression: function (accessor, object, property) {
1667 return {
1668 type: Syntax.MemberExpression,
1669 computed: accessor === '[',
1670 object: object,
1671 property: property
1672 };
1673 },
1674
1675 createNewExpression: function (callee, args) {
1676 return {
1677 type: Syntax.NewExpression,
1678 callee: callee,
1679 'arguments': args
1680 };
1681 },
1682
1683 createObjectExpression: function (properties) {
1684 return {
1685 type: Syntax.ObjectExpression,
1686 properties: properties
1687 };
1688 },
1689
1690 createPostfixExpression: function (operator, argument) {
1691 return {
1692 type: Syntax.UpdateExpression,
1693 operator: operator,
1694 argument: argument,
1695 prefix: false
1696 };
1697 },
1698
1699 createProgram: function (body) {
1700 return {
1701 type: Syntax.Program,
1702 body: body
1703 };
1704 },
1705
1706 createProperty: function (kind, key, value) {
1707 return {
1708 type: Syntax.Property,
1709 key: key,
1710 value: value,
1711 kind: kind
1712 };
1713 },
1714
1715 createReturnStatement: function (argument) {
1716 return {
1717 type: Syntax.ReturnStatement,
1718 argument: argument
1719 };
1720 },
1721
1722 createSequenceExpression: function (expressions) {
1723 return {
1724 type: Syntax.SequenceExpression,
1725 expressions: expressions
1726 };
1727 },
1728
1729 createSwitchCase: function (test, consequent) {
1730 return {
1731 type: Syntax.SwitchCase,
1732 test: test,
1733 consequent: consequent
1734 };
1735 },
1736
1737 createSwitchStatement: function (discriminant, cases) {
1738 return {
1739 type: Syntax.SwitchStatement,
1740 discriminant: discriminant,
1741 cases: cases
1742 };
1743 },
1744
1745 createThisExpression: function () {
1746 return {
1747 type: Syntax.ThisExpression
1748 };
1749 },
1750
1751 createThrowStatement: function (argument) {
1752 return {
1753 type: Syntax.ThrowStatement,
1754 argument: argument
1755 };
1756 },
1757
1758 createTryStatement: function (block, guardedHandlers, handlers, finalizer) {
1759 return {
1760 type: Syntax.TryStatement,
1761 block: block,
1762 guardedHandlers: guardedHandlers,
1763 handlers: handlers,
1764 finalizer: finalizer
1765 };
1766 },
1767
1768 createUnaryExpression: function (operator, argument) {
1769 if (operator === '++' || operator === '--') {
1770 return {
1771 type: Syntax.UpdateExpression,
1772 operator: operator,
1773 argument: argument,
1774 prefix: true
1775 };
1776 }
1777 return {
1778 type: Syntax.UnaryExpression,
1779 operator: operator,
1780 argument: argument,
1781 prefix: true
1782 };
1783 },
1784
1785 createVariableDeclaration: function (declarations, kind) {
1786 return {
1787 type: Syntax.VariableDeclaration,
1788 declarations: declarations,
1789 kind: kind
1790 };
1791 },
1792
1793 createVariableDeclarator: function (id, init) {
1794 return {
1795 type: Syntax.VariableDeclarator,
1796 id: id,
1797 init: init
1798 };
1799 },
1800
1801 createWhileStatement: function (test, body) {
1802 return {
1803 type: Syntax.WhileStatement,
1804 test: test,
1805 body: body
1806 };
1807 },
1808
1809 createWithStatement: function (object, body) {
1810 return {
1811 type: Syntax.WithStatement,
1812 object: object,
1813 body: body
1814 };
1815 }
1816 };
1817
1818 // Return true if there is a line terminator before the next token.
1819
1820 function peekLineTerminator() {
1821 var pos, line, start, found;
1822
1823 pos = index;
1824 line = lineNumber;
1825 start = lineStart;
1826 skipComment();
1827 found = lineNumber !== line;
1828 index = pos;
1829 lineNumber = line;
1830 lineStart = start;
1831
1832 return found;
1833 }
1834
1835 // Throw an exception
1836
1837 function throwError(token, messageFormat) {
1838 var error,
1839 args = Array.prototype.slice.call(arguments, 2),
1840 msg = messageFormat.replace(
1841 /%(\d)/g,
1842 function (whole, index) {
1843 assert(index < args.length, 'Message reference must be in range');
1844 return args[index];
1845 }
1846 );
1847
1848 if (typeof token.lineNumber === 'number') {
1849 error = new Error('Line ' + token.lineNumber + ': ' + msg);
1850 error.index = token.start;
1851 error.lineNumber = token.lineNumber;
1852 error.column = token.start - lineStart + 1;
1853 } else {
1854 error = new Error('Line ' + lineNumber + ': ' + msg);
1855 error.index = index;
1856 error.lineNumber = lineNumber;
1857 error.column = index - lineStart + 1;
1858 }
1859
1860 error.description = msg;
1861 throw error;
1862 }
1863
1864 function throwErrorTolerant() {
1865 try {
1866 throwError.apply(null, arguments);
1867 } catch (e) {
1868 if (extra.errors) {
1869 extra.errors.push(e);
1870 } else {
1871 throw e;
1872 }
1873 }
1874 }
1875
1876
1877 // Throw an exception because of the token.
1878
1879 function throwUnexpected(token) {
1880 if (token.type === Token.EOF) {
1881 throwError(token, Messages.UnexpectedEOS);
1882 }
1883
1884 if (token.type === Token.NumericLiteral) {
1885 throwError(token, Messages.UnexpectedNumber);
1886 }
1887
1888 if (token.type === Token.StringLiteral) {
1889 throwError(token, Messages.UnexpectedString);
1890 }
1891
1892 if (token.type === Token.Identifier) {
1893 throwError(token, Messages.UnexpectedIdentifier);
1894 }
1895
1896 if (token.type === Token.Keyword) {
1897 if (isFutureReservedWord(token.value)) {
1898 throwError(token, Messages.UnexpectedReserved);
1899 } else if (strict && isStrictModeReservedWord(token.value)) {
1900 throwErrorTolerant(token, Messages.StrictReservedWord);
1901 return;
1902 }
1903 throwError(token, Messages.UnexpectedToken, token.value);
1904 }
1905
1906 // BooleanLiteral, NullLiteral, or Punctuator.
1907 throwError(token, Messages.UnexpectedToken, token.value);
1908 }
1909
1910 // Expect the next token to match the specified punctuator.
1911 // If not, an exception will be thrown.
1912
1913 function expect(value) {
1914 var token = lex();
1915 if (token.type !== Token.Punctuator || token.value !== value) {
1916 throwUnexpected(token);
1917 }
1918 }
1919
1920 // Expect the next token to match the specified keyword.
1921 // If not, an exception will be thrown.
1922
1923 function expectKeyword(keyword) {
1924 var token = lex();
1925 if (token.type !== Token.Keyword || token.value !== keyword) {
1926 throwUnexpected(token);
1927 }
1928 }
1929
1930 // Return true if the next token matches the specified punctuator.
1931
1932 function match(value) {
1933 return lookahead.type === Token.Punctuator && lookahead.value === value;
1934 }
1935
1936 // Return true if the next token matches the specified keyword
1937
1938 function matchKeyword(keyword) {
1939 return lookahead.type === Token.Keyword && lookahead.value === keyword;
1940 }
1941
1942 // Return true if the next token is an assignment operator
1943
1944 function matchAssign() {
1945 var op;
1946
1947 if (lookahead.type !== Token.Punctuator) {
1948 return false;
1949 }
1950 op = lookahead.value;
1951 return op === '=' ||
1952 op === '*=' ||
1953 op === '/=' ||
1954 op === '%=' ||
1955 op === '+=' ||
1956 op === '-=' ||
1957 op === '<<=' ||
1958 op === '>>=' ||
1959 op === '>>>=' ||
1960 op === '&=' ||
1961 op === '^=' ||
1962 op === '|=';
1963 }
1964
1965 function consumeSemicolon() {
1966 var line, oldIndex = index, oldLineNumber = lineNumber,
1967 oldLineStart = lineStart, oldLookahead = lookahead;
1968
1969 // Catch the very common case first: immediately a semicolon (U+003B).
1970 if (source.charCodeAt(index) === 0x3B || match(';')) {
1971 lex();
1972 return;
1973 }
1974
1975 line = lineNumber;
1976 skipComment();
1977 if (lineNumber !== line) {
1978 index = oldIndex;
1979 lineNumber = oldLineNumber;
1980 lineStart = oldLineStart;
1981 lookahead = oldLookahead;
1982 return;
1983 }
1984
1985 if (lookahead.type !== Token.EOF && !match('}')) {
1986 throwUnexpected(lookahead);
1987 }
1988 }
1989
1990 // Return true if provided expression is LeftHandSideExpression
1991
1992 function isLeftHandSide(expr) {
1993 return expr.type === Syntax.Identifier || expr.type === Syntax.MemberExpression;
1994 }
1995
1996 // 11.1.4 Array Initialiser
1997
1998 function parseArrayInitialiser() {
1999 var elements = [], startToken;
2000
2001 startToken = lookahead;
2002 expect('[');
2003
2004 while (!match(']')) {
2005 if (match(',')) {
2006 lex();
2007 elements.push(null);
2008 } else {
2009 elements.push(parseAssignmentExpression());
2010
2011 if (!match(']')) {
2012 expect(',');
2013 }
2014 }
2015 }
2016
2017 lex();
2018
2019 return delegate.markEnd(delegate.createArrayExpression(elements), startToken);
2020 }
2021
2022 // 11.1.5 Object Initialiser
2023
2024 function parsePropertyFunction(param, first) {
2025 var previousStrict, body, startToken;
2026
2027 previousStrict = strict;
2028 startToken = lookahead;
2029 body = parseFunctionSourceElements();
2030 if (first && strict && isRestrictedWord(param[0].name)) {
2031 throwErrorTolerant(first, Messages.StrictParamName);
2032 }
2033 strict = previousStrict;
2034 return delegate.markEnd(delegate.createFunctionExpression(null, param, [], body), startToken);
2035 }
2036
2037 function parseObjectPropertyKey() {
2038 var token, startToken;
2039
2040 startToken = lookahead;
2041 token = lex();
2042
2043 // Note: This function is called only from parseObjectProperty(), where
2044 // EOF and Punctuator tokens are already filtered out.
2045
2046 if (token.type === Token.StringLiteral || token.type === Token.NumericLiteral) {
2047 if (strict && token.octal) {
2048 throwErrorTolerant(token, Messages.StrictOctalLiteral);
2049 }
2050 return delegate.markEnd(delegate.createLiteral(token), startToken);
2051 }
2052
2053 return delegate.markEnd(delegate.createIdentifier(token.value), startToken);
2054 }
2055
2056 function parseObjectProperty() {
2057 var token, key, id, value, param, startToken;
2058
2059 token = lookahead;
2060 startToken = lookahead;
2061
2062 if (token.type === Token.Identifier) {
2063
2064 id = parseObjectPropertyKey();
2065
2066 // Property Assignment: Getter and Setter.
2067
2068 if (token.value === 'get' && !match(':')) {
2069 key = parseObjectPropertyKey();
2070 expect('(');
2071 expect(')');
2072 value = parsePropertyFunction([]);
2073 return delegate.markEnd(delegate.createProperty('get', key, value), startToken);
2074 }
2075 if (token.value === 'set' && !match(':')) {
2076 key = parseObjectPropertyKey();
2077 expect('(');
2078 token = lookahead;
2079 if (token.type !== Token.Identifier) {
2080 expect(')');
2081 throwErrorTolerant(token, Messages.UnexpectedToken, token.value);
2082 value = parsePropertyFunction([]);
2083 } else {
2084 param = [ parseVariableIdentifier() ];
2085 expect(')');
2086 value = parsePropertyFunction(param, token);
2087 }
2088 return delegate.markEnd(delegate.createProperty('set', key, value), startToken);
2089 }
2090 expect(':');
2091 value = parseAssignmentExpression();
2092 return delegate.markEnd(delegate.createProperty('init', id, value), startToken);
2093 }
2094 if (token.type === Token.EOF || token.type === Token.Punctuator) {
2095 throwUnexpected(token);
2096 } else {
2097 key = parseObjectPropertyKey();
2098 expect(':');
2099 value = parseAssignmentExpression();
2100 return delegate.markEnd(delegate.createProperty('init', key, value), startToken);
2101 }
2102 }
2103
2104 function parseObjectInitialiser() {
2105 var properties = [], property, name, key, kind, map = {}, toString = String, startToken;
2106
2107 startToken = lookahead;
2108
2109 expect('{');
2110
2111 while (!match('}')) {
2112 property = parseObjectProperty();
2113
2114 if (property.key.type === Syntax.Identifier) {
2115 name = property.key.name;
2116 } else {
2117 name = toString(property.key.value);
2118 }
2119 kind = (property.kind === 'init') ? PropertyKind.Data : (property.kind === 'get') ? PropertyKind.Get : PropertyKind.Set;
2120
2121 key = '$' + name;
2122 if (Object.prototype.hasOwnProperty.call(map, key)) {
2123 if (map[key] === PropertyKind.Data) {
2124 if (strict && kind === PropertyKind.Data) {
2125 throwErrorTolerant({}, Messages.StrictDuplicateProperty);
2126 } else if (kind !== PropertyKind.Data) {
2127 throwErrorTolerant({}, Messages.AccessorDataProperty);
2128 }
2129 } else {
2130 if (kind === PropertyKind.Data) {
2131 throwErrorTolerant({}, Messages.AccessorDataProperty);
2132 } else if (map[key] & kind) {
2133 throwErrorTolerant({}, Messages.AccessorGetSet);
2134 }
2135 }
2136 map[key] |= kind;
2137 } else {
2138 map[key] = kind;
2139 }
2140
2141 properties.push(property);
2142
2143 if (!match('}')) {
2144 expect(',');
2145 }
2146 }
2147
2148 expect('}');
2149
2150 return delegate.markEnd(delegate.createObjectExpression(properties), startToken);
2151 }
2152
2153 // 11.1.6 The Grouping Operator
2154
2155 function parseGroupExpression() {
2156 var expr;
2157
2158 expect('(');
2159
2160 expr = parseExpression();
2161
2162 expect(')');
2163
2164 return expr;
2165 }
2166
2167
2168 // 11.1 Primary Expressions
2169
2170 function parsePrimaryExpression() {
2171 var type, token, expr, startToken;
2172
2173 if (match('(')) {
2174 return parseGroupExpression();
2175 }
2176
2177 if (match('[')) {
2178 return parseArrayInitialiser();
2179 }
2180
2181 if (match('{')) {
2182 return parseObjectInitialiser();
2183 }
2184
2185 type = lookahead.type;
2186 startToken = lookahead;
2187
2188 if (type === Token.Identifier) {
2189 expr = delegate.createIdentifier(lex().value);
2190 } else if (type === Token.StringLiteral || type === Token.NumericLiteral) {
2191 if (strict && lookahead.octal) {
2192 throwErrorTolerant(lookahead, Messages.StrictOctalLiteral);
2193 }
2194 expr = delegate.createLiteral(lex());
2195 } else if (type === Token.Keyword) {
2196 if (matchKeyword('function')) {
2197 return parseFunctionExpression();
2198 }
2199 if (matchKeyword('this')) {
2200 lex();
2201 expr = delegate.createThisExpression();
2202 } else {
2203 throwUnexpected(lex());
2204 }
2205 } else if (type === Token.BooleanLiteral) {
2206 token = lex();
2207 token.value = (token.value === 'true');
2208 expr = delegate.createLiteral(token);
2209 } else if (type === Token.NullLiteral) {
2210 token = lex();
2211 token.value = null;
2212 expr = delegate.createLiteral(token);
2213 } else if (match('/') || match('/=')) {
2214 if (typeof extra.tokens !== 'undefined') {
2215 expr = delegate.createLiteral(collectRegex());
2216 } else {
2217 expr = delegate.createLiteral(scanRegExp());
2218 }
2219 peek();
2220 } else {
2221 throwUnexpected(lex());
2222 }
2223
2224 return delegate.markEnd(expr, startToken);
2225 }
2226
2227 // 11.2 Left-Hand-Side Expressions
2228
2229 function parseArguments() {
2230 var args = [];
2231
2232 expect('(');
2233
2234 if (!match(')')) {
2235 while (index < length) {
2236 args.push(parseAssignmentExpression());
2237 if (match(')')) {
2238 break;
2239 }
2240 expect(',');
2241 }
2242 }
2243
2244 expect(')');
2245
2246 return args;
2247 }
2248
2249 function parseNonComputedProperty() {
2250 var token, startToken;
2251
2252 startToken = lookahead;
2253 token = lex();
2254
2255 if (!isIdentifierName(token)) {
2256 throwUnexpected(token);
2257 }
2258
2259 return delegate.markEnd(delegate.createIdentifier(token.value), startToken);
2260 }
2261
2262 function parseNonComputedMember() {
2263 expect('.');
2264
2265 return parseNonComputedProperty();
2266 }
2267
2268 function parseComputedMember() {
2269 var expr;
2270
2271 expect('[');
2272
2273 expr = parseExpression();
2274
2275 expect(']');
2276
2277 return expr;
2278 }
2279
2280 function parseNewExpression() {
2281 var callee, args, startToken;
2282
2283 startToken = lookahead;
2284 expectKeyword('new');
2285 callee = parseLeftHandSideExpression();
2286 args = match('(') ? parseArguments() : [];
2287
2288 return delegate.markEnd(delegate.createNewExpression(callee, args), startToken);
2289 }
2290
2291 function parseLeftHandSideExpressionAllowCall() {
2292 var expr, args, property, startToken, previousAllowIn = state.allowIn;
2293
2294 startToken = lookahead;
2295 state.allowIn = true;
2296 expr = matchKeyword('new') ? parseNewExpression() : parsePrimaryExpression();
2297
2298 for (;;) {
2299 if (match('.')) {
2300 property = parseNonComputedMember();
2301 expr = delegate.createMemberExpression('.', expr, property);
2302 } else if (match('(')) {
2303 args = parseArguments();
2304 expr = delegate.createCallExpression(expr, args);
2305 } else if (match('[')) {
2306 property = parseComputedMember();
2307 expr = delegate.createMemberExpression('[', expr, property);
2308 } else {
2309 break;
2310 }
2311 delegate.markEnd(expr, startToken);
2312 }
2313 state.allowIn = previousAllowIn;
2314
2315 return expr;
2316 }
2317
2318 function parseLeftHandSideExpression() {
2319 var expr, property, startToken;
2320 assert(state.allowIn, 'callee of new expression always allow in keyword.');
2321
2322 startToken = lookahead;
2323
2324 expr = matchKeyword('new') ? parseNewExpression() : parsePrimaryExpression();
2325
2326 while (match('.') || match('[')) {
2327 if (match('[')) {
2328 property = parseComputedMember();
2329 expr = delegate.createMemberExpression('[', expr, property);
2330 } else {
2331 property = parseNonComputedMember();
2332 expr = delegate.createMemberExpression('.', expr, property);
2333 }
2334 delegate.markEnd(expr, startToken);
2335 }
2336 return expr;
2337 }
2338
2339 // 11.3 Postfix Expressions
2340
2341 function parsePostfixExpression() {
2342 var expr, token, startToken = lookahead;
2343
2344 expr = parseLeftHandSideExpressionAllowCall();
2345
2346 if (lookahead.type === Token.Punctuator) {
2347 if ((match('++') || match('--')) && !peekLineTerminator()) {
2348 // 11.3.1, 11.3.2
2349 if (strict && expr.type === Syntax.Identifier && isRestrictedWord(expr.name)) {
2350 throwErrorTolerant({}, Messages.StrictLHSPostfix);
2351 }
2352
2353 if (!isLeftHandSide(expr)) {
2354 throwErrorTolerant({}, Messages.InvalidLHSInAssignment);
2355 }
2356
2357 token = lex();
2358 expr = delegate.markEnd(delegate.createPostfixExpression(token.value, expr), startToken);
2359 }
2360 }
2361
2362 return expr;
2363 }
2364
2365 // 11.4 Unary Operators
2366
2367 function parseUnaryExpression() {
2368 var token, expr, startToken;
2369
2370 if (lookahead.type !== Token.Punctuator && lookahead.type !== Token.Keyword) {
2371 expr = parsePostfixExpression();
2372 } else if (match('++') || match('--')) {
2373 startToken = lookahead;
2374 token = lex();
2375 expr = parseUnaryExpression();
2376 // 11.4.4, 11.4.5
2377 if (strict && expr.type === Syntax.Identifier && isRestrictedWord(expr.name)) {
2378 throwErrorTolerant({}, Messages.StrictLHSPrefix);
2379 }
2380
2381 if (!isLeftHandSide(expr)) {
2382 throwErrorTolerant({}, Messages.InvalidLHSInAssignment);
2383 }
2384
2385 expr = delegate.createUnaryExpression(token.value, expr);
2386 expr = delegate.markEnd(expr, startToken);
2387 } else if (match('+') || match('-') || match('~') || match('!')) {
2388 startToken = lookahead;
2389 token = lex();
2390 expr = parseUnaryExpression();
2391 expr = delegate.createUnaryExpression(token.value, expr);
2392 expr = delegate.markEnd(expr, startToken);
2393 } else if (matchKeyword('delete') || matchKeyword('void') || matchKeyword('typeof')) {
2394 startToken = lookahead;
2395 token = lex();
2396 expr = parseUnaryExpression();
2397 expr = delegate.createUnaryExpression(token.value, expr);
2398 expr = delegate.markEnd(expr, startToken);
2399 if (strict && expr.operator === 'delete' && expr.argument.type === Syntax.Identifier) {
2400 throwErrorTolerant({}, Messages.StrictDelete);
2401 }
2402 } else {
2403 expr = parsePostfixExpression();
2404 }
2405
2406 return expr;
2407 }
2408
2409 function binaryPrecedence(token, allowIn) {
2410 var prec = 0;
2411
2412 if (token.type !== Token.Punctuator && token.type !== Token.Keyword) {
2413 return 0;
2414 }
2415
2416 switch (token.value) {
2417 case '||':
2418 prec = 1;
2419 break;
2420
2421 case '&&':
2422 prec = 2;
2423 break;
2424
2425 case '|':
2426 prec = 3;
2427 break;
2428
2429 case '^':
2430 prec = 4;
2431 break;
2432
2433 case '&':
2434 prec = 5;
2435 break;
2436
2437 case '==':
2438 case '!=':
2439 case '===':
2440 case '!==':
2441 prec = 6;
2442 break;
2443
2444 case '<':
2445 case '>':
2446 case '<=':
2447 case '>=':
2448 case 'instanceof':
2449 prec = 7;
2450 break;
2451
2452 case 'in':
2453 prec = allowIn ? 7 : 0;
2454 break;
2455
2456 case '<<':
2457 case '>>':
2458 case '>>>':
2459 prec = 8;
2460 break;
2461
2462 case '+':
2463 case '-':
2464 prec = 9;
2465 break;
2466
2467 case '*':
2468 case '/':
2469 case '%':
2470 prec = 11;
2471 break;
2472
2473 default:
2474 break;
2475 }
2476
2477 return prec;
2478 }
2479
2480 // 11.5 Multiplicative Operators
2481 // 11.6 Additive Operators
2482 // 11.7 Bitwise Shift Operators
2483 // 11.8 Relational Operators
2484 // 11.9 Equality Operators
2485 // 11.10 Binary Bitwise Operators
2486 // 11.11 Binary Logical Operators
2487
2488 function parseBinaryExpression() {
2489 var marker, markers, expr, token, prec, stack, right, operator, left, i;
2490
2491 marker = lookahead;
2492 left = parseUnaryExpression();
2493
2494 token = lookahead;
2495 prec = binaryPrecedence(token, state.allowIn);
2496 if (prec === 0) {
2497 return left;
2498 }
2499 token.prec = prec;
2500 lex();
2501
2502 markers = [marker, lookahead];
2503 right = parseUnaryExpression();
2504
2505 stack = [left, token, right];
2506
2507 while ((prec = binaryPrecedence(lookahead, state.allowIn)) > 0) {
2508
2509 // Reduce: make a binary expression from the three topmost entries.
2510 while ((stack.length > 2) && (prec <= stack[stack.length - 2].prec)) {
2511 right = stack.pop();
2512 operator = stack.pop().value;
2513 left = stack.pop();
2514 expr = delegate.createBinaryExpression(operator, left, right);
2515 markers.pop();
2516 marker = markers[markers.length - 1];
2517 delegate.markEnd(expr, marker);
2518 stack.push(expr);
2519 }
2520
2521 // Shift.
2522 token = lex();
2523 token.prec = prec;
2524 stack.push(token);
2525 markers.push(lookahead);
2526 expr = parseUnaryExpression();
2527 stack.push(expr);
2528 }
2529
2530 // Final reduce to clean-up the stack.
2531 i = stack.length - 1;
2532 expr = stack[i];
2533 markers.pop();
2534 while (i > 1) {
2535 expr = delegate.createBinaryExpression(stack[i - 1].value, stack[i - 2], expr);
2536 i -= 2;
2537 marker = markers.pop();
2538 delegate.markEnd(expr, marker);
2539 }
2540
2541 return expr;
2542 }
2543
2544
2545 // 11.12 Conditional Operator
2546
2547 function parseConditionalExpression() {
2548 var expr, previousAllowIn, consequent, alternate, startToken;
2549
2550 startToken = lookahead;
2551
2552 expr = parseBinaryExpression();
2553
2554 if (match('?')) {
2555 lex();
2556 previousAllowIn = state.allowIn;
2557 state.allowIn = true;
2558 consequent = parseAssignmentExpression();
2559 state.allowIn = previousAllowIn;
2560 expect(':');
2561 alternate = parseAssignmentExpression();
2562
2563 expr = delegate.createConditionalExpression(expr, consequent, alternate);
2564 delegate.markEnd(expr, startToken);
2565 }
2566
2567 return expr;
2568 }
2569
2570 // 11.13 Assignment Operators
2571
2572 function parseAssignmentExpression() {
2573 var token, left, right, node, startToken;
2574
2575 token = lookahead;
2576 startToken = lookahead;
2577
2578 node = left = parseConditionalExpression();
2579
2580 if (matchAssign()) {
2581 // LeftHandSideExpression
2582 if (!isLeftHandSide(left)) {
2583 throwErrorTolerant({}, Messages.InvalidLHSInAssignment);
2584 }
2585
2586 // 11.13.1
2587 if (strict && left.type === Syntax.Identifier && isRestrictedWord(left.name)) {
2588 throwErrorTolerant(token, Messages.StrictLHSAssignment);
2589 }
2590
2591 token = lex();
2592 right = parseAssignmentExpression();
2593 node = delegate.markEnd(delegate.createAssignmentExpression(token.value, left, right), startToken);
2594 }
2595
2596 return node;
2597 }
2598
2599 // 11.14 Comma Operator
2600
2601 function parseExpression() {
2602 var expr, startToken = lookahead;
2603
2604 expr = parseAssignmentExpression();
2605
2606 if (match(',')) {
2607 expr = delegate.createSequenceExpression([ expr ]);
2608
2609 while (index < length) {
2610 if (!match(',')) {
2611 break;
2612 }
2613 lex();
2614 expr.expressions.push(parseAssignmentExpression());
2615 }
2616
2617 delegate.markEnd(expr, startToken);
2618 }
2619
2620 return expr;
2621 }
2622
2623 // 12.1 Block
2624
2625 function parseStatementList() {
2626 var list = [],
2627 statement;
2628
2629 while (index < length) {
2630 if (match('}')) {
2631 break;
2632 }
2633 statement = parseSourceElement();
2634 if (typeof statement === 'undefined') {
2635 break;
2636 }
2637 list.push(statement);
2638 }
2639
2640 return list;
2641 }
2642
2643 function parseBlock() {
2644 var block, startToken;
2645
2646 startToken = lookahead;
2647 expect('{');
2648
2649 block = parseStatementList();
2650
2651 expect('}');
2652
2653 return delegate.markEnd(delegate.createBlockStatement(block), startToken);
2654 }
2655
2656 // 12.2 Variable Statement
2657
2658 function parseVariableIdentifier() {
2659 var token, startToken;
2660
2661 startToken = lookahead;
2662 token = lex();
2663
2664 if (token.type !== Token.Identifier) {
2665 throwUnexpected(token);
2666 }
2667
2668 return delegate.markEnd(delegate.createIdentifier(token.value), startToken);
2669 }
2670
2671 function parseVariableDeclaration(kind) {
2672 var init = null, id, startToken;
2673
2674 startToken = lookahead;
2675 id = parseVariableIdentifier();
2676
2677 // 12.2.1
2678 if (strict && isRestrictedWord(id.name)) {
2679 throwErrorTolerant({}, Messages.StrictVarName);
2680 }
2681
2682 if (kind === 'const') {
2683 expect('=');
2684 init = parseAssignmentExpression();
2685 } else if (match('=')) {
2686 lex();
2687 init = parseAssignmentExpression();
2688 }
2689
2690 return delegate.markEnd(delegate.createVariableDeclarator(id, init), startToken);
2691 }
2692
2693 function parseVariableDeclarationList(kind) {
2694 var list = [];
2695
2696 do {
2697 list.push(parseVariableDeclaration(kind));
2698 if (!match(',')) {
2699 break;
2700 }
2701 lex();
2702 } while (index < length);
2703
2704 return list;
2705 }
2706
2707 function parseVariableStatement() {
2708 var declarations;
2709
2710 expectKeyword('var');
2711
2712 declarations = parseVariableDeclarationList();
2713
2714 consumeSemicolon();
2715
2716 return delegate.createVariableDeclaration(declarations, 'var');
2717 }
2718
2719 // kind may be `const` or `let`
2720 // Both are experimental and not in the specification yet.
2721 // see http://wiki.ecmascript.org/doku.php?id=harmony:const
2722 // and http://wiki.ecmascript.org/doku.php?id=harmony:let
2723 function parseConstLetDeclaration(kind) {
2724 var declarations, startToken;
2725
2726 startToken = lookahead;
2727
2728 expectKeyword(kind);
2729
2730 declarations = parseVariableDeclarationList(kind);
2731
2732 consumeSemicolon();
2733
2734 return delegate.markEnd(delegate.createVariableDeclaration(declarations, kind), startToken);
2735 }
2736
2737 // 12.3 Empty Statement
2738
2739 function parseEmptyStatement() {
2740 expect(';');
2741 return delegate.createEmptyStatement();
2742 }
2743
2744 // 12.4 Expression Statement
2745
2746 function parseExpressionStatement() {
2747 var expr = parseExpression();
2748 consumeSemicolon();
2749 return delegate.createExpressionStatement(expr);
2750 }
2751
2752 // 12.5 If statement
2753
2754 function parseIfStatement() {
2755 var test, consequent, alternate;
2756
2757 expectKeyword('if');
2758
2759 expect('(');
2760
2761 test = parseExpression();
2762
2763 expect(')');
2764
2765 consequent = parseStatement();
2766
2767 if (matchKeyword('else')) {
2768 lex();
2769 alternate = parseStatement();
2770 } else {
2771 alternate = null;
2772 }
2773
2774 return delegate.createIfStatement(test, consequent, alternate);
2775 }
2776
2777 // 12.6 Iteration Statements
2778
2779 function parseDoWhileStatement() {
2780 var body, test, oldInIteration;
2781
2782 expectKeyword('do');
2783
2784 oldInIteration = state.inIteration;
2785 state.inIteration = true;
2786
2787 body = parseStatement();
2788
2789 state.inIteration = oldInIteration;
2790
2791 expectKeyword('while');
2792
2793 expect('(');
2794
2795 test = parseExpression();
2796
2797 expect(')');
2798
2799 if (match(';')) {
2800 lex();
2801 }
2802
2803 return delegate.createDoWhileStatement(body, test);
2804 }
2805
2806 function parseWhileStatement() {
2807 var test, body, oldInIteration;
2808
2809 expectKeyword('while');
2810
2811 expect('(');
2812
2813 test = parseExpression();
2814
2815 expect(')');
2816
2817 oldInIteration = state.inIteration;
2818 state.inIteration = true;
2819
2820 body = parseStatement();
2821
2822 state.inIteration = oldInIteration;
2823
2824 return delegate.createWhileStatement(test, body);
2825 }
2826
2827 function parseForVariableDeclaration() {
2828 var token, declarations, startToken;
2829
2830 startToken = lookahead;
2831 token = lex();
2832 declarations = parseVariableDeclarationList();
2833
2834 return delegate.markEnd(delegate.createVariableDeclaration(declarations, token.value), startToken);
2835 }
2836
2837 function parseForStatement() {
2838 var init, test, update, left, right, body, oldInIteration, previousAllowIn = state.allowIn;
2839
2840 init = test = update = null;
2841
2842 expectKeyword('for');
2843
2844 expect('(');
2845
2846 if (match(';')) {
2847 lex();
2848 } else {
2849 if (matchKeyword('var') || matchKeyword('let')) {
2850 state.allowIn = false;
2851 init = parseForVariableDeclaration();
2852 state.allowIn = previousAllowIn;
2853
2854 if (init.declarations.length === 1 && matchKeyword('in')) {
2855 lex();
2856 left = init;
2857 right = parseExpression();
2858 init = null;
2859 }
2860 } else {
2861 state.allowIn = false;
2862 init = parseExpression();
2863 state.allowIn = previousAllowIn;
2864
2865 if (matchKeyword('in')) {
2866 // LeftHandSideExpression
2867 if (!isLeftHandSide(init)) {
2868 throwErrorTolerant({}, Messages.InvalidLHSInForIn);
2869 }
2870
2871 lex();
2872 left = init;
2873 right = parseExpression();
2874 init = null;
2875 }
2876 }
2877
2878 if (typeof left === 'undefined') {
2879 expect(';');
2880 }
2881 }
2882
2883 if (typeof left === 'undefined') {
2884
2885 if (!match(';')) {
2886 test = parseExpression();
2887 }
2888 expect(';');
2889
2890 if (!match(')')) {
2891 update = parseExpression();
2892 }
2893 }
2894
2895 expect(')');
2896
2897 oldInIteration = state.inIteration;
2898 state.inIteration = true;
2899
2900 body = parseStatement();
2901
2902 state.inIteration = oldInIteration;
2903
2904 return (typeof left === 'undefined') ?
2905 delegate.createForStatement(init, test, update, body) :
2906 delegate.createForInStatement(left, right, body);
2907 }
2908
2909 // 12.7 The continue statement
2910
2911 function parseContinueStatement() {
2912 var label = null, key;
2913
2914 expectKeyword('continue');
2915
2916 // Optimize the most common form: 'continue;'.
2917 if (source.charCodeAt(index) === 0x3B) {
2918 lex();
2919
2920 if (!state.inIteration) {
2921 throwError({}, Messages.IllegalContinue);
2922 }
2923
2924 return delegate.createContinueStatement(null);
2925 }
2926
2927 if (peekLineTerminator()) {
2928 if (!state.inIteration) {
2929 throwError({}, Messages.IllegalContinue);
2930 }
2931
2932 return delegate.createContinueStatement(null);
2933 }
2934
2935 if (lookahead.type === Token.Identifier) {
2936 label = parseVariableIdentifier();
2937
2938 key = '$' + label.name;
2939 if (!Object.prototype.hasOwnProperty.call(state.labelSet, key)) {
2940 throwError({}, Messages.UnknownLabel, label.name);
2941 }
2942 }
2943
2944 consumeSemicolon();
2945
2946 if (label === null && !state.inIteration) {
2947 throwError({}, Messages.IllegalContinue);
2948 }
2949
2950 return delegate.createContinueStatement(label);
2951 }
2952
2953 // 12.8 The break statement
2954
2955 function parseBreakStatement() {
2956 var label = null, key;
2957
2958 expectKeyword('break');
2959
2960 // Catch the very common case first: immediately a semicolon (U+003B).
2961 if (source.charCodeAt(index) === 0x3B) {
2962 lex();
2963
2964 if (!(state.inIteration || state.inSwitch)) {
2965 throwError({}, Messages.IllegalBreak);
2966 }
2967
2968 return delegate.createBreakStatement(null);
2969 }
2970
2971 if (peekLineTerminator()) {
2972 if (!(state.inIteration || state.inSwitch)) {
2973 throwError({}, Messages.IllegalBreak);
2974 }
2975
2976 return delegate.createBreakStatement(null);
2977 }
2978
2979 if (lookahead.type === Token.Identifier) {
2980 label = parseVariableIdentifier();
2981
2982 key = '$' + label.name;
2983 if (!Object.prototype.hasOwnProperty.call(state.labelSet, key)) {
2984 throwError({}, Messages.UnknownLabel, label.name);
2985 }
2986 }
2987
2988 consumeSemicolon();
2989
2990 if (label === null && !(state.inIteration || state.inSwitch)) {
2991 throwError({}, Messages.IllegalBreak);
2992 }
2993
2994 return delegate.createBreakStatement(label);
2995 }
2996
2997 // 12.9 The return statement
2998
2999 function parseReturnStatement() {
3000 var argument = null;
3001
3002 expectKeyword('return');
3003
3004 if (!state.inFunctionBody) {
3005 throwErrorTolerant({}, Messages.IllegalReturn);
3006 }
3007
3008 // 'return' followed by a space and an identifier is very common.
3009 if (source.charCodeAt(index) === 0x20) {
3010 if (isIdentifierStart(source.charCodeAt(index + 1))) {
3011 argument = parseExpression();
3012 consumeSemicolon();
3013 return delegate.createReturnStatement(argument);
3014 }
3015 }
3016
3017 if (peekLineTerminator()) {
3018 return delegate.createReturnStatement(null);
3019 }
3020
3021 if (!match(';')) {
3022 if (!match('}') && lookahead.type !== Token.EOF) {
3023 argument = parseExpression();
3024 }
3025 }
3026
3027 consumeSemicolon();
3028
3029 return delegate.createReturnStatement(argument);
3030 }
3031
3032 // 12.10 The with statement
3033
3034 function parseWithStatement() {
3035 var object, body;
3036
3037 if (strict) {
3038 // TODO(ikarienator): Should we update the test cases instead?
3039 skipComment();
3040 throwErrorTolerant({}, Messages.StrictModeWith);
3041 }
3042
3043 expectKeyword('with');
3044
3045 expect('(');
3046
3047 object = parseExpression();
3048
3049 expect(')');
3050
3051 body = parseStatement();
3052
3053 return delegate.createWithStatement(object, body);
3054 }
3055
3056 // 12.10 The swith statement
3057
3058 function parseSwitchCase() {
3059 var test, consequent = [], statement, startToken;
3060
3061 startToken = lookahead;
3062 if (matchKeyword('default')) {
3063 lex();
3064 test = null;
3065 } else {
3066 expectKeyword('case');
3067 test = parseExpression();
3068 }
3069 expect(':');
3070
3071 while (index < length) {
3072 if (match('}') || matchKeyword('default') || matchKeyword('case')) {
3073 break;
3074 }
3075 statement = parseStatement();
3076 consequent.push(statement);
3077 }
3078
3079 return delegate.markEnd(delegate.createSwitchCase(test, consequent), startToken);
3080 }
3081
3082 function parseSwitchStatement() {
3083 var discriminant, cases, clause, oldInSwitch, defaultFound;
3084
3085 expectKeyword('switch');
3086
3087 expect('(');
3088
3089 discriminant = parseExpression();
3090
3091 expect(')');
3092
3093 expect('{');
3094
3095 cases = [];
3096
3097 if (match('}')) {
3098 lex();
3099 return delegate.createSwitchStatement(discriminant, cases);
3100 }
3101
3102 oldInSwitch = state.inSwitch;
3103 state.inSwitch = true;
3104 defaultFound = false;
3105
3106 while (index < length) {
3107 if (match('}')) {
3108 break;
3109 }
3110 clause = parseSwitchCase();
3111 if (clause.test === null) {
3112 if (defaultFound) {
3113 throwError({}, Messages.MultipleDefaultsInSwitch);
3114 }
3115 defaultFound = true;
3116 }
3117 cases.push(clause);
3118 }
3119
3120 state.inSwitch = oldInSwitch;
3121
3122 expect('}');
3123
3124 return delegate.createSwitchStatement(discriminant, cases);
3125 }
3126
3127 // 12.13 The throw statement
3128
3129 function parseThrowStatement() {
3130 var argument;
3131
3132 expectKeyword('throw');
3133
3134 if (peekLineTerminator()) {
3135 throwError({}, Messages.NewlineAfterThrow);
3136 }
3137
3138 argument = parseExpression();
3139
3140 consumeSemicolon();
3141
3142 return delegate.createThrowStatement(argument);
3143 }
3144
3145 // 12.14 The try statement
3146
3147 function parseCatchClause() {
3148 var param, body, startToken;
3149
3150 startToken = lookahead;
3151 expectKeyword('catch');
3152
3153 expect('(');
3154 if (match(')')) {
3155 throwUnexpected(lookahead);
3156 }
3157
3158 param = parseVariableIdentifier();
3159 // 12.14.1
3160 if (strict && isRestrictedWord(param.name)) {
3161 throwErrorTolerant({}, Messages.StrictCatchVariable);
3162 }
3163
3164 expect(')');
3165 body = parseBlock();
3166 return delegate.markEnd(delegate.createCatchClause(param, body), startToken);
3167 }
3168
3169 function parseTryStatement() {
3170 var block, handlers = [], finalizer = null;
3171
3172 expectKeyword('try');
3173
3174 block = parseBlock();
3175
3176 if (matchKeyword('catch')) {
3177 handlers.push(parseCatchClause());
3178 }
3179
3180 if (matchKeyword('finally')) {
3181 lex();
3182 finalizer = parseBlock();
3183 }
3184
3185 if (handlers.length === 0 && !finalizer) {
3186 throwError({}, Messages.NoCatchOrFinally);
3187 }
3188
3189 return delegate.createTryStatement(block, [], handlers, finalizer);
3190 }
3191
3192 // 12.15 The debugger statement
3193
3194 function parseDebuggerStatement() {
3195 expectKeyword('debugger');
3196
3197 consumeSemicolon();
3198
3199 return delegate.createDebuggerStatement();
3200 }
3201
3202 // 12 Statements
3203
3204 function parseStatement() {
3205 var type = lookahead.type,
3206 expr,
3207 labeledBody,
3208 key,
3209 startToken;
3210
3211 if (type === Token.EOF) {
3212 throwUnexpected(lookahead);
3213 }
3214
3215 if (type === Token.Punctuator && lookahead.value === '{') {
3216 return parseBlock();
3217 }
3218
3219 startToken = lookahead;
3220
3221 if (type === Token.Punctuator) {
3222 switch (lookahead.value) {
3223 case ';':
3224 return delegate.markEnd(parseEmptyStatement(), startToken);
3225 case '(':
3226 return delegate.markEnd(parseExpressionStatement(), startToken);
3227 default:
3228 break;
3229 }
3230 }
3231
3232 if (type === Token.Keyword) {
3233 switch (lookahead.value) {
3234 case 'break':
3235 return delegate.markEnd(parseBreakStatement(), startToken);
3236 case 'continue':
3237 return delegate.markEnd(parseContinueStatement(), startToken);
3238 case 'debugger':
3239 return delegate.markEnd(parseDebuggerStatement(), startToken);
3240 case 'do':
3241 return delegate.markEnd(parseDoWhileStatement(), startToken);
3242 case 'for':
3243 return delegate.markEnd(parseForStatement(), startToken);
3244 case 'function':
3245 return delegate.markEnd(parseFunctionDeclaration(), startToken);
3246 case 'if':
3247 return delegate.markEnd(parseIfStatement(), startToken);
3248 case 'return':
3249 return delegate.markEnd(parseReturnStatement(), startToken);
3250 case 'switch':
3251 return delegate.markEnd(parseSwitchStatement(), startToken);
3252 case 'throw':
3253 return delegate.markEnd(parseThrowStatement(), startToken);
3254 case 'try':
3255 return delegate.markEnd(parseTryStatement(), startToken);
3256 case 'var':
3257 return delegate.markEnd(parseVariableStatement(), startToken);
3258 case 'while':
3259 return delegate.markEnd(parseWhileStatement(), startToken);
3260 case 'with':
3261 return delegate.markEnd(parseWithStatement(), startToken);
3262 default:
3263 break;
3264 }
3265 }
3266
3267 expr = parseExpression();
3268
3269 // 12.12 Labelled Statements
3270 if ((expr.type === Syntax.Identifier) && match(':')) {
3271 lex();
3272
3273 key = '$' + expr.name;
3274 if (Object.prototype.hasOwnProperty.call(state.labelSet, key)) {
3275 throwError({}, Messages.Redeclaration, 'Label', expr.name);
3276 }
3277
3278 state.labelSet[key] = true;
3279 labeledBody = parseStatement();
3280 delete state.labelSet[key];
3281 return delegate.markEnd(delegate.createLabeledStatement(expr, labeledBody), startToken);
3282 }
3283
3284 consumeSemicolon();
3285
3286 return delegate.markEnd(delegate.createExpressionStatement(expr), startToken);
3287 }
3288
3289 // 13 Function Definition
3290
3291 function parseFunctionSourceElements() {
3292 var sourceElement, sourceElements = [], token, directive, firstRestricted,
3293 oldLabelSet, oldInIteration, oldInSwitch, oldInFunctionBody, startToken;
3294
3295 startToken = lookahead;
3296 expect('{');
3297
3298 while (index < length) {
3299 if (lookahead.type !== Token.StringLiteral) {
3300 break;
3301 }
3302 token = lookahead;
3303
3304 sourceElement = parseSourceElement();
3305 sourceElements.push(sourceElement);
3306 if (sourceElement.expression.type !== Syntax.Literal) {
3307 // this is not directive
3308 break;
3309 }
3310 directive = source.slice(token.start + 1, token.end - 1);
3311 if (directive === 'use strict') {
3312 strict = true;
3313 if (firstRestricted) {
3314 throwErrorTolerant(firstRestricted, Messages.StrictOctalLiteral);
3315 }
3316 } else {
3317 if (!firstRestricted && token.octal) {
3318 firstRestricted = token;
3319 }
3320 }
3321 }
3322
3323 oldLabelSet = state.labelSet;
3324 oldInIteration = state.inIteration;
3325 oldInSwitch = state.inSwitch;
3326 oldInFunctionBody = state.inFunctionBody;
3327
3328 state.labelSet = {};
3329 state.inIteration = false;
3330 state.inSwitch = false;
3331 state.inFunctionBody = true;
3332
3333 while (index < length) {
3334 if (match('}')) {
3335 break;
3336 }
3337 sourceElement = parseSourceElement();
3338 if (typeof sourceElement === 'undefined') {
3339 break;
3340 }
3341 sourceElements.push(sourceElement);
3342 }
3343
3344 expect('}');
3345
3346 state.labelSet = oldLabelSet;
3347 state.inIteration = oldInIteration;
3348 state.inSwitch = oldInSwitch;
3349 state.inFunctionBody = oldInFunctionBody;
3350
3351 return delegate.markEnd(delegate.createBlockStatement(sourceElements), startToken);
3352 }
3353
3354 function parseParams(firstRestricted) {
3355 var param, params = [], token, stricted, paramSet, key, message;
3356 expect('(');
3357
3358 if (!match(')')) {
3359 paramSet = {};
3360 while (index < length) {
3361 token = lookahead;
3362 param = parseVariableIdentifier();
3363 key = '$' + token.value;
3364 if (strict) {
3365 if (isRestrictedWord(token.value)) {
3366 stricted = token;
3367 message = Messages.StrictParamName;
3368 }
3369 if (Object.prototype.hasOwnProperty.call(paramSet, key)) {
3370 stricted = token;
3371 message = Messages.StrictParamDupe;
3372 }
3373 } else if (!firstRestricted) {
3374 if (isRestrictedWord(token.value)) {
3375 firstRestricted = token;
3376 message = Messages.StrictParamName;
3377 } else if (isStrictModeReservedWord(token.value)) {
3378 firstRestricted = token;
3379 message = Messages.StrictReservedWord;
3380 } else if (Object.prototype.hasOwnProperty.call(paramSet, key)) {
3381 firstRestricted = token;
3382 message = Messages.StrictParamDupe;
3383 }
3384 }
3385 params.push(param);
3386 paramSet[key] = true;
3387 if (match(')')) {
3388 break;
3389 }
3390 expect(',');
3391 }
3392 }
3393
3394 expect(')');
3395
3396 return {
3397 params: params,
3398 stricted: stricted,
3399 firstRestricted: firstRestricted,
3400 message: message
3401 };
3402 }
3403
3404 function parseFunctionDeclaration() {
3405 var id, params = [], body, token, stricted, tmp, firstRestricted, message, previousStrict, startToken;
3406
3407 startToken = lookahead;
3408
3409 expectKeyword('function');
3410 token = lookahead;
3411 id = parseVariableIdentifier();
3412 if (strict) {
3413 if (isRestrictedWord(token.value)) {
3414 throwErrorTolerant(token, Messages.StrictFunctionName);
3415 }
3416 } else {
3417 if (isRestrictedWord(token.value)) {
3418 firstRestricted = token;
3419 message = Messages.StrictFunctionName;
3420 } else if (isStrictModeReservedWord(token.value)) {
3421 firstRestricted = token;
3422 message = Messages.StrictReservedWord;
3423 }
3424 }
3425
3426 tmp = parseParams(firstRestricted);
3427 params = tmp.params;
3428 stricted = tmp.stricted;
3429 firstRestricted = tmp.firstRestricted;
3430 if (tmp.message) {
3431 message = tmp.message;
3432 }
3433
3434 previousStrict = strict;
3435 body = parseFunctionSourceElements();
3436 if (strict && firstRestricted) {
3437 throwError(firstRestricted, message);
3438 }
3439 if (strict && stricted) {
3440 throwErrorTolerant(stricted, message);
3441 }
3442 strict = previousStrict;
3443
3444 return delegate.markEnd(delegate.createFunctionDeclaration(id, params, [], body), startToken);
3445 }
3446
3447 function parseFunctionExpression() {
3448 var token, id = null, stricted, firstRestricted, message, tmp, params = [], body, previousStrict, startToken;
3449
3450 startToken = lookahead;
3451 expectKeyword('function');
3452
3453 if (!match('(')) {
3454 token = lookahead;
3455 id = parseVariableIdentifier();
3456 if (strict) {
3457 if (isRestrictedWord(token.value)) {
3458 throwErrorTolerant(token, Messages.StrictFunctionName);
3459 }
3460 } else {
3461 if (isRestrictedWord(token.value)) {
3462 firstRestricted = token;
3463 message = Messages.StrictFunctionName;
3464 } else if (isStrictModeReservedWord(token.value)) {
3465 firstRestricted = token;
3466 message = Messages.StrictReservedWord;
3467 }
3468 }
3469 }
3470
3471 tmp = parseParams(firstRestricted);
3472 params = tmp.params;
3473 stricted = tmp.stricted;
3474 firstRestricted = tmp.firstRestricted;
3475 if (tmp.message) {
3476 message = tmp.message;
3477 }
3478
3479 previousStrict = strict;
3480 body = parseFunctionSourceElements();
3481 if (strict && firstRestricted) {
3482 throwError(firstRestricted, message);
3483 }
3484 if (strict && stricted) {
3485 throwErrorTolerant(stricted, message);
3486 }
3487 strict = previousStrict;
3488
3489 return delegate.markEnd(delegate.createFunctionExpression(id, params, [], body), startToken);
3490 }
3491
3492 // 14 Program
3493
3494 function parseSourceElement() {
3495 if (lookahead.type === Token.Keyword) {
3496 switch (lookahead.value) {
3497 case 'const':
3498 case 'let':
3499 return parseConstLetDeclaration(lookahead.value);
3500 case 'function':
3501 return parseFunctionDeclaration();
3502 default:
3503 return parseStatement();
3504 }
3505 }
3506
3507 if (lookahead.type !== Token.EOF) {
3508 return parseStatement();
3509 }
3510 }
3511
3512 function parseSourceElements() {
3513 var sourceElement, sourceElements = [], token, directive, firstRestricted;
3514
3515 while (index < length) {
3516 token = lookahead;
3517 if (token.type !== Token.StringLiteral) {
3518 break;
3519 }
3520
3521 sourceElement = parseSourceElement();
3522 sourceElements.push(sourceElement);
3523 if (sourceElement.expression.type !== Syntax.Literal) {
3524 // this is not directive
3525 break;
3526 }
3527 directive = source.slice(token.start + 1, token.end - 1);
3528 if (directive === 'use strict') {
3529 strict = true;
3530 if (firstRestricted) {
3531 throwErrorTolerant(firstRestricted, Messages.StrictOctalLiteral);
3532 }
3533 } else {
3534 if (!firstRestricted && token.octal) {
3535 firstRestricted = token;
3536 }
3537 }
3538 }
3539
3540 while (index < length) {
3541 sourceElement = parseSourceElement();
3542 /* istanbul ignore if */
3543 if (typeof sourceElement === 'undefined') {
3544 break;
3545 }
3546 sourceElements.push(sourceElement);
3547 }
3548 return sourceElements;
3549 }
3550
3551 function parseProgram() {
3552 var body, startToken;
3553
3554 skipComment();
3555 peek();
3556 startToken = lookahead;
3557 strict = false;
3558
3559 body = parseSourceElements();
3560 return delegate.markEnd(delegate.createProgram(body), startToken);
3561 }
3562
3563 function filterTokenLocation() {
3564 var i, entry, token, tokens = [];
3565
3566 for (i = 0; i < extra.tokens.length; ++i) {
3567 entry = extra.tokens[i];
3568 token = {
3569 type: entry.type,
3570 value: entry.value
3571 };
3572 if (extra.range) {
3573 token.range = entry.range;
3574 }
3575 if (extra.loc) {
3576 token.loc = entry.loc;
3577 }
3578 tokens.push(token);
3579 }
3580
3581 extra.tokens = tokens;
3582 }
3583
3584 function tokenize(code, options) {
3585 var toString,
3586 token,
3587 tokens;
3588
3589 toString = String;
3590 if (typeof code !== 'string' && !(code instanceof String)) {
3591 code = toString(code);
3592 }
3593
3594 delegate = SyntaxTreeDelegate;
3595 source = code;
3596 index = 0;
3597 lineNumber = (source.length > 0) ? 1 : 0;
3598 lineStart = 0;
3599 length = source.length;
3600 lookahead = null;
3601 state = {
3602 allowIn: true,
3603 labelSet: {},
3604 inFunctionBody: false,
3605 inIteration: false,
3606 inSwitch: false,
3607 lastCommentStart: -1
3608 };
3609
3610 extra = {};
3611
3612 // Options matching.
3613 options = options || {};
3614
3615 // Of course we collect tokens here.
3616 options.tokens = true;
3617 extra.tokens = [];
3618 extra.tokenize = true;
3619 // The following two fields are necessary to compute the Regex tokens.
3620 extra.openParenToken = -1;
3621 extra.openCurlyToken = -1;
3622
3623 extra.range = (typeof options.range === 'boolean') && options.range;
3624 extra.loc = (typeof options.loc === 'boolean') && options.loc;
3625
3626 if (typeof options.comment === 'boolean' && options.comment) {
3627 extra.comments = [];
3628 }
3629 if (typeof options.tolerant === 'boolean' && options.tolerant) {
3630 extra.errors = [];
3631 }
3632
3633 try {
3634 peek();
3635 if (lookahead.type === Token.EOF) {
3636 return extra.tokens;
3637 }
3638
3639 token = lex();
3640 while (lookahead.type !== Token.EOF) {
3641 try {
3642 token = lex();
3643 } catch (lexError) {
3644 token = lookahead;
3645 if (extra.errors) {
3646 extra.errors.push(lexError);
3647 // We have to break on the first error
3648 // to avoid infinite loops.
3649 break;
3650 } else {
3651 throw lexError;
3652 }
3653 }
3654 }
3655
3656 filterTokenLocation();
3657 tokens = extra.tokens;
3658 if (typeof extra.comments !== 'undefined') {
3659 tokens.comments = extra.comments;
3660 }
3661 if (typeof extra.errors !== 'undefined') {
3662 tokens.errors = extra.errors;
3663 }
3664 } catch (e) {
3665 throw e;
3666 } finally {
3667 extra = {};
3668 }
3669 return tokens;
3670 }
3671
3672 function parse(code, options) {
3673 var program, toString;
3674
3675 toString = String;
3676 if (typeof code !== 'string' && !(code instanceof String)) {
3677 code = toString(code);
3678 }
3679
3680 delegate = SyntaxTreeDelegate;
3681 source = code;
3682 index = 0;
3683 lineNumber = (source.length > 0) ? 1 : 0;
3684 lineStart = 0;
3685 length = source.length;
3686 lookahead = null;
3687 state = {
3688 allowIn: true,
3689 labelSet: {},
3690 inFunctionBody: false,
3691 inIteration: false,
3692 inSwitch: false,
3693 lastCommentStart: -1
3694 };
3695
3696 extra = {};
3697 if (typeof options !== 'undefined') {
3698 extra.range = (typeof options.range === 'boolean') && options.range;
3699 extra.loc = (typeof options.loc === 'boolean') && options.loc;
3700 extra.attachComment = (typeof options.attachComment === 'boolean') && options.attachComment;
3701
3702 if (extra.loc && options.source !== null && options.source !== undefined) {
3703 extra.source = toString(options.source);
3704 }
3705
3706 if (typeof options.tokens === 'boolean' && options.tokens) {
3707 extra.tokens = [];
3708 }
3709 if (typeof options.comment === 'boolean' && options.comment) {
3710 extra.comments = [];
3711 }
3712 if (typeof options.tolerant === 'boolean' && options.tolerant) {
3713 extra.errors = [];
3714 }
3715 if (extra.attachComment) {
3716 extra.range = true;
3717 extra.comments = [];
3718 extra.bottomRightStack = [];
3719 extra.trailingComments = [];
3720 extra.leadingComments = [];
3721 }
3722 }
3723
3724 try {
3725 program = parseProgram();
3726 if (typeof extra.comments !== 'undefined') {
3727 program.comments = extra.comments;
3728 }
3729 if (typeof extra.tokens !== 'undefined') {
3730 filterTokenLocation();
3731 program.tokens = extra.tokens;
3732 }
3733 if (typeof extra.errors !== 'undefined') {
3734 program.errors = extra.errors;
3735 }
3736 } catch (e) {
3737 throw e;
3738 } finally {
3739 extra = {};
3740 }
3741
3742 return program;
3743 }
3744
3745 // Sync with *.json manifests.
3746 exports.version = '1.2.5';
3747
3748 exports.tokenize = tokenize;
3749
3750 exports.parse = parse;
3751
3752 // Deep copy.
3753 /* istanbul ignore next */
3754 exports.Syntax = (function () {
3755 var name, types = {};
3756
3757 if (typeof Object.create === 'function') {
3758 types = Object.create(null);
3759 }
3760
3761 for (name in Syntax) {
3762 if (Syntax.hasOwnProperty(name)) {
3763 types[name] = Syntax[name];
3764 }
3765 }
3766
3767 if (typeof Object.freeze === 'function') {
3768 Object.freeze(types);
3769 }
3770
3771 return types;
3772 }());
3773
3774}));
3775/* vim: set sw=4 ts=4 et tw=80 : */
3776
3777},{}],1:[function(require,module,exports){
3778(function (process){
3779/* parser generated by jison 0.4.13 */
3780/*
3781 Returns a Parser object of the following structure:
3782
3783 Parser: {
3784 yy: {}
3785 }
3786
3787 Parser.prototype: {
3788 yy: {},
3789 trace: function(),
3790 symbols_: {associative list: name ==> number},
3791 terminals_: {associative list: number ==> name},
3792 productions_: [...],
3793 performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$),
3794 table: [...],
3795 defaultActions: {...},
3796 parseError: function(str, hash),
3797 parse: function(input),
3798
3799 lexer: {
3800 EOF: 1,
3801 parseError: function(str, hash),
3802 setInput: function(input),
3803 input: function(),
3804 unput: function(str),
3805 more: function(),
3806 less: function(n),
3807 pastInput: function(),
3808 upcomingInput: function(),
3809 showPosition: function(),
3810 test_match: function(regex_match_array, rule_index),
3811 next: function(),
3812 lex: function(),
3813 begin: function(condition),
3814 popState: function(),
3815 _currentRules: function(),
3816 topState: function(),
3817 pushState: function(condition),
3818
3819 options: {
3820 ranges: boolean (optional: true ==> token location info will include a .range[] member)
3821 flex: boolean (optional: true ==> flex-like lexing behaviour where the rules are tested exhaustively to find the longest match)
3822 backtrack_lexer: boolean (optional: true ==> lexer regexes are tested in order and for each matching regex the action code is invoked; the lexer terminates the scan when a token is returned by the action code)
3823 },
3824
3825 performAction: function(yy, yy_, $avoiding_name_collisions, YY_START),
3826 rules: [...],
3827 conditions: {associative list: name ==> set},
3828 }
3829 }
3830
3831
3832 token location info (@$, _$, etc.): {
3833 first_line: n,
3834 last_line: n,
3835 first_column: n,
3836 last_column: n,
3837 range: [start_number, end_number] (where the numbers are indexes into the input string, regular zero-based)
3838 }
3839
3840
3841 the parseError function receives a 'hash' object with these members for lexer and parser errors: {
3842 text: (matched text)
3843 token: (the produced terminal token, if any)
3844 line: (yylineno)
3845 }
3846 while parser (grammar) errors will also provide these members, i.e. parser errors deliver a superset of attributes: {
3847 loc: (yylloc)
3848 expected: (string describing the set of expected tokens)
3849 recoverable: (boolean: TRUE when the parser has a error recovery rule available for this particular error)
3850 }
3851*/
3852var parser = (function(){
3853var parser = {trace: function trace() { },
3854yy: {},
3855symbols_: {"error":2,"JSON_PATH":3,"DOLLAR":4,"PATH_COMPONENTS":5,"LEADING_CHILD_MEMBER_EXPRESSION":6,"PATH_COMPONENT":7,"MEMBER_COMPONENT":8,"SUBSCRIPT_COMPONENT":9,"CHILD_MEMBER_COMPONENT":10,"DESCENDANT_MEMBER_COMPONENT":11,"DOT":12,"MEMBER_EXPRESSION":13,"DOT_DOT":14,"STAR":15,"IDENTIFIER":16,"SCRIPT_EXPRESSION":17,"INTEGER":18,"END":19,"CHILD_SUBSCRIPT_COMPONENT":20,"DESCENDANT_SUBSCRIPT_COMPONENT":21,"[":22,"SUBSCRIPT":23,"]":24,"SUBSCRIPT_EXPRESSION":25,"SUBSCRIPT_EXPRESSION_LIST":26,"SUBSCRIPT_EXPRESSION_LISTABLE":27,",":28,"STRING_LITERAL":29,"ARRAY_SLICE":30,"FILTER_EXPRESSION":31,"QQ_STRING":32,"Q_STRING":33,"$accept":0,"$end":1},
3856terminals_: {2:"error",4:"DOLLAR",12:"DOT",14:"DOT_DOT",15:"STAR",16:"IDENTIFIER",17:"SCRIPT_EXPRESSION",18:"INTEGER",19:"END",22:"[",24:"]",28:",",30:"ARRAY_SLICE",31:"FILTER_EXPRESSION",32:"QQ_STRING",33:"Q_STRING"},
3857productions_: [0,[3,1],[3,2],[3,1],[3,2],[5,1],[5,2],[7,1],[7,1],[8,1],[8,1],[10,2],[6,1],[11,2],[13,1],[13,1],[13,1],[13,1],[13,1],[9,1],[9,1],[20,3],[21,4],[23,1],[23,1],[26,1],[26,3],[27,1],[27,1],[27,1],[25,1],[25,1],[25,1],[29,1],[29,1]],
3858performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate /* action[1] */, $$ /* vstack */, _$ /* lstack */
3859/**/) {
3860/* this == yyval */
3861if (!yy.ast) {
3862 yy.ast = _ast;
3863 _ast.initialize();
3864}
3865
3866var $0 = $$.length - 1;
3867switch (yystate) {
3868case 1:yy.ast.set({ expression: { type: "root", value: $$[$0] } }); yy.ast.unshift(); return yy.ast.yield()
3869break;
3870case 2:yy.ast.set({ expression: { type: "root", value: $$[$0-1] } }); yy.ast.unshift(); return yy.ast.yield()
3871break;
3872case 3:yy.ast.unshift(); return yy.ast.yield()
3873break;
3874case 4:yy.ast.set({ operation: "member", scope: "child", expression: { type: "identifier", value: $$[$0-1] }}); yy.ast.unshift(); return yy.ast.yield()
3875break;
3876case 5:
3877break;
3878case 6:
3879break;
3880case 7:yy.ast.set({ operation: "member" }); yy.ast.push()
3881break;
3882case 8:yy.ast.set({ operation: "subscript" }); yy.ast.push()
3883break;
3884case 9:yy.ast.set({ scope: "child" })
3885break;
3886case 10:yy.ast.set({ scope: "descendant" })
3887break;
3888case 11:
3889break;
3890case 12:yy.ast.set({ scope: "child", operation: "member" })
3891break;
3892case 13:
3893break;
3894case 14:yy.ast.set({ expression: { type: "wildcard", value: $$[$0] } })
3895break;
3896case 15:yy.ast.set({ expression: { type: "identifier", value: $$[$0] } })
3897break;
3898case 16:yy.ast.set({ expression: { type: "script_expression", value: $$[$0] } })
3899break;
3900case 17:yy.ast.set({ expression: { type: "numeric_literal", value: parseInt($$[$0]) } })
3901break;
3902case 18:
3903break;
3904case 19:yy.ast.set({ scope: "child" })
3905break;
3906case 20:yy.ast.set({ scope: "descendant" })
3907break;
3908case 21:
3909break;
3910case 22:
3911break;
3912case 23:
3913break;
3914case 24:$$[$0].length > 1? yy.ast.set({ expression: { type: "union", value: $$[$0] } }) : this.$ = $$[$0]
3915break;
3916case 25:this.$ = [$$[$0]]
3917break;
3918case 26:this.$ = $$[$0-2].concat($$[$0])
3919break;
3920case 27:this.$ = { expression: { type: "numeric_literal", value: parseInt($$[$0]) } }; yy.ast.set(this.$)
3921break;
3922case 28:this.$ = { expression: { type: "string_literal", value: $$[$0] } }; yy.ast.set(this.$)
3923break;
3924case 29:this.$ = { expression: { type: "slice", value: $$[$0] } }; yy.ast.set(this.$)
3925break;
3926case 30:this.$ = { expression: { type: "wildcard", value: $$[$0] } }; yy.ast.set(this.$)
3927break;
3928case 31:this.$ = { expression: { type: "script_expression", value: $$[$0] } }; yy.ast.set(this.$)
3929break;
3930case 32:this.$ = { expression: { type: "filter_expression", value: $$[$0] } }; yy.ast.set(this.$)
3931break;
3932case 33:this.$ = $$[$0]
3933break;
3934case 34:this.$ = $$[$0]
3935break;
3936}
3937},
3938table: [{3:1,4:[1,2],6:3,13:4,15:[1,5],16:[1,6],17:[1,7],18:[1,8],19:[1,9]},{1:[3]},{1:[2,1],5:10,7:11,8:12,9:13,10:14,11:15,12:[1,18],14:[1,19],20:16,21:17,22:[1,20]},{1:[2,3],5:21,7:11,8:12,9:13,10:14,11:15,12:[1,18],14:[1,19],20:16,21:17,22:[1,20]},{1:[2,12],12:[2,12],14:[2,12],22:[2,12]},{1:[2,14],12:[2,14],14:[2,14],22:[2,14]},{1:[2,15],12:[2,15],14:[2,15],22:[2,15]},{1:[2,16],12:[2,16],14:[2,16],22:[2,16]},{1:[2,17],12:[2,17],14:[2,17],22:[2,17]},{1:[2,18],12:[2,18],14:[2,18],22:[2,18]},{1:[2,2],7:22,8:12,9:13,10:14,11:15,12:[1,18],14:[1,19],20:16,21:17,22:[1,20]},{1:[2,5],12:[2,5],14:[2,5],22:[2,5]},{1:[2,7],12:[2,7],14:[2,7],22:[2,7]},{1:[2,8],12:[2,8],14:[2,8],22:[2,8]},{1:[2,9],12:[2,9],14:[2,9],22:[2,9]},{1:[2,10],12:[2,10],14:[2,10],22:[2,10]},{1:[2,19],12:[2,19],14:[2,19],22:[2,19]},{1:[2,20],12:[2,20],14:[2,20],22:[2,20]},{13:23,15:[1,5],16:[1,6],17:[1,7],18:[1,8],19:[1,9]},{13:24,15:[1,5],16:[1,6],17:[1,7],18:[1,8],19:[1,9],22:[1,25]},{15:[1,29],17:[1,30],18:[1,33],23:26,25:27,26:28,27:32,29:34,30:[1,35],31:[1,31],32:[1,36],33:[1,37]},{1:[2,4],7:22,8:12,9:13,10:14,11:15,12:[1,18],14:[1,19],20:16,21:17,22:[1,20]},{1:[2,6],12:[2,6],14:[2,6],22:[2,6]},{1:[2,11],12:[2,11],14:[2,11],22:[2,11]},{1:[2,13],12:[2,13],14:[2,13],22:[2,13]},{15:[1,29],17:[1,30],18:[1,33],23:38,25:27,26:28,27:32,29:34,30:[1,35],31:[1,31],32:[1,36],33:[1,37]},{24:[1,39]},{24:[2,23]},{24:[2,24],28:[1,40]},{24:[2,30]},{24:[2,31]},{24:[2,32]},{24:[2,25],28:[2,25]},{24:[2,27],28:[2,27]},{24:[2,28],28:[2,28]},{24:[2,29],28:[2,29]},{24:[2,33],28:[2,33]},{24:[2,34],28:[2,34]},{24:[1,41]},{1:[2,21],12:[2,21],14:[2,21],22:[2,21]},{18:[1,33],27:42,29:34,30:[1,35],32:[1,36],33:[1,37]},{1:[2,22],12:[2,22],14:[2,22],22:[2,22]},{24:[2,26],28:[2,26]}],
3939defaultActions: {27:[2,23],29:[2,30],30:[2,31],31:[2,32]},
3940parseError: function parseError(str, hash) {
3941 if (hash.recoverable) {
3942 this.trace(str);
3943 } else {
3944 throw new Error(str);
3945 }
3946},
3947parse: function parse(input) {
3948 var self = this, stack = [0], vstack = [null], lstack = [], table = this.table, yytext = '', yylineno = 0, yyleng = 0, recovering = 0, TERROR = 2, EOF = 1;
3949 var args = lstack.slice.call(arguments, 1);
3950 this.lexer.setInput(input);
3951 this.lexer.yy = this.yy;
3952 this.yy.lexer = this.lexer;
3953 this.yy.parser = this;
3954 if (typeof this.lexer.yylloc == 'undefined') {
3955 this.lexer.yylloc = {};
3956 }
3957 var yyloc = this.lexer.yylloc;
3958 lstack.push(yyloc);
3959 var ranges = this.lexer.options && this.lexer.options.ranges;
3960 if (typeof this.yy.parseError === 'function') {
3961 this.parseError = this.yy.parseError;
3962 } else {
3963 this.parseError = Object.getPrototypeOf(this).parseError;
3964 }
3965 function popStack(n) {
3966 stack.length = stack.length - 2 * n;
3967 vstack.length = vstack.length - n;
3968 lstack.length = lstack.length - n;
3969 }
3970 function lex() {
3971 var token;
3972 token = self.lexer.lex() || EOF;
3973 if (typeof token !== 'number') {
3974 token = self.symbols_[token] || token;
3975 }
3976 return token;
3977 }
3978 var symbol, preErrorSymbol, state, action, a, r, yyval = {}, p, len, newState, expected;
3979 while (true) {
3980 state = stack[stack.length - 1];
3981 if (this.defaultActions[state]) {
3982 action = this.defaultActions[state];
3983 } else {
3984 if (symbol === null || typeof symbol == 'undefined') {
3985 symbol = lex();
3986 }
3987 action = table[state] && table[state][symbol];
3988 }
3989 if (typeof action === 'undefined' || !action.length || !action[0]) {
3990 var errStr = '';
3991 expected = [];
3992 for (p in table[state]) {
3993 if (this.terminals_[p] && p > TERROR) {
3994 expected.push('\'' + this.terminals_[p] + '\'');
3995 }
3996 }
3997 if (this.lexer.showPosition) {
3998 errStr = 'Parse error on line ' + (yylineno + 1) + ':\n' + this.lexer.showPosition() + '\nExpecting ' + expected.join(', ') + ', got \'' + (this.terminals_[symbol] || symbol) + '\'';
3999 } else {
4000 errStr = 'Parse error on line ' + (yylineno + 1) + ': Unexpected ' + (symbol == EOF ? 'end of input' : '\'' + (this.terminals_[symbol] || symbol) + '\'');
4001 }
4002 this.parseError(errStr, {
4003 text: this.lexer.match,
4004 token: this.terminals_[symbol] || symbol,
4005 line: this.lexer.yylineno,
4006 loc: yyloc,
4007 expected: expected
4008 });
4009 }
4010 if (action[0] instanceof Array && action.length > 1) {
4011 throw new Error('Parse Error: multiple actions possible at state: ' + state + ', token: ' + symbol);
4012 }
4013 switch (action[0]) {
4014 case 1:
4015 stack.push(symbol);
4016 vstack.push(this.lexer.yytext);
4017 lstack.push(this.lexer.yylloc);
4018 stack.push(action[1]);
4019 symbol = null;
4020 if (!preErrorSymbol) {
4021 yyleng = this.lexer.yyleng;
4022 yytext = this.lexer.yytext;
4023 yylineno = this.lexer.yylineno;
4024 yyloc = this.lexer.yylloc;
4025 if (recovering > 0) {
4026 recovering--;
4027 }
4028 } else {
4029 symbol = preErrorSymbol;
4030 preErrorSymbol = null;
4031 }
4032 break;
4033 case 2:
4034 len = this.productions_[action[1]][1];
4035 yyval.$ = vstack[vstack.length - len];
4036 yyval._$ = {
4037 first_line: lstack[lstack.length - (len || 1)].first_line,
4038 last_line: lstack[lstack.length - 1].last_line,
4039 first_column: lstack[lstack.length - (len || 1)].first_column,
4040 last_column: lstack[lstack.length - 1].last_column
4041 };
4042 if (ranges) {
4043 yyval._$.range = [
4044 lstack[lstack.length - (len || 1)].range[0],
4045 lstack[lstack.length - 1].range[1]
4046 ];
4047 }
4048 r = this.performAction.apply(yyval, [
4049 yytext,
4050 yyleng,
4051 yylineno,
4052 this.yy,
4053 action[1],
4054 vstack,
4055 lstack
4056 ].concat(args));
4057 if (typeof r !== 'undefined') {
4058 return r;
4059 }
4060 if (len) {
4061 stack = stack.slice(0, -1 * len * 2);
4062 vstack = vstack.slice(0, -1 * len);
4063 lstack = lstack.slice(0, -1 * len);
4064 }
4065 stack.push(this.productions_[action[1]][0]);
4066 vstack.push(yyval.$);
4067 lstack.push(yyval._$);
4068 newState = table[stack[stack.length - 2]][stack[stack.length - 1]];
4069 stack.push(newState);
4070 break;
4071 case 3:
4072 return true;
4073 }
4074 }
4075 return true;
4076}};
4077var _ast = {
4078
4079 initialize: function() {
4080 this._nodes = [];
4081 this._node = {};
4082 this._stash = [];
4083 },
4084
4085 set: function(props) {
4086 for (var k in props) this._node[k] = props[k];
4087 return this._node;
4088 },
4089
4090 node: function(obj) {
4091 if (arguments.length) this._node = obj;
4092 return this._node;
4093 },
4094
4095 push: function() {
4096 this._nodes.push(this._node);
4097 this._node = {};
4098 },
4099
4100 unshift: function() {
4101 this._nodes.unshift(this._node);
4102 this._node = {};
4103 },
4104
4105 yield: function() {
4106 var _nodes = this._nodes;
4107 this.initialize();
4108 return _nodes;
4109 }
4110};
4111/* generated by jison-lex 0.2.1 */
4112var lexer = (function(){
4113var lexer = {
4114
4115EOF:1,
4116
4117parseError:function parseError(str, hash) {
4118 if (this.yy.parser) {
4119 this.yy.parser.parseError(str, hash);
4120 } else {
4121 throw new Error(str);
4122 }
4123 },
4124
4125// resets the lexer, sets new input
4126setInput:function (input) {
4127 this._input = input;
4128 this._more = this._backtrack = this.done = false;
4129 this.yylineno = this.yyleng = 0;
4130 this.yytext = this.matched = this.match = '';
4131 this.conditionStack = ['INITIAL'];
4132 this.yylloc = {
4133 first_line: 1,
4134 first_column: 0,
4135 last_line: 1,
4136 last_column: 0
4137 };
4138 if (this.options.ranges) {
4139 this.yylloc.range = [0,0];
4140 }
4141 this.offset = 0;
4142 return this;
4143 },
4144
4145// consumes and returns one char from the input
4146input:function () {
4147 var ch = this._input[0];
4148 this.yytext += ch;
4149 this.yyleng++;
4150 this.offset++;
4151 this.match += ch;
4152 this.matched += ch;
4153 var lines = ch.match(/(?:\r\n?|\n).*/g);
4154 if (lines) {
4155 this.yylineno++;
4156 this.yylloc.last_line++;
4157 } else {
4158 this.yylloc.last_column++;
4159 }
4160 if (this.options.ranges) {
4161 this.yylloc.range[1]++;
4162 }
4163
4164 this._input = this._input.slice(1);
4165 return ch;
4166 },
4167
4168// unshifts one char (or a string) into the input
4169unput:function (ch) {
4170 var len = ch.length;
4171 var lines = ch.split(/(?:\r\n?|\n)/g);
4172
4173 this._input = ch + this._input;
4174 this.yytext = this.yytext.substr(0, this.yytext.length - len - 1);
4175 //this.yyleng -= len;
4176 this.offset -= len;
4177 var oldLines = this.match.split(/(?:\r\n?|\n)/g);
4178 this.match = this.match.substr(0, this.match.length - 1);
4179 this.matched = this.matched.substr(0, this.matched.length - 1);
4180
4181 if (lines.length - 1) {
4182 this.yylineno -= lines.length - 1;
4183 }
4184 var r = this.yylloc.range;
4185
4186 this.yylloc = {
4187 first_line: this.yylloc.first_line,
4188 last_line: this.yylineno + 1,
4189 first_column: this.yylloc.first_column,
4190 last_column: lines ?
4191 (lines.length === oldLines.length ? this.yylloc.first_column : 0)
4192 + oldLines[oldLines.length - lines.length].length - lines[0].length :
4193 this.yylloc.first_column - len
4194 };
4195
4196 if (this.options.ranges) {
4197 this.yylloc.range = [r[0], r[0] + this.yyleng - len];
4198 }
4199 this.yyleng = this.yytext.length;
4200 return this;
4201 },
4202
4203// When called from action, caches matched text and appends it on next action
4204more:function () {
4205 this._more = true;
4206 return this;
4207 },
4208
4209// When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead.
4210reject:function () {
4211 if (this.options.backtrack_lexer) {
4212 this._backtrack = true;
4213 } else {
4214 return this.parseError('Lexical error on line ' + (this.yylineno + 1) + '. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n' + this.showPosition(), {
4215 text: "",
4216 token: null,
4217 line: this.yylineno
4218 });
4219
4220 }
4221 return this;
4222 },
4223
4224// retain first n characters of the match
4225less:function (n) {
4226 this.unput(this.match.slice(n));
4227 },
4228
4229// displays already matched input, i.e. for error messages
4230pastInput:function () {
4231 var past = this.matched.substr(0, this.matched.length - this.match.length);
4232 return (past.length > 20 ? '...':'') + past.substr(-20).replace(/\n/g, "");
4233 },
4234
4235// displays upcoming input, i.e. for error messages
4236upcomingInput:function () {
4237 var next = this.match;
4238 if (next.length < 20) {
4239 next += this._input.substr(0, 20-next.length);
4240 }
4241 return (next.substr(0,20) + (next.length > 20 ? '...' : '')).replace(/\n/g, "");
4242 },
4243
4244// displays the character position where the lexing error occurred, i.e. for error messages
4245showPosition:function () {
4246 var pre = this.pastInput();
4247 var c = new Array(pre.length + 1).join("-");
4248 return pre + this.upcomingInput() + "\n" + c + "^";
4249 },
4250
4251// test the lexed token: return FALSE when not a match, otherwise return token
4252test_match:function (match, indexed_rule) {
4253 var token,
4254 lines,
4255 backup;
4256
4257 if (this.options.backtrack_lexer) {
4258 // save context
4259 backup = {
4260 yylineno: this.yylineno,
4261 yylloc: {
4262 first_line: this.yylloc.first_line,
4263 last_line: this.last_line,
4264 first_column: this.yylloc.first_column,
4265 last_column: this.yylloc.last_column
4266 },
4267 yytext: this.yytext,
4268 match: this.match,
4269 matches: this.matches,
4270 matched: this.matched,
4271 yyleng: this.yyleng,
4272 offset: this.offset,
4273 _more: this._more,
4274 _input: this._input,
4275 yy: this.yy,
4276 conditionStack: this.conditionStack.slice(0),
4277 done: this.done
4278 };
4279 if (this.options.ranges) {
4280 backup.yylloc.range = this.yylloc.range.slice(0);
4281 }
4282 }
4283
4284 lines = match[0].match(/(?:\r\n?|\n).*/g);
4285 if (lines) {
4286 this.yylineno += lines.length;
4287 }
4288 this.yylloc = {
4289 first_line: this.yylloc.last_line,
4290 last_line: this.yylineno + 1,
4291 first_column: this.yylloc.last_column,
4292 last_column: lines ?
4293 lines[lines.length - 1].length - lines[lines.length - 1].match(/\r?\n?/)[0].length :
4294 this.yylloc.last_column + match[0].length
4295 };
4296 this.yytext += match[0];
4297 this.match += match[0];
4298 this.matches = match;
4299 this.yyleng = this.yytext.length;
4300 if (this.options.ranges) {
4301 this.yylloc.range = [this.offset, this.offset += this.yyleng];
4302 }
4303 this._more = false;
4304 this._backtrack = false;
4305 this._input = this._input.slice(match[0].length);
4306 this.matched += match[0];
4307 token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]);
4308 if (this.done && this._input) {
4309 this.done = false;
4310 }
4311 if (token) {
4312 return token;
4313 } else if (this._backtrack) {
4314 // recover context
4315 for (var k in backup) {
4316 this[k] = backup[k];
4317 }
4318 return false; // rule action called reject() implying the next rule should be tested instead.
4319 }
4320 return false;
4321 },
4322
4323// return next match in input
4324next:function () {
4325 if (this.done) {
4326 return this.EOF;
4327 }
4328 if (!this._input) {
4329 this.done = true;
4330 }
4331
4332 var token,
4333 match,
4334 tempMatch,
4335 index;
4336 if (!this._more) {
4337 this.yytext = '';
4338 this.match = '';
4339 }
4340 var rules = this._currentRules();
4341 for (var i = 0; i < rules.length; i++) {
4342 tempMatch = this._input.match(this.rules[rules[i]]);
4343 if (tempMatch && (!match || tempMatch[0].length > match[0].length)) {
4344 match = tempMatch;
4345 index = i;
4346 if (this.options.backtrack_lexer) {
4347 token = this.test_match(tempMatch, rules[i]);
4348 if (token !== false) {
4349 return token;
4350 } else if (this._backtrack) {
4351 match = false;
4352 continue; // rule action called reject() implying a rule MISmatch.
4353 } else {
4354 // else: this is a lexer rule which consumes input without producing a token (e.g. whitespace)
4355 return false;
4356 }
4357 } else if (!this.options.flex) {
4358 break;
4359 }
4360 }
4361 }
4362 if (match) {
4363 token = this.test_match(match, rules[index]);
4364 if (token !== false) {
4365 return token;
4366 }
4367 // else: this is a lexer rule which consumes input without producing a token (e.g. whitespace)
4368 return false;
4369 }
4370 if (this._input === "") {
4371 return this.EOF;
4372 } else {
4373 return this.parseError('Lexical error on line ' + (this.yylineno + 1) + '. Unrecognized text.\n' + this.showPosition(), {
4374 text: "",
4375 token: null,
4376 line: this.yylineno
4377 });
4378 }
4379 },
4380
4381// return next match that has a token
4382lex:function lex() {
4383 var r = this.next();
4384 if (r) {
4385 return r;
4386 } else {
4387 return this.lex();
4388 }
4389 },
4390
4391// activates a new lexer condition state (pushes the new lexer condition state onto the condition stack)
4392begin:function begin(condition) {
4393 this.conditionStack.push(condition);
4394 },
4395
4396// pop the previously active lexer condition state off the condition stack
4397popState:function popState() {
4398 var n = this.conditionStack.length - 1;
4399 if (n > 0) {
4400 return this.conditionStack.pop();
4401 } else {
4402 return this.conditionStack[0];
4403 }
4404 },
4405
4406// produce the lexer rule set which is active for the currently active lexer condition state
4407_currentRules:function _currentRules() {
4408 if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) {
4409 return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules;
4410 } else {
4411 return this.conditions["INITIAL"].rules;
4412 }
4413 },
4414
4415// return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available
4416topState:function topState(n) {
4417 n = this.conditionStack.length - 1 - Math.abs(n || 0);
4418 if (n >= 0) {
4419 return this.conditionStack[n];
4420 } else {
4421 return "INITIAL";
4422 }
4423 },
4424
4425// alias for begin(condition)
4426pushState:function pushState(condition) {
4427 this.begin(condition);
4428 },
4429
4430// return the number of states currently on the stack
4431stateStackSize:function stateStackSize() {
4432 return this.conditionStack.length;
4433 },
4434options: {},
4435performAction: function anonymous(yy,yy_,$avoiding_name_collisions,YY_START
4436/**/) {
4437
4438var YYSTATE=YY_START;
4439switch($avoiding_name_collisions) {
4440case 0:return 4
4441break;
4442case 1:return 14
4443break;
4444case 2:return 12
4445break;
4446case 3:return 15
4447break;
4448case 4:return 16
4449break;
4450case 5:return 22
4451break;
4452case 6:return 24
4453break;
4454case 7:return 28
4455break;
4456case 8:return 30
4457break;
4458case 9:return 18
4459break;
4460case 10:yy_.yytext = yy_.yytext.substr(1,yy_.yyleng-2); return 32;
4461break;
4462case 11:yy_.yytext = yy_.yytext.substr(1,yy_.yyleng-2); return 33;
4463break;
4464case 12:return 17
4465break;
4466case 13:return 31
4467break;
4468}
4469},
4470rules: [/^(?:\$)/,/^(?:\.\.)/,/^(?:\.)/,/^(?:\*)/,/^(?:[a-zA-Z_]+[a-zA-Z0-9_]*)/,/^(?:\[)/,/^(?:\])/,/^(?:,)/,/^(?:((-?(?:0|[1-9][0-9]*)))?\:((-?(?:0|[1-9][0-9]*)))?(\:((-?(?:0|[1-9][0-9]*)))?)?)/,/^(?:(-?(?:0|[1-9][0-9]*)))/,/^(?:"(?:\\["bfnrt/\\]|\\u[a-fA-F0-9]{4}|[^"\\])*")/,/^(?:'(?:\\['bfnrt/\\]|\\u[a-fA-F0-9]{4}|[^'\\])*')/,/^(?:\(.+?\)(?=\]))/,/^(?:\?\(.+?\)(?=\]))/],
4471conditions: {"INITIAL":{"rules":[0,1,2,3,4,5,6,7,8,9,10,11,12,13],"inclusive":true}}
4472};
4473return lexer;
4474})();
4475parser.lexer = lexer;
4476function Parser () {
4477 this.yy = {};
4478}
4479Parser.prototype = parser;parser.Parser = Parser;
4480return new Parser;
4481})();
4482
4483
4484if (typeof require !== 'undefined' && typeof exports !== 'undefined') {
4485exports.parser = parser;
4486exports.Parser = parser.Parser;
4487exports.parse = function () { return parser.parse.apply(parser, arguments); };
4488exports.main = function commonjsMain(args) {
4489 if (!args[1]) {
4490 console.log('Usage: '+args[0]+' FILE');
4491 process.exit(1);
4492 }
4493 var source = require('fs').readFileSync(require('path').normalize(args[1]), "utf8");
4494 return exports.parser.parse(source);
4495};
4496if (typeof module !== 'undefined' && require.main === module) {
4497 exports.main(process.argv.slice(1));
4498}
4499}
4500
4501}).call(this,require('_process'))
4502},{"_process":14,"fs":12,"path":13}],2:[function(require,module,exports){
4503module.exports = {
4504 identifier: "[a-zA-Z_]+[a-zA-Z0-9_]*",
4505 integer: "-?(?:0|[1-9][0-9]*)",
4506 qq_string: "\"(?:\\\\[\"bfnrt/\\\\]|\\\\u[a-fA-F0-9]{4}|[^\"\\\\])*\"",
4507 q_string: "'(?:\\\\[\'bfnrt/\\\\]|\\\\u[a-fA-F0-9]{4}|[^\'\\\\])*'"
4508};
4509
4510},{}],3:[function(require,module,exports){
4511var dict = require('./dict');
4512var fs = require('fs');
4513var grammar = {
4514
4515 lex: {
4516
4517 macros: {
4518 esc: "\\\\",
4519 int: dict.integer
4520 },
4521
4522 rules: [
4523 ["\\$", "return 'DOLLAR'"],
4524 ["\\.\\.", "return 'DOT_DOT'"],
4525 ["\\.", "return 'DOT'"],
4526 ["\\*", "return 'STAR'"],
4527 [dict.identifier, "return 'IDENTIFIER'"],
4528 ["\\[", "return '['"],
4529 ["\\]", "return ']'"],
4530 [",", "return ','"],
4531 ["({int})?\\:({int})?(\\:({int})?)?", "return 'ARRAY_SLICE'"],
4532 ["{int}", "return 'INTEGER'"],
4533 [dict.qq_string, "yytext = yytext.substr(1,yyleng-2); return 'QQ_STRING';"],
4534 [dict.q_string, "yytext = yytext.substr(1,yyleng-2); return 'Q_STRING';"],
4535 ["\\(.+?\\)(?=\\])", "return 'SCRIPT_EXPRESSION'"],
4536 ["\\?\\(.+?\\)(?=\\])", "return 'FILTER_EXPRESSION'"]
4537 ]
4538 },
4539
4540 start: "JSON_PATH",
4541
4542 bnf: {
4543
4544 JSON_PATH: [
4545 [ 'DOLLAR', 'yy.ast.set({ expression: { type: "root", value: $1 } }); yy.ast.unshift(); return yy.ast.yield()' ],
4546 [ 'DOLLAR PATH_COMPONENTS', 'yy.ast.set({ expression: { type: "root", value: $1 } }); yy.ast.unshift(); return yy.ast.yield()' ],
4547 [ 'LEADING_CHILD_MEMBER_EXPRESSION', 'yy.ast.unshift(); return yy.ast.yield()' ],
4548 [ 'LEADING_CHILD_MEMBER_EXPRESSION PATH_COMPONENTS', 'yy.ast.set({ operation: "member", scope: "child", expression: { type: "identifier", value: $1 }}); yy.ast.unshift(); return yy.ast.yield()' ] ],
4549
4550 PATH_COMPONENTS: [
4551 [ 'PATH_COMPONENT', '' ],
4552 [ 'PATH_COMPONENTS PATH_COMPONENT', '' ] ],
4553
4554 PATH_COMPONENT: [
4555 [ 'MEMBER_COMPONENT', 'yy.ast.set({ operation: "member" }); yy.ast.push()' ],
4556 [ 'SUBSCRIPT_COMPONENT', 'yy.ast.set({ operation: "subscript" }); yy.ast.push() ' ] ],
4557
4558 MEMBER_COMPONENT: [
4559 [ 'CHILD_MEMBER_COMPONENT', 'yy.ast.set({ scope: "child" })' ],
4560 [ 'DESCENDANT_MEMBER_COMPONENT', 'yy.ast.set({ scope: "descendant" })' ] ],
4561
4562 CHILD_MEMBER_COMPONENT: [
4563 [ 'DOT MEMBER_EXPRESSION', '' ] ],
4564
4565 LEADING_CHILD_MEMBER_EXPRESSION: [
4566 [ 'MEMBER_EXPRESSION', 'yy.ast.set({ scope: "child", operation: "member" })' ] ],
4567
4568 DESCENDANT_MEMBER_COMPONENT: [
4569 [ 'DOT_DOT MEMBER_EXPRESSION', '' ] ],
4570
4571 MEMBER_EXPRESSION: [
4572 [ 'STAR', 'yy.ast.set({ expression: { type: "wildcard", value: $1 } })' ],
4573 [ 'IDENTIFIER', 'yy.ast.set({ expression: { type: "identifier", value: $1 } })' ],
4574 [ 'SCRIPT_EXPRESSION', 'yy.ast.set({ expression: { type: "script_expression", value: $1 } })' ],
4575 [ 'INTEGER', 'yy.ast.set({ expression: { type: "numeric_literal", value: parseInt($1) } })' ],
4576 [ 'END', '' ] ],
4577
4578 SUBSCRIPT_COMPONENT: [
4579 [ 'CHILD_SUBSCRIPT_COMPONENT', 'yy.ast.set({ scope: "child" })' ],
4580 [ 'DESCENDANT_SUBSCRIPT_COMPONENT', 'yy.ast.set({ scope: "descendant" })' ] ],
4581
4582 CHILD_SUBSCRIPT_COMPONENT: [
4583 [ '[ SUBSCRIPT ]', '' ] ],
4584
4585 DESCENDANT_SUBSCRIPT_COMPONENT: [
4586 [ 'DOT_DOT [ SUBSCRIPT ]', '' ] ],
4587
4588 SUBSCRIPT: [
4589 [ 'SUBSCRIPT_EXPRESSION', '' ],
4590 [ 'SUBSCRIPT_EXPRESSION_LIST', '$1.length > 1? yy.ast.set({ expression: { type: "union", value: $1 } }) : $$ = $1' ] ],
4591
4592 SUBSCRIPT_EXPRESSION_LIST: [
4593 [ 'SUBSCRIPT_EXPRESSION_LISTABLE', '$$ = [$1]'],
4594 [ 'SUBSCRIPT_EXPRESSION_LIST , SUBSCRIPT_EXPRESSION_LISTABLE', '$$ = $1.concat($3)' ] ],
4595
4596 SUBSCRIPT_EXPRESSION_LISTABLE: [
4597 [ 'INTEGER', '$$ = { expression: { type: "numeric_literal", value: parseInt($1) } }; yy.ast.set($$)' ],
4598 [ 'STRING_LITERAL', '$$ = { expression: { type: "string_literal", value: $1 } }; yy.ast.set($$)' ],
4599 [ 'ARRAY_SLICE', '$$ = { expression: { type: "slice", value: $1 } }; yy.ast.set($$)' ] ],
4600
4601 SUBSCRIPT_EXPRESSION: [
4602 [ 'STAR', '$$ = { expression: { type: "wildcard", value: $1 } }; yy.ast.set($$)' ],
4603 [ 'SCRIPT_EXPRESSION', '$$ = { expression: { type: "script_expression", value: $1 } }; yy.ast.set($$)' ],
4604 [ 'FILTER_EXPRESSION', '$$ = { expression: { type: "filter_expression", value: $1 } }; yy.ast.set($$)' ] ],
4605
4606 STRING_LITERAL: [
4607 [ 'QQ_STRING', "$$ = $1" ],
4608 [ 'Q_STRING', "$$ = $1" ] ]
4609 }
4610};
4611if (fs.readFileSync) {
4612 grammar.moduleInclude = fs.readFileSync(require.resolve("../include/module.js"));
4613 grammar.actionInclude = fs.readFileSync(require.resolve("../include/action.js"));
4614}
4615
4616module.exports = grammar;
4617
4618},{"./dict":2,"fs":12}],4:[function(require,module,exports){
4619var aesprim = require('./aesprim');
4620var slice = require('./slice');
4621var _evaluate = require('static-eval');
4622var _uniq = require('underscore').uniq;
4623
4624// Property names that must never be accessible in expressions.
4625// Mitigates prototype pollution and constructor escape attacks.
4626var UNSAFE_PROPERTY_NAMES = Object.create(null);
4627
4628/* jshint -W069: true */
4629UNSAFE_PROPERTY_NAMES['constructor'] = true;
4630UNSAFE_PROPERTY_NAMES['__proto__'] = true;
4631UNSAFE_PROPERTY_NAMES['prototype'] = true;
4632/* jshint -W069: false */
4633
4634function isUnsafePropertyName(name) {
4635 return typeof name === 'string' && UNSAFE_PROPERTY_NAMES[name] === true;
4636}
4637
4638function isSafeAst(ast) {
4639 if (!ast || typeof ast !== 'object') return false;
4640
4641 function walk(node) {
4642 if (!node || typeof node !== 'object' || !node.type) {
4643 return false;
4644 }
4645
4646 switch (node.type) {
4647
4648 // ===== SAFE TERMINALS =====
4649
4650 case 'Literal':
4651 return true;
4652
4653 case 'Identifier':
4654 // Only allow the special scope identifier
4655 return node.name === '@';
4656
4657
4658 // ===== PROPERTY ACCESS =====
4659
4660 case 'MemberExpression': {
4661 if (!walk(node.object)) {
4662 return false;
4663 }
4664
4665 // Non-computed: obj.property
4666 if (!node.computed && node.property.type === 'Identifier') {
4667 if (isUnsafePropertyName(node.property.name)) {
4668 return false;
4669 }
4670 return true;
4671 }
4672
4673 // Computed: obj["property"]
4674 if (node.computed) {
4675 if (!walk(node.property)) {
4676 return false;
4677 }
4678
4679 if (
4680 node.property.type === 'Literal' &&
4681 isUnsafePropertyName(String(node.property.value))
4682 ) {
4683 return false;
4684 }
4685
4686 return true;
4687 }
4688
4689 return false;
4690 }
4691
4692
4693 // ===== EXPRESSIONS =====
4694
4695 case 'UnaryExpression':
4696 return walk(node.argument);
4697
4698 case 'BinaryExpression':
4699 case 'LogicalExpression':
4700 return walk(node.left) && walk(node.right);
4701
4702 case 'ConditionalExpression':
4703 return (
4704 walk(node.test) &&
4705 walk(node.consequent) &&
4706 walk(node.alternate)
4707 );
4708
4709 case 'ArrayExpression':
4710 for (var i = 0; i < node.elements.length; i++) {
4711 if (!walk(node.elements[i])) {
4712 return false;
4713 }
4714 }
4715 return true;
4716
4717 case 'ObjectExpression':
4718 for (var j = 0; j < node.properties.length; j++) {
4719 var prop = node.properties[j];
4720
4721 // Reject unsafe keys
4722 if (
4723 prop.key &&
4724 (
4725 (prop.key.type === 'Identifier' &&
4726 isUnsafePropertyName(prop.key.name)) ||
4727 (prop.key.type === 'Literal' &&
4728 isUnsafePropertyName(String(prop.key.value)))
4729 )
4730 ) {
4731 return false;
4732 }
4733
4734 if (!walk(prop.value)) {
4735 return false;
4736 }
4737 }
4738 return true;
4739
4740
4741 // ===== EXPLICITLY REJECT DANGEROUS TYPES =====
4742 // Security: do not rely on default deny; list each code-execution / escape vector.
4743
4744 case 'CallExpression':
4745 case 'NewExpression':
4746 case 'FunctionExpression':
4747 case 'ArrowFunctionExpression':
4748 case 'ThisExpression':
4749 case 'AssignmentExpression':
4750 case 'UpdateExpression':
4751 case 'SequenceExpression':
4752 case 'TemplateLiteral':
4753 case 'TemplateElement':
4754 case 'TaggedTemplateExpression':
4755 case 'ReturnStatement':
4756 case 'ExpressionStatement':
4757 return false;
4758
4759
4760 // ===== DEFAULT DENY =====
4761
4762 default:
4763 return false;
4764 }
4765 }
4766
4767 return walk(ast);
4768}
4769
4770var Handlers = function() {
4771 return this.initialize.apply(this, arguments);
4772}
4773
4774Handlers.prototype.initialize = function() {
4775 this.traverse = traverser(true);
4776 this.descend = traverser();
4777}
4778
4779Handlers.prototype.keys = Object.keys;
4780
4781Handlers.prototype.resolve = function(component) {
4782
4783 var key = [ component.operation, component.scope, component.expression.type ].join('-');
4784 var method = this._fns[key];
4785
4786 if (!method) throw new Error("couldn't resolve key: " + key);
4787 return method.bind(this);
4788};
4789
4790Handlers.prototype.register = function(key, handler) {
4791
4792 if (!handler instanceof Function) {
4793 throw new Error("handler must be a function");
4794 }
4795
4796 this._fns[key] = handler;
4797};
4798
4799Handlers.prototype._fns = {
4800
4801 'member-child-identifier': function(component, partial) {
4802 var key = component.expression.value;
4803 var value = partial.value;
4804 if (value instanceof Object && key in value) {
4805 return [ { value: value[key], path: partial.path.concat(key) } ]
4806 }
4807 },
4808
4809 'member-descendant-identifier':
4810 _traverse(function(key, value, ref) { return key == ref }),
4811
4812 'subscript-child-numeric_literal':
4813 _descend(function(key, value, ref) { return key === ref }),
4814
4815 'member-child-numeric_literal':
4816 _descend(function(key, value, ref) { return String(key) === String(ref) }),
4817
4818 'subscript-descendant-numeric_literal':
4819 _traverse(function(key, value, ref) { return key === ref }),
4820
4821 'member-child-wildcard':
4822 _descend(function() { return true }),
4823
4824 'member-descendant-wildcard':
4825 _traverse(function() { return true }),
4826
4827 'subscript-descendant-wildcard':
4828 _traverse(function() { return true }),
4829
4830 'subscript-child-wildcard':
4831 _descend(function() { return true }),
4832
4833 'subscript-child-slice': function(component, partial) {
4834 if (is_array(partial.value)) {
4835 var args = component.expression.value.split(':').map(_parse_nullable_int);
4836 var values = partial.value.map(function(v, i) { return { value: v, path: partial.path.concat(i) } });
4837 return slice.apply(null, [values].concat(args));
4838 }
4839 },
4840
4841 'subscript-child-union': function(component, partial) {
4842 var results = [];
4843 component.expression.value.forEach(function(component) {
4844 var _component = { operation: 'subscript', scope: 'child', expression: component.expression };
4845 var handler = this.resolve(_component);
4846 var _results = handler(_component, partial);
4847 if (_results) {
4848 results = results.concat(_results);
4849 }
4850 }, this);
4851
4852 return unique(results);
4853 },
4854
4855 'subscript-descendant-union': function(component, partial, count) {
4856
4857 var jp = require('..');
4858 var self = this;
4859
4860 var results = [];
4861 var nodes = jp.nodes(partial, '$..*').slice(1);
4862
4863 nodes.forEach(function(node) {
4864 if (results.length >= count) return;
4865 component.expression.value.forEach(function(component) {
4866 var _component = { operation: 'subscript', scope: 'child', expression: component.expression };
4867 var handler = self.resolve(_component);
4868 var _results = handler(_component, node);
4869 results = results.concat(_results);
4870 });
4871 });
4872
4873 return unique(results);
4874 },
4875
4876 'subscript-child-filter_expression': function(component, partial, count) {
4877
4878 // slice out the expression from ?(expression)
4879 var src = component.expression.value.slice(2, -1);
4880 var ast = aesprim.parse(src).body[0].expression;
4881
4882 var passable = function(key, value) {
4883 return evaluate(ast, { '@': value });
4884 }
4885
4886 return this.descend(partial, null, passable, count);
4887
4888 },
4889
4890 'subscript-descendant-filter_expression': function(component, partial, count) {
4891
4892 // slice out the expression from ?(expression)
4893 var src = component.expression.value.slice(2, -1);
4894 var ast = aesprim.parse(src).body[0].expression;
4895
4896 var passable = function(key, value) {
4897 return evaluate(ast, { '@': value });
4898 }
4899
4900 return this.traverse(partial, null, passable, count);
4901 },
4902
4903 'subscript-child-script_expression': function(component, partial) {
4904 var exp = component.expression.value.slice(1, -1);
4905 return eval_recurse(partial, exp, '$[{{value}}]');
4906 },
4907
4908 'member-child-script_expression': function(component, partial) {
4909 var exp = component.expression.value.slice(1, -1);
4910 return eval_recurse(partial, exp, '$.{{value}}');
4911 },
4912
4913 'member-descendant-script_expression': function(component, partial) {
4914 var exp = component.expression.value.slice(1, -1);
4915 return eval_recurse(partial, exp, '$..value');
4916 }
4917};
4918
4919Handlers.prototype._fns['subscript-child-string_literal'] =
4920 Handlers.prototype._fns['member-child-identifier'];
4921
4922Handlers.prototype._fns['member-descendant-numeric_literal'] =
4923 Handlers.prototype._fns['subscript-descendant-string_literal'] =
4924 Handlers.prototype._fns['member-descendant-identifier'];
4925
4926function eval_recurse(partial, src, template) {
4927
4928 var jp = require('./index');
4929 var ast = aesprim.parse(src).body[0].expression;
4930 var value = evaluate(ast, { '@': partial.value });
4931 var path = template.replace(/\{\{\s*value\s*\}\}/g, value);
4932
4933 var results = jp.nodes(partial.value, path);
4934 results.forEach(function(r) {
4935 r.path = partial.path.concat(r.path.slice(1));
4936 });
4937
4938 return results;
4939}
4940
4941function is_array(val) {
4942 return Array.isArray(val);
4943}
4944
4945function is_object(val) {
4946 // is this a non-array, non-null object?
4947 return val && !(val instanceof Array) && val instanceof Object;
4948}
4949
4950function traverser(recurse) {
4951
4952 return function(partial, ref, passable, count) {
4953
4954 var value = partial.value;
4955 var path = partial.path;
4956
4957 var results = [];
4958
4959 var descend = function(value, path) {
4960
4961 if (is_array(value)) {
4962 value.forEach(function(element, index) {
4963 if (results.length >= count) { return }
4964 if (passable(index, element, ref)) {
4965 results.push({ path: path.concat(index), value: element });
4966 }
4967 });
4968 value.forEach(function(element, index) {
4969 if (results.length >= count) { return }
4970 if (recurse) {
4971 descend(element, path.concat(index));
4972 }
4973 });
4974 } else if (is_object(value)) {
4975 this.keys(value).forEach(function(k) {
4976 if (results.length >= count) { return }
4977 if (passable(k, value[k], ref)) {
4978 results.push({ path: path.concat(k), value: value[k] });
4979 }
4980 })
4981 this.keys(value).forEach(function(k) {
4982 if (results.length >= count) { return }
4983 if (recurse) {
4984 descend(value[k], path.concat(k));
4985 }
4986 });
4987 }
4988 }.bind(this);
4989 descend(value, path);
4990 return results;
4991 }
4992}
4993
4994function _descend(passable) {
4995 return function(component, partial, count) {
4996 return this.descend(partial, component.expression.value, passable, count);
4997 }
4998}
4999
5000function _traverse(passable) {
5001 return function(component, partial, count) {
5002 return this.traverse(partial, component.expression.value, passable, count);
5003 }
5004}
5005
5006function evaluate(ast, scope) {
5007 if (!isSafeAst(ast)) {
5008 throw new Error('Unsafe expression: script and filter expressions may only access the current node (@) with safe property names');
5009 }
5010 try { return _evaluate(ast, scope) }
5011 catch (e) { }
5012}
5013
5014function unique(results) {
5015 results = results.filter(function(d) { return d })
5016 return _uniq(
5017 results,
5018 function(r) { return r.path.map(function(c) { return String(c).replace('-', '--') }).join('-') }
5019 );
5020}
5021
5022function _parse_nullable_int(val) {
5023 var sval = String(val);
5024 return sval.match(/^-?[0-9]+$/) ? parseInt(sval) : null;
5025}
5026
5027module.exports = Handlers;
5028
5029},{"..":"jsonpath","./aesprim":"./aesprim","./index":5,"./slice":7,"static-eval":15,"underscore":12}],5:[function(require,module,exports){
5030var assert = require('assert');
5031var dict = require('./dict');
5032var Parser = require('./parser');
5033var Handlers = require('./handlers');
5034
5035var JSONPath = function() {
5036 this.initialize.apply(this, arguments);
5037};
5038
5039JSONPath.prototype.initialize = function() {
5040 this.parser = new Parser();
5041 this.handlers = new Handlers();
5042};
5043
5044JSONPath.prototype.parse = function(string) {
5045 assert.ok(_is_string(string), "we need a path");
5046 return this.parser.parse(string);
5047};
5048
5049JSONPath.prototype.parent = function(obj, string) {
5050
5051 assert.ok(obj instanceof Object, "obj needs to be an object");
5052 assert.ok(string, "we need a path");
5053
5054 var node = this.nodes(obj, string)[0];
5055 if (node) this._assert_safe_path_keys(node.path);
5056 var key = node.path.pop(); /* jshint unused:false */
5057 return this.value(obj, node.path);
5058}
5059
5060JSONPath.prototype.apply = function(obj, string, fn) {
5061
5062 assert.ok(obj instanceof Object, "obj needs to be an object");
5063 assert.ok(string, "we need a path");
5064 assert.equal(typeof fn, "function", "fn needs to be function")
5065
5066 var nodes = this.nodes(obj, string).sort(function(a, b) {
5067 // sort nodes so we apply from the bottom up
5068 return b.path.length - a.path.length;
5069 });
5070
5071 nodes.forEach(function(node) {
5072 this._assert_safe_path_keys(node.path);
5073 var key = node.path.pop();
5074 var parent = this.value(obj, this.stringify(node.path));
5075 var val = node.value = fn.call(obj, parent[key]);
5076 parent[key] = val;
5077 }, this);
5078
5079 return nodes;
5080}
5081
5082JSONPath.prototype.value = function(obj, path, value) {
5083
5084 assert.ok(obj instanceof Object, "obj needs to be an object");
5085 assert.ok(path, "we need a path");
5086
5087 if (arguments.length >= 3) {
5088 var node = this.nodes(obj, path).shift();
5089 if (!node) return this._vivify(obj, path, value);
5090 this._assert_safe_path_keys(node.path);
5091 var key = node.path.slice(-1).shift();
5092 var parent = this.parent(obj, this.stringify(node.path));
5093 parent[key] = value;
5094 }
5095 return this.query(obj, this.stringify(path), 1).shift();
5096}
5097
5098JSONPath.prototype._vivify = function(obj, string, value) {
5099
5100 var self = this;
5101
5102 assert.ok(obj instanceof Object, "obj needs to be an object");
5103 assert.ok(string, "we need a path");
5104
5105 var path = this.parser.parse(string)
5106 .map(function(component) { return component.expression.value });
5107
5108 this._assert_safe_path_keys(path);
5109
5110 var setValue = function(path, value) {
5111 var key = path.pop();
5112 var node = self.value(obj, path);
5113 if (!node) {
5114 setValue(path.concat(), typeof key === 'string' ? {} : []);
5115 node = self.value(obj, path);
5116 }
5117 self._assert_safe_key(key);
5118 node[key] = value;
5119 }
5120 setValue(path, value);
5121 return this.query(obj, string)[0];
5122}
5123
5124JSONPath.prototype.query = function(obj, string, count) {
5125
5126 assert.ok(obj instanceof Object, "obj needs to be an object");
5127 assert.ok(_is_string(string), "we need a path");
5128
5129 var results = this.nodes(obj, string, count)
5130 .map(function(r) { return r.value });
5131
5132 return results;
5133};
5134
5135JSONPath.prototype.paths = function(obj, string, count) {
5136
5137 assert.ok(obj instanceof Object, "obj needs to be an object");
5138 assert.ok(string, "we need a path");
5139
5140 var results = this.nodes(obj, string, count)
5141 .map(function(r) { return r.path });
5142
5143 return results;
5144};
5145
5146JSONPath.prototype.nodes = function(obj, string, count) {
5147
5148 assert.ok(obj instanceof Object, "obj needs to be an object");
5149 assert.ok(string, "we need a path");
5150
5151 if (count === 0) return [];
5152
5153 var path = this.parser.parse(string);
5154 this._assert_safe_components(path);
5155 var handlers = this.handlers;
5156
5157 var partials = [ { path: ['$'], value: obj } ];
5158 var matches = [];
5159
5160 if (path.length && path[0].expression.type == 'root') path.shift();
5161
5162 if (!path.length) return partials;
5163
5164 path.forEach(function(component, index) {
5165
5166 if (matches.length >= count) return;
5167 var handler = handlers.resolve(component);
5168 var _partials = [];
5169
5170 partials.forEach(function(p) {
5171
5172 if (matches.length >= count) return;
5173 var results = handler(component, p, count);
5174
5175 if (index == path.length - 1) {
5176 // if we're through the components we're done
5177 matches = matches.concat(results || []);
5178 } else {
5179 // otherwise accumulate and carry on through
5180 _partials = _partials.concat(results || []);
5181 }
5182 });
5183
5184 partials = _partials;
5185
5186 });
5187
5188 return count ? matches.slice(0, count) : matches;
5189};
5190
5191JSONPath.prototype.stringify = function(path) {
5192
5193 assert.ok(path, "we need a path");
5194
5195 var string = '$';
5196
5197 var templates = {
5198 'descendant-member': '..{{value}}',
5199 'child-member': '.{{value}}',
5200 'descendant-subscript': '..[{{value}}]',
5201 'child-subscript': '[{{value}}]'
5202 };
5203
5204 path = this._normalize(path);
5205
5206 path.forEach(function(component) {
5207
5208 if (component.expression.type == 'root') return;
5209
5210 var key = [component.scope, component.operation].join('-');
5211 var template = templates[key];
5212 var value;
5213
5214 if (component.expression.type == 'string_literal') {
5215 value = JSON.stringify(component.expression.value)
5216 } else {
5217 value = component.expression.value;
5218 }
5219
5220 if (!template) throw new Error("couldn't find template " + key);
5221
5222 string += template.replace(/{{value}}/, value);
5223 });
5224
5225 return string;
5226}
5227
5228JSONPath.prototype._normalize = function(path) {
5229
5230 assert.ok(path, "we need a path");
5231
5232 if (typeof path == "string") {
5233
5234 return this.parser.parse(path);
5235
5236 } else if (Array.isArray(path) && typeof path[0] == "string") {
5237
5238 var _path = [ { expression: { type: "root", value: "$" } } ];
5239
5240 path.forEach(function(component, index) {
5241
5242 if (component == '$' && index === 0) return;
5243
5244 if (typeof component == "string" && component.match("^" + dict.identifier + "$")) {
5245 this._assert_safe_key(component);
5246
5247 _path.push({
5248 operation: 'member',
5249 scope: 'child',
5250 expression: { value: component, type: 'identifier' }
5251 });
5252
5253 } else {
5254
5255 var type = typeof component == "number" ?
5256 'numeric_literal' : 'string_literal';
5257
5258 if (type === 'string_literal') this._assert_safe_key(component);
5259
5260 _path.push({
5261 operation: 'subscript',
5262 scope: 'child',
5263 expression: { value: component, type: type }
5264 });
5265 }
5266 }, this);
5267
5268 return _path;
5269
5270 } else if (Array.isArray(path) && typeof path[0] == "object") {
5271
5272 return path
5273 }
5274
5275 throw new Error("couldn't understand path " + path);
5276}
5277
5278JSONPath.prototype._assert_safe_key = function(key) {
5279 if (_is_unsafe_key(key)) {
5280 throw new Error("Unsafe key in JSONPath: " + key);
5281 }
5282}
5283
5284JSONPath.prototype._assert_safe_path_keys = function(path) {
5285 if (!Array.isArray(path)) return;
5286 path.forEach(function(key) {
5287 if (key === '$') return;
5288 if (typeof key === 'string') this._assert_safe_key(key);
5289 }, this);
5290}
5291
5292JSONPath.prototype._assert_safe_components = function(components) {
5293 var self = this;
5294 if (!Array.isArray(components)) return;
5295
5296 var checkExpression = function(expression) {
5297 if (!expression) return;
5298 if (expression.type === 'identifier' || expression.type === 'string_literal') {
5299 self._assert_safe_key(expression.value);
5300 return;
5301 }
5302
5303 if (expression.type === 'union' && Array.isArray(expression.value)) {
5304 expression.value.forEach(function(component) {
5305 if (component && component.expression) {
5306 checkExpression(component.expression);
5307 }
5308 });
5309 }
5310 };
5311
5312 components.forEach(function(component) {
5313 if (component && component.expression) {
5314 checkExpression(component.expression);
5315 }
5316 });
5317}
5318
5319function _is_string(obj) {
5320 return Object.prototype.toString.call(obj) == '[object String]';
5321}
5322
5323function _is_unsafe_key(key) {
5324 return key === '__proto__' || key === 'prototype' || key === 'constructor';
5325}
5326
5327JSONPath.Handlers = Handlers;
5328JSONPath.Parser = Parser;
5329
5330var instance = new JSONPath;
5331instance.JSONPath = JSONPath;
5332
5333module.exports = instance;
5334
5335},{"./dict":2,"./handlers":4,"./parser":6,"assert":8}],6:[function(require,module,exports){
5336var grammar = require('./grammar');
5337var gparser = require('../generated/parser');
5338
5339var Parser = function() {
5340
5341 var parser = new gparser.Parser();
5342
5343 var _parseError = parser.parseError;
5344 parser.yy.parseError = function() {
5345 if (parser.yy.ast) {
5346 parser.yy.ast.initialize();
5347 }
5348 _parseError.apply(parser, arguments);
5349 }
5350
5351 return parser;
5352
5353};
5354
5355Parser.grammar = grammar;
5356module.exports = Parser;
5357
5358},{"../generated/parser":1,"./grammar":3}],7:[function(require,module,exports){
5359module.exports = function(arr, start, end, step) {
5360
5361 if (typeof start == 'string') throw new Error("start cannot be a string");
5362 if (typeof end == 'string') throw new Error("end cannot be a string");
5363 if (typeof step == 'string') throw new Error("step cannot be a string");
5364
5365 var len = arr.length;
5366
5367 if (step === 0) throw new Error("step cannot be zero");
5368 step = step ? integer(step) : 1;
5369
5370 // normalize negative values
5371 start = start < 0 ? len + start : start;
5372 end = end < 0 ? len + end : end;
5373
5374 // default extents to extents
5375 start = integer(start === 0 ? 0 : !start ? (step > 0 ? 0 : len - 1) : start);
5376 end = integer(end === 0 ? 0 : !end ? (step > 0 ? len : -1) : end);
5377
5378 // clamp extents
5379 start = step > 0 ? Math.max(0, start) : Math.min(len, start);
5380 end = step > 0 ? Math.min(end, len) : Math.max(-1, end);
5381
5382 // return empty if extents are backwards
5383 if (step > 0 && end <= start) return [];
5384 if (step < 0 && start <= end) return [];
5385
5386 var result = [];
5387
5388 for (var i = start; i != end; i += step) {
5389 if ((step < 0 && i <= end) || (step > 0 && i >= end)) break;
5390 result.push(arr[i]);
5391 }
5392
5393 return result;
5394}
5395
5396function integer(val) {
5397 return String(val).match(/^[0-9]+$/) ? parseInt(val) :
5398 Number.isFinite(val) ? parseInt(val, 10) : 0;
5399}
5400
5401},{}],8:[function(require,module,exports){
5402// http://wiki.commonjs.org/wiki/Unit_Testing/1.0
5403//
5404// THIS IS NOT TESTED NOR LIKELY TO WORK OUTSIDE V8!
5405//
5406// Originally from narwhal.js (http://narwhaljs.org)
5407// Copyright (c) 2009 Thomas Robinson <280north.com>
5408//
5409// Permission is hereby granted, free of charge, to any person obtaining a copy
5410// of this software and associated documentation files (the 'Software'), to
5411// deal in the Software without restriction, including without limitation the
5412// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
5413// sell copies of the Software, and to permit persons to whom the Software is
5414// furnished to do so, subject to the following conditions:
5415//
5416// The above copyright notice and this permission notice shall be included in
5417// all copies or substantial portions of the Software.
5418//
5419// THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
5420// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
5421// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
5422// AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
5423// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
5424// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
5425
5426// when used in node, this will actually load the util module we depend on
5427// versus loading the builtin util module as happens otherwise
5428// this is a bug in node module loading as far as I am concerned
5429var util = require('util/');
5430
5431var pSlice = Array.prototype.slice;
5432var hasOwn = Object.prototype.hasOwnProperty;
5433
5434// 1. The assert module provides functions that throw
5435// AssertionError's when particular conditions are not met. The
5436// assert module must conform to the following interface.
5437
5438var assert = module.exports = ok;
5439
5440// 2. The AssertionError is defined in assert.
5441// new assert.AssertionError({ message: message,
5442// actual: actual,
5443// expected: expected })
5444
5445assert.AssertionError = function AssertionError(options) {
5446 this.name = 'AssertionError';
5447 this.actual = options.actual;
5448 this.expected = options.expected;
5449 this.operator = options.operator;
5450 if (options.message) {
5451 this.message = options.message;
5452 this.generatedMessage = false;
5453 } else {
5454 this.message = getMessage(this);
5455 this.generatedMessage = true;
5456 }
5457 var stackStartFunction = options.stackStartFunction || fail;
5458
5459 if (Error.captureStackTrace) {
5460 Error.captureStackTrace(this, stackStartFunction);
5461 }
5462 else {
5463 // non v8 browsers so we can have a stacktrace
5464 var err = new Error();
5465 if (err.stack) {
5466 var out = err.stack;
5467
5468 // try to strip useless frames
5469 var fn_name = stackStartFunction.name;
5470 var idx = out.indexOf('\n' + fn_name);
5471 if (idx >= 0) {
5472 // once we have located the function frame
5473 // we need to strip out everything before it (and its line)
5474 var next_line = out.indexOf('\n', idx + 1);
5475 out = out.substring(next_line + 1);
5476 }
5477
5478 this.stack = out;
5479 }
5480 }
5481};
5482
5483// assert.AssertionError instanceof Error
5484util.inherits(assert.AssertionError, Error);
5485
5486function replacer(key, value) {
5487 if (util.isUndefined(value)) {
5488 return '' + value;
5489 }
5490 if (util.isNumber(value) && !isFinite(value)) {
5491 return value.toString();
5492 }
5493 if (util.isFunction(value) || util.isRegExp(value)) {
5494 return value.toString();
5495 }
5496 return value;
5497}
5498
5499function truncate(s, n) {
5500 if (util.isString(s)) {
5501 return s.length < n ? s : s.slice(0, n);
5502 } else {
5503 return s;
5504 }
5505}
5506
5507function getMessage(self) {
5508 return truncate(JSON.stringify(self.actual, replacer), 128) + ' ' +
5509 self.operator + ' ' +
5510 truncate(JSON.stringify(self.expected, replacer), 128);
5511}
5512
5513// At present only the three keys mentioned above are used and
5514// understood by the spec. Implementations or sub modules can pass
5515// other keys to the AssertionError's constructor - they will be
5516// ignored.
5517
5518// 3. All of the following functions must throw an AssertionError
5519// when a corresponding condition is not met, with a message that
5520// may be undefined if not provided. All assertion methods provide
5521// both the actual and expected values to the assertion error for
5522// display purposes.
5523
5524function fail(actual, expected, message, operator, stackStartFunction) {
5525 throw new assert.AssertionError({
5526 message: message,
5527 actual: actual,
5528 expected: expected,
5529 operator: operator,
5530 stackStartFunction: stackStartFunction
5531 });
5532}
5533
5534// EXTENSION! allows for well behaved errors defined elsewhere.
5535assert.fail = fail;
5536
5537// 4. Pure assertion tests whether a value is truthy, as determined
5538// by !!guard.
5539// assert.ok(guard, message_opt);
5540// This statement is equivalent to assert.equal(true, !!guard,
5541// message_opt);. To test strictly for the value true, use
5542// assert.strictEqual(true, guard, message_opt);.
5543
5544function ok(value, message) {
5545 if (!value) fail(value, true, message, '==', assert.ok);
5546}
5547assert.ok = ok;
5548
5549// 5. The equality assertion tests shallow, coercive equality with
5550// ==.
5551// assert.equal(actual, expected, message_opt);
5552
5553assert.equal = function equal(actual, expected, message) {
5554 if (actual != expected) fail(actual, expected, message, '==', assert.equal);
5555};
5556
5557// 6. The non-equality assertion tests for whether two objects are not equal
5558// with != assert.notEqual(actual, expected, message_opt);
5559
5560assert.notEqual = function notEqual(actual, expected, message) {
5561 if (actual == expected) {
5562 fail(actual, expected, message, '!=', assert.notEqual);
5563 }
5564};
5565
5566// 7. The equivalence assertion tests a deep equality relation.
5567// assert.deepEqual(actual, expected, message_opt);
5568
5569assert.deepEqual = function deepEqual(actual, expected, message) {
5570 if (!_deepEqual(actual, expected)) {
5571 fail(actual, expected, message, 'deepEqual', assert.deepEqual);
5572 }
5573};
5574
5575function _deepEqual(actual, expected) {
5576 // 7.1. All identical values are equivalent, as determined by ===.
5577 if (actual === expected) {
5578 return true;
5579
5580 } else if (util.isBuffer(actual) && util.isBuffer(expected)) {
5581 if (actual.length != expected.length) return false;
5582
5583 for (var i = 0; i < actual.length; i++) {
5584 if (actual[i] !== expected[i]) return false;
5585 }
5586
5587 return true;
5588
5589 // 7.2. If the expected value is a Date object, the actual value is
5590 // equivalent if it is also a Date object that refers to the same time.
5591 } else if (util.isDate(actual) && util.isDate(expected)) {
5592 return actual.getTime() === expected.getTime();
5593
5594 // 7.3 If the expected value is a RegExp object, the actual value is
5595 // equivalent if it is also a RegExp object with the same source and
5596 // properties (`global`, `multiline`, `lastIndex`, `ignoreCase`).
5597 } else if (util.isRegExp(actual) && util.isRegExp(expected)) {
5598 return actual.source === expected.source &&
5599 actual.global === expected.global &&
5600 actual.multiline === expected.multiline &&
5601 actual.lastIndex === expected.lastIndex &&
5602 actual.ignoreCase === expected.ignoreCase;
5603
5604 // 7.4. Other pairs that do not both pass typeof value == 'object',
5605 // equivalence is determined by ==.
5606 } else if (!util.isObject(actual) && !util.isObject(expected)) {
5607 return actual == expected;
5608
5609 // 7.5 For all other Object pairs, including Array objects, equivalence is
5610 // determined by having the same number of owned properties (as verified
5611 // with Object.prototype.hasOwnProperty.call), the same set of keys
5612 // (although not necessarily the same order), equivalent values for every
5613 // corresponding key, and an identical 'prototype' property. Note: this
5614 // accounts for both named and indexed properties on Arrays.
5615 } else {
5616 return objEquiv(actual, expected);
5617 }
5618}
5619
5620function isArguments(object) {
5621 return Object.prototype.toString.call(object) == '[object Arguments]';
5622}
5623
5624function objEquiv(a, b) {
5625 if (util.isNullOrUndefined(a) || util.isNullOrUndefined(b))
5626 return false;
5627 // an identical 'prototype' property.
5628 if (a.prototype !== b.prototype) return false;
5629 // if one is a primitive, the other must be same
5630 if (util.isPrimitive(a) || util.isPrimitive(b)) {
5631 return a === b;
5632 }
5633 var aIsArgs = isArguments(a),
5634 bIsArgs = isArguments(b);
5635 if ((aIsArgs && !bIsArgs) || (!aIsArgs && bIsArgs))
5636 return false;
5637 if (aIsArgs) {
5638 a = pSlice.call(a);
5639 b = pSlice.call(b);
5640 return _deepEqual(a, b);
5641 }
5642 var ka = objectKeys(a),
5643 kb = objectKeys(b),
5644 key, i;
5645 // having the same number of owned properties (keys incorporates
5646 // hasOwnProperty)
5647 if (ka.length != kb.length)
5648 return false;
5649 //the same set of keys (although not necessarily the same order),
5650 ka.sort();
5651 kb.sort();
5652 //~~~cheap key test
5653 for (i = ka.length - 1; i >= 0; i--) {
5654 if (ka[i] != kb[i])
5655 return false;
5656 }
5657 //equivalent values for every corresponding key, and
5658 //~~~possibly expensive deep test
5659 for (i = ka.length - 1; i >= 0; i--) {
5660 key = ka[i];
5661 if (!_deepEqual(a[key], b[key])) return false;
5662 }
5663 return true;
5664}
5665
5666// 8. The non-equivalence assertion tests for any deep inequality.
5667// assert.notDeepEqual(actual, expected, message_opt);
5668
5669assert.notDeepEqual = function notDeepEqual(actual, expected, message) {
5670 if (_deepEqual(actual, expected)) {
5671 fail(actual, expected, message, 'notDeepEqual', assert.notDeepEqual);
5672 }
5673};
5674
5675// 9. The strict equality assertion tests strict equality, as determined by ===.
5676// assert.strictEqual(actual, expected, message_opt);
5677
5678assert.strictEqual = function strictEqual(actual, expected, message) {
5679 if (actual !== expected) {
5680 fail(actual, expected, message, '===', assert.strictEqual);
5681 }
5682};
5683
5684// 10. The strict non-equality assertion tests for strict inequality, as
5685// determined by !==. assert.notStrictEqual(actual, expected, message_opt);
5686
5687assert.notStrictEqual = function notStrictEqual(actual, expected, message) {
5688 if (actual === expected) {
5689 fail(actual, expected, message, '!==', assert.notStrictEqual);
5690 }
5691};
5692
5693function expectedException(actual, expected) {
5694 if (!actual || !expected) {
5695 return false;
5696 }
5697
5698 if (Object.prototype.toString.call(expected) == '[object RegExp]') {
5699 return expected.test(actual);
5700 } else if (actual instanceof expected) {
5701 return true;
5702 } else if (expected.call({}, actual) === true) {
5703 return true;
5704 }
5705
5706 return false;
5707}
5708
5709function _throws(shouldThrow, block, expected, message) {
5710 var actual;
5711
5712 if (util.isString(expected)) {
5713 message = expected;
5714 expected = null;
5715 }
5716
5717 try {
5718 block();
5719 } catch (e) {
5720 actual = e;
5721 }
5722
5723 message = (expected && expected.name ? ' (' + expected.name + ').' : '.') +
5724 (message ? ' ' + message : '.');
5725
5726 if (shouldThrow && !actual) {
5727 fail(actual, expected, 'Missing expected exception' + message);
5728 }
5729
5730 if (!shouldThrow && expectedException(actual, expected)) {
5731 fail(actual, expected, 'Got unwanted exception' + message);
5732 }
5733
5734 if ((shouldThrow && actual && expected &&
5735 !expectedException(actual, expected)) || (!shouldThrow && actual)) {
5736 throw actual;
5737 }
5738}
5739
5740// 11. Expected to throw an error:
5741// assert.throws(block, Error_opt, message_opt);
5742
5743assert.throws = function(block, /*optional*/error, /*optional*/message) {
5744 _throws.apply(this, [true].concat(pSlice.call(arguments)));
5745};
5746
5747// EXTENSION! This is annoying to write outside this module.
5748assert.doesNotThrow = function(block, /*optional*/message) {
5749 _throws.apply(this, [false].concat(pSlice.call(arguments)));
5750};
5751
5752assert.ifError = function(err) { if (err) {throw err;}};
5753
5754var objectKeys = Object.keys || function (obj) {
5755 var keys = [];
5756 for (var key in obj) {
5757 if (hasOwn.call(obj, key)) keys.push(key);
5758 }
5759 return keys;
5760};
5761
5762},{"util/":11}],9:[function(require,module,exports){
5763if (typeof Object.create === 'function') {
5764 // implementation from standard node.js 'util' module
5765 module.exports = function inherits(ctor, superCtor) {
5766 ctor.super_ = superCtor
5767 ctor.prototype = Object.create(superCtor.prototype, {
5768 constructor: {
5769 value: ctor,
5770 enumerable: false,
5771 writable: true,
5772 configurable: true
5773 }
5774 });
5775 };
5776} else {
5777 // old school shim for old browsers
5778 module.exports = function inherits(ctor, superCtor) {
5779 ctor.super_ = superCtor
5780 var TempCtor = function () {}
5781 TempCtor.prototype = superCtor.prototype
5782 ctor.prototype = new TempCtor()
5783 ctor.prototype.constructor = ctor
5784 }
5785}
5786
5787},{}],10:[function(require,module,exports){
5788module.exports = function isBuffer(arg) {
5789 return arg && typeof arg === 'object'
5790 && typeof arg.copy === 'function'
5791 && typeof arg.fill === 'function'
5792 && typeof arg.readUInt8 === 'function';
5793}
5794},{}],11:[function(require,module,exports){
5795(function (process,global){
5796// Copyright Joyent, Inc. and other Node contributors.
5797//
5798// Permission is hereby granted, free of charge, to any person obtaining a
5799// copy of this software and associated documentation files (the
5800// "Software"), to deal in the Software without restriction, including
5801// without limitation the rights to use, copy, modify, merge, publish,
5802// distribute, sublicense, and/or sell copies of the Software, and to permit
5803// persons to whom the Software is furnished to do so, subject to the
5804// following conditions:
5805//
5806// The above copyright notice and this permission notice shall be included
5807// in all copies or substantial portions of the Software.
5808//
5809// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
5810// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
5811// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
5812// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
5813// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
5814// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
5815// USE OR OTHER DEALINGS IN THE SOFTWARE.
5816
5817var formatRegExp = /%[sdj%]/g;
5818exports.format = function(f) {
5819 if (!isString(f)) {
5820 var objects = [];
5821 for (var i = 0; i < arguments.length; i++) {
5822 objects.push(inspect(arguments[i]));
5823 }
5824 return objects.join(' ');
5825 }
5826
5827 var i = 1;
5828 var args = arguments;
5829 var len = args.length;
5830 var str = String(f).replace(formatRegExp, function(x) {
5831 if (x === '%%') return '%';
5832 if (i >= len) return x;
5833 switch (x) {
5834 case '%s': return String(args[i++]);
5835 case '%d': return Number(args[i++]);
5836 case '%j':
5837 try {
5838 return JSON.stringify(args[i++]);
5839 } catch (_) {
5840 return '[Circular]';
5841 }
5842 default:
5843 return x;
5844 }
5845 });
5846 for (var x = args[i]; i < len; x = args[++i]) {
5847 if (isNull(x) || !isObject(x)) {
5848 str += ' ' + x;
5849 } else {
5850 str += ' ' + inspect(x);
5851 }
5852 }
5853 return str;
5854};
5855
5856
5857// Mark that a method should not be used.
5858// Returns a modified function which warns once by default.
5859// If --no-deprecation is set, then it is a no-op.
5860exports.deprecate = function(fn, msg) {
5861 // Allow for deprecating things in the process of starting up.
5862 if (isUndefined(global.process)) {
5863 return function() {
5864 return exports.deprecate(fn, msg).apply(this, arguments);
5865 };
5866 }
5867
5868 if (process.noDeprecation === true) {
5869 return fn;
5870 }
5871
5872 var warned = false;
5873 function deprecated() {
5874 if (!warned) {
5875 if (process.throwDeprecation) {
5876 throw new Error(msg);
5877 } else if (process.traceDeprecation) {
5878 console.trace(msg);
5879 } else {
5880 console.error(msg);
5881 }
5882 warned = true;
5883 }
5884 return fn.apply(this, arguments);
5885 }
5886
5887 return deprecated;
5888};
5889
5890
5891var debugs = {};
5892var debugEnviron;
5893exports.debuglog = function(set) {
5894 if (isUndefined(debugEnviron))
5895 debugEnviron = process.env.NODE_DEBUG || '';
5896 set = set.toUpperCase();
5897 if (!debugs[set]) {
5898 if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) {
5899 var pid = process.pid;
5900 debugs[set] = function() {
5901 var msg = exports.format.apply(exports, arguments);
5902 console.error('%s %d: %s', set, pid, msg);
5903 };
5904 } else {
5905 debugs[set] = function() {};
5906 }
5907 }
5908 return debugs[set];
5909};
5910
5911
5912/**
5913 * Echos the value of a value. Trys to print the value out
5914 * in the best way possible given the different types.
5915 *
5916 * @param {Object} obj The object to print out.
5917 * @param {Object} opts Optional options object that alters the output.
5918 */
5919/* legacy: obj, showHidden, depth, colors*/
5920function inspect(obj, opts) {
5921 // default options
5922 var ctx = {
5923 seen: [],
5924 stylize: stylizeNoColor
5925 };
5926 // legacy...
5927 if (arguments.length >= 3) ctx.depth = arguments[2];
5928 if (arguments.length >= 4) ctx.colors = arguments[3];
5929 if (isBoolean(opts)) {
5930 // legacy...
5931 ctx.showHidden = opts;
5932 } else if (opts) {
5933 // got an "options" object
5934 exports._extend(ctx, opts);
5935 }
5936 // set default options
5937 if (isUndefined(ctx.showHidden)) ctx.showHidden = false;
5938 if (isUndefined(ctx.depth)) ctx.depth = 2;
5939 if (isUndefined(ctx.colors)) ctx.colors = false;
5940 if (isUndefined(ctx.customInspect)) ctx.customInspect = true;
5941 if (ctx.colors) ctx.stylize = stylizeWithColor;
5942 return formatValue(ctx, obj, ctx.depth);
5943}
5944exports.inspect = inspect;
5945
5946
5947// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics
5948inspect.colors = {
5949 'bold' : [1, 22],
5950 'italic' : [3, 23],
5951 'underline' : [4, 24],
5952 'inverse' : [7, 27],
5953 'white' : [37, 39],
5954 'grey' : [90, 39],
5955 'black' : [30, 39],
5956 'blue' : [34, 39],
5957 'cyan' : [36, 39],
5958 'green' : [32, 39],
5959 'magenta' : [35, 39],
5960 'red' : [31, 39],
5961 'yellow' : [33, 39]
5962};
5963
5964// Don't use 'blue' not visible on cmd.exe
5965inspect.styles = {
5966 'special': 'cyan',
5967 'number': 'yellow',
5968 'boolean': 'yellow',
5969 'undefined': 'grey',
5970 'null': 'bold',
5971 'string': 'green',
5972 'date': 'magenta',
5973 // "name": intentionally not styling
5974 'regexp': 'red'
5975};
5976
5977
5978function stylizeWithColor(str, styleType) {
5979 var style = inspect.styles[styleType];
5980
5981 if (style) {
5982 return '\u001b[' + inspect.colors[style][0] + 'm' + str +
5983 '\u001b[' + inspect.colors[style][1] + 'm';
5984 } else {
5985 return str;
5986 }
5987}
5988
5989
5990function stylizeNoColor(str, styleType) {
5991 return str;
5992}
5993
5994
5995function arrayToHash(array) {
5996 var hash = {};
5997
5998 array.forEach(function(val, idx) {
5999 hash[val] = true;
6000 });
6001
6002 return hash;
6003}
6004
6005
6006function formatValue(ctx, value, recurseTimes) {
6007 // Provide a hook for user-specified inspect functions.
6008 // Check that value is an object with an inspect function on it
6009 if (ctx.customInspect &&
6010 value &&
6011 isFunction(value.inspect) &&
6012 // Filter out the util module, it's inspect function is special
6013 value.inspect !== exports.inspect &&
6014 // Also filter out any prototype objects using the circular check.
6015 !(value.constructor && value.constructor.prototype === value)) {
6016 var ret = value.inspect(recurseTimes, ctx);
6017 if (!isString(ret)) {
6018 ret = formatValue(ctx, ret, recurseTimes);
6019 }
6020 return ret;
6021 }
6022
6023 // Primitive types cannot have properties
6024 var primitive = formatPrimitive(ctx, value);
6025 if (primitive) {
6026 return primitive;
6027 }
6028
6029 // Look up the keys of the object.
6030 var keys = Object.keys(value);
6031 var visibleKeys = arrayToHash(keys);
6032
6033 if (ctx.showHidden) {
6034 keys = Object.getOwnPropertyNames(value);
6035 }
6036
6037 // IE doesn't make error fields non-enumerable
6038 // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx
6039 if (isError(value)
6040 && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) {
6041 return formatError(value);
6042 }
6043
6044 // Some type of object without properties can be shortcutted.
6045 if (keys.length === 0) {
6046 if (isFunction(value)) {
6047 var name = value.name ? ': ' + value.name : '';
6048 return ctx.stylize('[Function' + name + ']', 'special');
6049 }
6050 if (isRegExp(value)) {
6051 return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
6052 }
6053 if (isDate(value)) {
6054 return ctx.stylize(Date.prototype.toString.call(value), 'date');
6055 }
6056 if (isError(value)) {
6057 return formatError(value);
6058 }
6059 }
6060
6061 var base = '', array = false, braces = ['{', '}'];
6062
6063 // Make Array say that they are Array
6064 if (isArray(value)) {
6065 array = true;
6066 braces = ['[', ']'];
6067 }
6068
6069 // Make functions say that they are functions
6070 if (isFunction(value)) {
6071 var n = value.name ? ': ' + value.name : '';
6072 base = ' [Function' + n + ']';
6073 }
6074
6075 // Make RegExps say that they are RegExps
6076 if (isRegExp(value)) {
6077 base = ' ' + RegExp.prototype.toString.call(value);
6078 }
6079
6080 // Make dates with properties first say the date
6081 if (isDate(value)) {
6082 base = ' ' + Date.prototype.toUTCString.call(value);
6083 }
6084
6085 // Make error with message first say the error
6086 if (isError(value)) {
6087 base = ' ' + formatError(value);
6088 }
6089
6090 if (keys.length === 0 && (!array || value.length == 0)) {
6091 return braces[0] + base + braces[1];
6092 }
6093
6094 if (recurseTimes < 0) {
6095 if (isRegExp(value)) {
6096 return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
6097 } else {
6098 return ctx.stylize('[Object]', 'special');
6099 }
6100 }
6101
6102 ctx.seen.push(value);
6103
6104 var output;
6105 if (array) {
6106 output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);
6107 } else {
6108 output = keys.map(function(key) {
6109 return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);
6110 });
6111 }
6112
6113 ctx.seen.pop();
6114
6115 return reduceToSingleString(output, base, braces);
6116}
6117
6118
6119function formatPrimitive(ctx, value) {
6120 if (isUndefined(value))
6121 return ctx.stylize('undefined', 'undefined');
6122 if (isString(value)) {
6123 var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '')
6124 .replace(/'/g, "\\'")
6125 .replace(/\\"/g, '"') + '\'';
6126 return ctx.stylize(simple, 'string');
6127 }
6128 if (isNumber(value))
6129 return ctx.stylize('' + value, 'number');
6130 if (isBoolean(value))
6131 return ctx.stylize('' + value, 'boolean');
6132 // For some reason typeof null is "object", so special case here.
6133 if (isNull(value))
6134 return ctx.stylize('null', 'null');
6135}
6136
6137
6138function formatError(value) {
6139 return '[' + Error.prototype.toString.call(value) + ']';
6140}
6141
6142
6143function formatArray(ctx, value, recurseTimes, visibleKeys, keys) {
6144 var output = [];
6145 for (var i = 0, l = value.length; i < l; ++i) {
6146 if (hasOwnProperty(value, String(i))) {
6147 output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
6148 String(i), true));
6149 } else {
6150 output.push('');
6151 }
6152 }
6153 keys.forEach(function(key) {
6154 if (!key.match(/^\d+$/)) {
6155 output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
6156 key, true));
6157 }
6158 });
6159 return output;
6160}
6161
6162
6163function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {
6164 var name, str, desc;
6165 desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] };
6166 if (desc.get) {
6167 if (desc.set) {
6168 str = ctx.stylize('[Getter/Setter]', 'special');
6169 } else {
6170 str = ctx.stylize('[Getter]', 'special');
6171 }
6172 } else {
6173 if (desc.set) {
6174 str = ctx.stylize('[Setter]', 'special');
6175 }
6176 }
6177 if (!hasOwnProperty(visibleKeys, key)) {
6178 name = '[' + key + ']';
6179 }
6180 if (!str) {
6181 if (ctx.seen.indexOf(desc.value) < 0) {
6182 if (isNull(recurseTimes)) {
6183 str = formatValue(ctx, desc.value, null);
6184 } else {
6185 str = formatValue(ctx, desc.value, recurseTimes - 1);
6186 }
6187 if (str.indexOf('\n') > -1) {
6188 if (array) {
6189 str = str.split('\n').map(function(line) {
6190 return ' ' + line;
6191 }).join('\n').substr(2);
6192 } else {
6193 str = '\n' + str.split('\n').map(function(line) {
6194 return ' ' + line;
6195 }).join('\n');
6196 }
6197 }
6198 } else {
6199 str = ctx.stylize('[Circular]', 'special');
6200 }
6201 }
6202 if (isUndefined(name)) {
6203 if (array && key.match(/^\d+$/)) {
6204 return str;
6205 }
6206 name = JSON.stringify('' + key);
6207 if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) {
6208 name = name.substr(1, name.length - 2);
6209 name = ctx.stylize(name, 'name');
6210 } else {
6211 name = name.replace(/'/g, "\\'")
6212 .replace(/\\"/g, '"')
6213 .replace(/(^"|"$)/g, "'");
6214 name = ctx.stylize(name, 'string');
6215 }
6216 }
6217
6218 return name + ': ' + str;
6219}
6220
6221
6222function reduceToSingleString(output, base, braces) {
6223 var numLinesEst = 0;
6224 var length = output.reduce(function(prev, cur) {
6225 numLinesEst++;
6226 if (cur.indexOf('\n') >= 0) numLinesEst++;
6227 return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1;
6228 }, 0);
6229
6230 if (length > 60) {
6231 return braces[0] +
6232 (base === '' ? '' : base + '\n ') +
6233 ' ' +
6234 output.join(',\n ') +
6235 ' ' +
6236 braces[1];
6237 }
6238
6239 return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];
6240}
6241
6242
6243// NOTE: These type checking functions intentionally don't use `instanceof`
6244// because it is fragile and can be easily faked with `Object.create()`.
6245function isArray(ar) {
6246 return Array.isArray(ar);
6247}
6248exports.isArray = isArray;
6249
6250function isBoolean(arg) {
6251 return typeof arg === 'boolean';
6252}
6253exports.isBoolean = isBoolean;
6254
6255function isNull(arg) {
6256 return arg === null;
6257}
6258exports.isNull = isNull;
6259
6260function isNullOrUndefined(arg) {
6261 return arg == null;
6262}
6263exports.isNullOrUndefined = isNullOrUndefined;
6264
6265function isNumber(arg) {
6266 return typeof arg === 'number';
6267}
6268exports.isNumber = isNumber;
6269
6270function isString(arg) {
6271 return typeof arg === 'string';
6272}
6273exports.isString = isString;
6274
6275function isSymbol(arg) {
6276 return typeof arg === 'symbol';
6277}
6278exports.isSymbol = isSymbol;
6279
6280function isUndefined(arg) {
6281 return arg === void 0;
6282}
6283exports.isUndefined = isUndefined;
6284
6285function isRegExp(re) {
6286 return isObject(re) && objectToString(re) === '[object RegExp]';
6287}
6288exports.isRegExp = isRegExp;
6289
6290function isObject(arg) {
6291 return typeof arg === 'object' && arg !== null;
6292}
6293exports.isObject = isObject;
6294
6295function isDate(d) {
6296 return isObject(d) && objectToString(d) === '[object Date]';
6297}
6298exports.isDate = isDate;
6299
6300function isError(e) {
6301 return isObject(e) &&
6302 (objectToString(e) === '[object Error]' || e instanceof Error);
6303}
6304exports.isError = isError;
6305
6306function isFunction(arg) {
6307 return typeof arg === 'function';
6308}
6309exports.isFunction = isFunction;
6310
6311function isPrimitive(arg) {
6312 return arg === null ||
6313 typeof arg === 'boolean' ||
6314 typeof arg === 'number' ||
6315 typeof arg === 'string' ||
6316 typeof arg === 'symbol' || // ES6 symbol
6317 typeof arg === 'undefined';
6318}
6319exports.isPrimitive = isPrimitive;
6320
6321exports.isBuffer = require('./support/isBuffer');
6322
6323function objectToString(o) {
6324 return Object.prototype.toString.call(o);
6325}
6326
6327
6328function pad(n) {
6329 return n < 10 ? '0' + n.toString(10) : n.toString(10);
6330}
6331
6332
6333var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep',
6334 'Oct', 'Nov', 'Dec'];
6335
6336// 26 Feb 16:19:34
6337function timestamp() {
6338 var d = new Date();
6339 var time = [pad(d.getHours()),
6340 pad(d.getMinutes()),
6341 pad(d.getSeconds())].join(':');
6342 return [d.getDate(), months[d.getMonth()], time].join(' ');
6343}
6344
6345
6346// log is just a thin wrapper to console.log that prepends a timestamp
6347exports.log = function() {
6348 console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments));
6349};
6350
6351
6352/**
6353 * Inherit the prototype methods from one constructor into another.
6354 *
6355 * The Function.prototype.inherits from lang.js rewritten as a standalone
6356 * function (not on Function.prototype). NOTE: If this file is to be loaded
6357 * during bootstrapping this function needs to be rewritten using some native
6358 * functions as prototype setup using normal JavaScript does not work as
6359 * expected during bootstrapping (see mirror.js in r114903).
6360 *
6361 * @param {function} ctor Constructor function which needs to inherit the
6362 * prototype.
6363 * @param {function} superCtor Constructor function to inherit prototype from.
6364 */
6365exports.inherits = require('inherits');
6366
6367exports._extend = function(origin, add) {
6368 // Don't do anything if add isn't an object
6369 if (!add || !isObject(add)) return origin;
6370
6371 var keys = Object.keys(add);
6372 var i = keys.length;
6373 while (i--) {
6374 origin[keys[i]] = add[keys[i]];
6375 }
6376 return origin;
6377};
6378
6379function hasOwnProperty(obj, prop) {
6380 return Object.prototype.hasOwnProperty.call(obj, prop);
6381}
6382
6383}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
6384},{"./support/isBuffer":10,"_process":14,"inherits":9}],12:[function(require,module,exports){
6385
6386},{}],13:[function(require,module,exports){
6387(function (process){
6388// .dirname, .basename, and .extname methods are extracted from Node.js v8.11.1,
6389// backported and transplited with Babel, with backwards-compat fixes
6390
6391// Copyright Joyent, Inc. and other Node contributors.
6392//
6393// Permission is hereby granted, free of charge, to any person obtaining a
6394// copy of this software and associated documentation files (the
6395// "Software"), to deal in the Software without restriction, including
6396// without limitation the rights to use, copy, modify, merge, publish,
6397// distribute, sublicense, and/or sell copies of the Software, and to permit
6398// persons to whom the Software is furnished to do so, subject to the
6399// following conditions:
6400//
6401// The above copyright notice and this permission notice shall be included
6402// in all copies or substantial portions of the Software.
6403//
6404// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
6405// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
6406// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
6407// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
6408// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
6409// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
6410// USE OR OTHER DEALINGS IN THE SOFTWARE.
6411
6412// resolves . and .. elements in a path array with directory names there
6413// must be no slashes, empty elements, or device names (c:\) in the array
6414// (so also no leading and trailing slashes - it does not distinguish
6415// relative and absolute paths)
6416function normalizeArray(parts, allowAboveRoot) {
6417 // if the path tries to go above the root, `up` ends up > 0
6418 var up = 0;
6419 for (var i = parts.length - 1; i >= 0; i--) {
6420 var last = parts[i];
6421 if (last === '.') {
6422 parts.splice(i, 1);
6423 } else if (last === '..') {
6424 parts.splice(i, 1);
6425 up++;
6426 } else if (up) {
6427 parts.splice(i, 1);
6428 up--;
6429 }
6430 }
6431
6432 // if the path is allowed to go above the root, restore leading ..s
6433 if (allowAboveRoot) {
6434 for (; up--; up) {
6435 parts.unshift('..');
6436 }
6437 }
6438
6439 return parts;
6440}
6441
6442// path.resolve([from ...], to)
6443// posix version
6444exports.resolve = function() {
6445 var resolvedPath = '',
6446 resolvedAbsolute = false;
6447
6448 for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) {
6449 var path = (i >= 0) ? arguments[i] : process.cwd();
6450
6451 // Skip empty and invalid entries
6452 if (typeof path !== 'string') {
6453 throw new TypeError('Arguments to path.resolve must be strings');
6454 } else if (!path) {
6455 continue;
6456 }
6457
6458 resolvedPath = path + '/' + resolvedPath;
6459 resolvedAbsolute = path.charAt(0) === '/';
6460 }
6461
6462 // At this point the path should be resolved to a full absolute path, but
6463 // handle relative paths to be safe (might happen when process.cwd() fails)
6464
6465 // Normalize the path
6466 resolvedPath = normalizeArray(filter(resolvedPath.split('/'), function(p) {
6467 return !!p;
6468 }), !resolvedAbsolute).join('/');
6469
6470 return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.';
6471};
6472
6473// path.normalize(path)
6474// posix version
6475exports.normalize = function(path) {
6476 var isAbsolute = exports.isAbsolute(path),
6477 trailingSlash = substr(path, -1) === '/';
6478
6479 // Normalize the path
6480 path = normalizeArray(filter(path.split('/'), function(p) {
6481 return !!p;
6482 }), !isAbsolute).join('/');
6483
6484 if (!path && !isAbsolute) {
6485 path = '.';
6486 }
6487 if (path && trailingSlash) {
6488 path += '/';
6489 }
6490
6491 return (isAbsolute ? '/' : '') + path;
6492};
6493
6494// posix version
6495exports.isAbsolute = function(path) {
6496 return path.charAt(0) === '/';
6497};
6498
6499// posix version
6500exports.join = function() {
6501 var paths = Array.prototype.slice.call(arguments, 0);
6502 return exports.normalize(filter(paths, function(p, index) {
6503 if (typeof p !== 'string') {
6504 throw new TypeError('Arguments to path.join must be strings');
6505 }
6506 return p;
6507 }).join('/'));
6508};
6509
6510
6511// path.relative(from, to)
6512// posix version
6513exports.relative = function(from, to) {
6514 from = exports.resolve(from).substr(1);
6515 to = exports.resolve(to).substr(1);
6516
6517 function trim(arr) {
6518 var start = 0;
6519 for (; start < arr.length; start++) {
6520 if (arr[start] !== '') break;
6521 }
6522
6523 var end = arr.length - 1;
6524 for (; end >= 0; end--) {
6525 if (arr[end] !== '') break;
6526 }
6527
6528 if (start > end) return [];
6529 return arr.slice(start, end - start + 1);
6530 }
6531
6532 var fromParts = trim(from.split('/'));
6533 var toParts = trim(to.split('/'));
6534
6535 var length = Math.min(fromParts.length, toParts.length);
6536 var samePartsLength = length;
6537 for (var i = 0; i < length; i++) {
6538 if (fromParts[i] !== toParts[i]) {
6539 samePartsLength = i;
6540 break;
6541 }
6542 }
6543
6544 var outputParts = [];
6545 for (var i = samePartsLength; i < fromParts.length; i++) {
6546 outputParts.push('..');
6547 }
6548
6549 outputParts = outputParts.concat(toParts.slice(samePartsLength));
6550
6551 return outputParts.join('/');
6552};
6553
6554exports.sep = '/';
6555exports.delimiter = ':';
6556
6557exports.dirname = function (path) {
6558 if (typeof path !== 'string') path = path + '';
6559 if (path.length === 0) return '.';
6560 var code = path.charCodeAt(0);
6561 var hasRoot = code === 47 /*/*/;
6562 var end = -1;
6563 var matchedSlash = true;
6564 for (var i = path.length - 1; i >= 1; --i) {
6565 code = path.charCodeAt(i);
6566 if (code === 47 /*/*/) {
6567 if (!matchedSlash) {
6568 end = i;
6569 break;
6570 }
6571 } else {
6572 // We saw the first non-path separator
6573 matchedSlash = false;
6574 }
6575 }
6576
6577 if (end === -1) return hasRoot ? '/' : '.';
6578 if (hasRoot && end === 1) {
6579 // return '//';
6580 // Backwards-compat fix:
6581 return '/';
6582 }
6583 return path.slice(0, end);
6584};
6585
6586function basename(path) {
6587 if (typeof path !== 'string') path = path + '';
6588
6589 var start = 0;
6590 var end = -1;
6591 var matchedSlash = true;
6592 var i;
6593
6594 for (i = path.length - 1; i >= 0; --i) {
6595 if (path.charCodeAt(i) === 47 /*/*/) {
6596 // If we reached a path separator that was not part of a set of path
6597 // separators at the end of the string, stop now
6598 if (!matchedSlash) {
6599 start = i + 1;
6600 break;
6601 }
6602 } else if (end === -1) {
6603 // We saw the first non-path separator, mark this as the end of our
6604 // path component
6605 matchedSlash = false;
6606 end = i + 1;
6607 }
6608 }
6609
6610 if (end === -1) return '';
6611 return path.slice(start, end);
6612}
6613
6614// Uses a mixed approach for backwards-compatibility, as ext behavior changed
6615// in new Node.js versions, so only basename() above is backported here
6616exports.basename = function (path, ext) {
6617 var f = basename(path);
6618 if (ext && f.substr(-1 * ext.length) === ext) {
6619 f = f.substr(0, f.length - ext.length);
6620 }
6621 return f;
6622};
6623
6624exports.extname = function (path) {
6625 if (typeof path !== 'string') path = path + '';
6626 var startDot = -1;
6627 var startPart = 0;
6628 var end = -1;
6629 var matchedSlash = true;
6630 // Track the state of characters (if any) we see before our first dot and
6631 // after any path separator we find
6632 var preDotState = 0;
6633 for (var i = path.length - 1; i >= 0; --i) {
6634 var code = path.charCodeAt(i);
6635 if (code === 47 /*/*/) {
6636 // If we reached a path separator that was not part of a set of path
6637 // separators at the end of the string, stop now
6638 if (!matchedSlash) {
6639 startPart = i + 1;
6640 break;
6641 }
6642 continue;
6643 }
6644 if (end === -1) {
6645 // We saw the first non-path separator, mark this as the end of our
6646 // extension
6647 matchedSlash = false;
6648 end = i + 1;
6649 }
6650 if (code === 46 /*.*/) {
6651 // If this is our first dot, mark it as the start of our extension
6652 if (startDot === -1)
6653 startDot = i;
6654 else if (preDotState !== 1)
6655 preDotState = 1;
6656 } else if (startDot !== -1) {
6657 // We saw a non-dot and non-path separator before our dot, so we should
6658 // have a good chance at having a non-empty extension
6659 preDotState = -1;
6660 }
6661 }
6662
6663 if (startDot === -1 || end === -1 ||
6664 // We saw a non-dot character immediately before the dot
6665 preDotState === 0 ||
6666 // The (right-most) trimmed path component is exactly '..'
6667 preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) {
6668 return '';
6669 }
6670 return path.slice(startDot, end);
6671};
6672
6673function filter (xs, f) {
6674 if (xs.filter) return xs.filter(f);
6675 var res = [];
6676 for (var i = 0; i < xs.length; i++) {
6677 if (f(xs[i], i, xs)) res.push(xs[i]);
6678 }
6679 return res;
6680}
6681
6682// String.prototype.substr - negative index don't work in IE8
6683var substr = 'ab'.substr(-1) === 'b'
6684 ? function (str, start, len) { return str.substr(start, len) }
6685 : function (str, start, len) {
6686 if (start < 0) start = str.length + start;
6687 return str.substr(start, len);
6688 }
6689;
6690
6691}).call(this,require('_process'))
6692},{"_process":14}],14:[function(require,module,exports){
6693// shim for using process in browser
6694var process = module.exports = {};
6695
6696// cached from whatever global is present so that test runners that stub it
6697// don't break things. But we need to wrap it in a try catch in case it is
6698// wrapped in strict mode code which doesn't define any globals. It's inside a
6699// function because try/catches deoptimize in certain engines.
6700
6701var cachedSetTimeout;
6702var cachedClearTimeout;
6703
6704function defaultSetTimout() {
6705 throw new Error('setTimeout has not been defined');
6706}
6707function defaultClearTimeout () {
6708 throw new Error('clearTimeout has not been defined');
6709}
6710(function () {
6711 try {
6712 if (typeof setTimeout === 'function') {
6713 cachedSetTimeout = setTimeout;
6714 } else {
6715 cachedSetTimeout = defaultSetTimout;
6716 }
6717 } catch (e) {
6718 cachedSetTimeout = defaultSetTimout;
6719 }
6720 try {
6721 if (typeof clearTimeout === 'function') {
6722 cachedClearTimeout = clearTimeout;
6723 } else {
6724 cachedClearTimeout = defaultClearTimeout;
6725 }
6726 } catch (e) {
6727 cachedClearTimeout = defaultClearTimeout;
6728 }
6729} ())
6730function runTimeout(fun) {
6731 if (cachedSetTimeout === setTimeout) {
6732 //normal enviroments in sane situations
6733 return setTimeout(fun, 0);
6734 }
6735 // if setTimeout wasn't available but was latter defined
6736 if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {
6737 cachedSetTimeout = setTimeout;
6738 return setTimeout(fun, 0);
6739 }
6740 try {
6741 // when when somebody has screwed with setTimeout but no I.E. maddness
6742 return cachedSetTimeout(fun, 0);
6743 } catch(e){
6744 try {
6745 // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
6746 return cachedSetTimeout.call(null, fun, 0);
6747 } catch(e){
6748 // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error
6749 return cachedSetTimeout.call(this, fun, 0);
6750 }
6751 }
6752
6753
6754}
6755function runClearTimeout(marker) {
6756 if (cachedClearTimeout === clearTimeout) {
6757 //normal enviroments in sane situations
6758 return clearTimeout(marker);
6759 }
6760 // if clearTimeout wasn't available but was latter defined
6761 if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {
6762 cachedClearTimeout = clearTimeout;
6763 return clearTimeout(marker);
6764 }
6765 try {
6766 // when when somebody has screwed with setTimeout but no I.E. maddness
6767 return cachedClearTimeout(marker);
6768 } catch (e){
6769 try {
6770 // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
6771 return cachedClearTimeout.call(null, marker);
6772 } catch (e){
6773 // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.
6774 // Some versions of I.E. have different rules for clearTimeout vs setTimeout
6775 return cachedClearTimeout.call(this, marker);
6776 }
6777 }
6778
6779
6780
6781}
6782var queue = [];
6783var draining = false;
6784var currentQueue;
6785var queueIndex = -1;
6786
6787function cleanUpNextTick() {
6788 if (!draining || !currentQueue) {
6789 return;
6790 }
6791 draining = false;
6792 if (currentQueue.length) {
6793 queue = currentQueue.concat(queue);
6794 } else {
6795 queueIndex = -1;
6796 }
6797 if (queue.length) {
6798 drainQueue();
6799 }
6800}
6801
6802function drainQueue() {
6803 if (draining) {
6804 return;
6805 }
6806 var timeout = runTimeout(cleanUpNextTick);
6807 draining = true;
6808
6809 var len = queue.length;
6810 while(len) {
6811 currentQueue = queue;
6812 queue = [];
6813 while (++queueIndex < len) {
6814 if (currentQueue) {
6815 currentQueue[queueIndex].run();
6816 }
6817 }
6818 queueIndex = -1;
6819 len = queue.length;
6820 }
6821 currentQueue = null;
6822 draining = false;
6823 runClearTimeout(timeout);
6824}
6825
6826process.nextTick = function (fun) {
6827 var args = new Array(arguments.length - 1);
6828 if (arguments.length > 1) {
6829 for (var i = 1; i < arguments.length; i++) {
6830 args[i - 1] = arguments[i];
6831 }
6832 }
6833 queue.push(new Item(fun, args));
6834 if (queue.length === 1 && !draining) {
6835 runTimeout(drainQueue);
6836 }
6837};
6838
6839// v8 likes predictible objects
6840function Item(fun, array) {
6841 this.fun = fun;
6842 this.array = array;
6843}
6844Item.prototype.run = function () {
6845 this.fun.apply(null, this.array);
6846};
6847process.title = 'browser';
6848process.browser = true;
6849process.env = {};
6850process.argv = [];
6851process.version = ''; // empty string to avoid regexp issues
6852process.versions = {};
6853
6854function noop() {}
6855
6856process.on = noop;
6857process.addListener = noop;
6858process.once = noop;
6859process.off = noop;
6860process.removeListener = noop;
6861process.removeAllListeners = noop;
6862process.emit = noop;
6863process.prependListener = noop;
6864process.prependOnceListener = noop;
6865
6866process.listeners = function (name) { return [] }
6867
6868process.binding = function (name) {
6869 throw new Error('process.binding is not supported');
6870};
6871
6872process.cwd = function () { return '/' };
6873process.chdir = function (dir) {
6874 throw new Error('process.chdir is not supported');
6875};
6876process.umask = function() { return 0; };
6877
6878},{}],15:[function(require,module,exports){
6879var unparse = require('escodegen').generate;
6880
6881module.exports = function (ast, vars, opts) {
6882 if(!opts) opts = {};
6883 var rejectAccessToMethodsOnFunctions = !opts.allowAccessToMethodsOnFunctions;
6884
6885 if (!vars) vars = {};
6886 var FAIL = {};
6887
6888 var result = (function walk (node, noExecute) {
6889 if (node.type === 'Literal') {
6890 return node.value;
6891 }
6892 else if (node.type === 'UnaryExpression'){
6893 var val = walk(node.argument, noExecute)
6894 if (node.operator === '+') return +val
6895 if (node.operator === '-') return -val
6896 if (node.operator === '~') return ~val
6897 if (node.operator === '!') return !val
6898 return FAIL
6899 }
6900 else if (node.type === 'ArrayExpression') {
6901 var xs = [];
6902 for (var i = 0, l = node.elements.length; i < l; i++) {
6903 var x = walk(node.elements[i], noExecute);
6904 if (x === FAIL) return FAIL;
6905 xs.push(x);
6906 }
6907 return xs;
6908 }
6909 else if (node.type === 'ObjectExpression') {
6910 var obj = {};
6911 for (var i = 0; i < node.properties.length; i++) {
6912 var prop = node.properties[i];
6913 var value = prop.value === null
6914 ? prop.value
6915 : walk(prop.value, noExecute)
6916 ;
6917 if (value === FAIL) return FAIL;
6918 obj[prop.key.value || prop.key.name] = value;
6919 }
6920 return obj;
6921 }
6922 else if (node.type === 'BinaryExpression' ||
6923 node.type === 'LogicalExpression') {
6924 var op = node.operator;
6925
6926 if (op === '&&') {
6927 var l = walk(node.left);
6928 if (l === FAIL) return FAIL;
6929 if (!l) return l;
6930 var r = walk(node.right);
6931 if (r === FAIL) return FAIL;
6932 return r;
6933 }
6934 else if (op === '||') {
6935 var l = walk(node.left);
6936 if (l === FAIL) return FAIL;
6937 if (l) return l;
6938 var r = walk(node.right);
6939 if (r === FAIL) return FAIL;
6940 return r;
6941 }
6942
6943 var l = walk(node.left, noExecute);
6944 if (l === FAIL) return FAIL;
6945 var r = walk(node.right, noExecute);
6946 if (r === FAIL) return FAIL;
6947
6948 if (op === '==') return l == r;
6949 if (op === '===') return l === r;
6950 if (op === '!=') return l != r;
6951 if (op === '!==') return l !== r;
6952 if (op === '+') return l + r;
6953 if (op === '-') return l - r;
6954 if (op === '*') return l * r;
6955 if (op === '/') return l / r;
6956 if (op === '%') return l % r;
6957 if (op === '<') return l < r;
6958 if (op === '<=') return l <= r;
6959 if (op === '>') return l > r;
6960 if (op === '>=') return l >= r;
6961 if (op === '|') return l | r;
6962 if (op === '&') return l & r;
6963 if (op === '^') return l ^ r;
6964
6965 return FAIL;
6966 }
6967 else if (node.type === 'Identifier') {
6968 if ({}.hasOwnProperty.call(vars, node.name)) {
6969 return vars[node.name];
6970 }
6971 else return FAIL;
6972 }
6973 else if (node.type === 'ThisExpression') {
6974 if ({}.hasOwnProperty.call(vars, 'this')) {
6975 return vars['this'];
6976 }
6977 else return FAIL;
6978 }
6979 else if (node.type === 'CallExpression') {
6980 var callee = walk(node.callee, noExecute);
6981 if (callee === FAIL) return FAIL;
6982 if (typeof callee !== 'function') return FAIL;
6983
6984
6985 var ctx = node.callee.object ? walk(node.callee.object, noExecute) : FAIL;
6986 if (ctx === FAIL) ctx = null;
6987
6988 var args = [];
6989 for (var i = 0, l = node.arguments.length; i < l; i++) {
6990 var x = walk(node.arguments[i], noExecute);
6991 if (x === FAIL) return FAIL;
6992 args.push(x);
6993 }
6994
6995 if (noExecute) {
6996 return undefined;
6997 }
6998
6999 return callee.apply(ctx, args);
7000 }
7001 else if (node.type === 'MemberExpression') {
7002 var obj = walk(node.object, noExecute);
7003 if((obj === FAIL) || (
7004 (typeof obj == 'function') && rejectAccessToMethodsOnFunctions
7005 )){
7006 return FAIL;
7007 }
7008 if (node.property.type === 'Identifier' && !node.computed) {
7009 if (isUnsafeProperty(node.property.name)) return FAIL;
7010 return obj[node.property.name];
7011 }
7012 var prop = walk(node.property, noExecute);
7013 if (prop === null || prop === FAIL) return FAIL;
7014 if (isUnsafeProperty(prop)) return FAIL;
7015 return obj[prop];
7016 }
7017 else if (node.type === 'ConditionalExpression') {
7018 var val = walk(node.test, noExecute)
7019 if (val === FAIL) return FAIL;
7020 return val ? walk(node.consequent) : walk(node.alternate, noExecute)
7021 }
7022 else if (node.type === 'ExpressionStatement') {
7023 var val = walk(node.expression, noExecute)
7024 if (val === FAIL) return FAIL;
7025 return val;
7026 }
7027 else if (node.type === 'ReturnStatement') {
7028 return walk(node.argument, noExecute)
7029 }
7030 else if (node.type === 'FunctionExpression') {
7031 var bodies = node.body.body;
7032
7033 // Create a "scope" for our arguments
7034 var oldVars = {};
7035 Object.keys(vars).forEach(function(element){
7036 oldVars[element] = vars[element];
7037 })
7038
7039 for(var i=0; i<node.params.length; i++){
7040 var key = node.params[i];
7041 if(key.type == 'Identifier'){
7042 vars[key.name] = null;
7043 }
7044 else return FAIL;
7045 }
7046 for(var i in bodies){
7047 if(walk(bodies[i], true) === FAIL){
7048 return FAIL;
7049 }
7050 }
7051 // restore the vars and scope after we walk
7052 vars = oldVars;
7053
7054 var keys = Object.keys(vars);
7055 var vals = keys.map(function(key) {
7056 return vars[key];
7057 });
7058 return Function(keys.join(', '), 'return ' + unparse(node)).apply(null, vals);
7059 }
7060 else if (node.type === 'TemplateLiteral') {
7061 var str = '';
7062 for (var i = 0; i < node.expressions.length; i++) {
7063 str += walk(node.quasis[i], noExecute);
7064 str += walk(node.expressions[i], noExecute);
7065 }
7066 str += walk(node.quasis[i], noExecute);
7067 return str;
7068 }
7069 else if (node.type === 'TaggedTemplateExpression') {
7070 var tag = walk(node.tag, noExecute);
7071 var quasi = node.quasi;
7072 var strings = quasi.quasis.map(walk);
7073 var values = quasi.expressions.map(walk);
7074 return tag.apply(null, [strings].concat(values));
7075 }
7076 else if (node.type === 'TemplateElement') {
7077 return node.value.cooked;
7078 }
7079 else return FAIL;
7080 })(ast);
7081
7082 return result === FAIL ? undefined : result;
7083};
7084
7085function isUnsafeProperty(name) {
7086 return name === 'constructor' || name === '__proto__';
7087}
7088
7089},{"escodegen":12}],"jsonpath":[function(require,module,exports){
7090module.exports = require('./lib/index');
7091
7092},{"./lib/index":5}]},{},["jsonpath"])("jsonpath")
7093});
Note: See TracBrowser for help on using the repository browser.