MDL-65776 libraries: Upgrade jsbeautify to 1.13
[moodle.git] / lib / editor / atto / plugins / html / yui / src / beautify / js / beautify.js
1 /* AUTO-GENERATED. DO NOT MODIFY. */
2 /*
4   The MIT License (MIT)
6   Copyright (c) 2007-2018 Einar Lielmanis, Liam Newman, and contributors.
8   Permission is hereby granted, free of charge, to any person
9   obtaining a copy of this software and associated documentation files
10   (the "Software"), to deal in the Software without restriction,
11   including without limitation the rights to use, copy, modify, merge,
12   publish, distribute, sublicense, and/or sell copies of the Software,
13   and to permit persons to whom the Software is furnished to do so,
14   subject to the following conditions:
16   The above copyright notice and this permission notice shall be
17   included in all copies or substantial portions of the Software.
19   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
23   BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
24   ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
25   CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26   SOFTWARE.
28  JS Beautifier
29 ---------------
32   Written by Einar Lielmanis, <einar@beautifier.io>
33       https://beautifier.io/
35   Originally converted to javascript by Vital, <vital76@gmail.com>
36   "End braces on own line" added by Chris J. Shull, <chrisjshull@gmail.com>
37   Parsing improvements for brace-less statements by Liam Newman <bitwiseman@beautifier.io>
40   Usage:
41     js_beautify(js_source_text);
42     js_beautify(js_source_text, options);
44   The options are:
45     indent_size (default 4)          - indentation size,
46     indent_char (default space)      - character to indent with,
47     preserve_newlines (default true) - whether existing line breaks should be preserved,
48     max_preserve_newlines (default unlimited) - maximum number of line breaks to be preserved in one chunk,
50     jslint_happy (default false) - if true, then jslint-stricter mode is enforced.
52             jslint_happy        !jslint_happy
53             ---------------------------------
54             function ()         function()
56             switch () {         switch() {
57             case 1:               case 1:
58               break;                break;
59             }                   }
61     space_after_anon_function (default false) - should the space before an anonymous function's parens be added, "function()" vs "function ()",
62           NOTE: This option is overriden by jslint_happy (i.e. if jslint_happy is true, space_after_anon_function is true by design)
64     brace_style (default "collapse") - "collapse" | "expand" | "end-expand" | "none" | any of the former + ",preserve-inline"
65             put braces on the same line as control statements (default), or put braces on own line (Allman / ANSI style), or just put end braces on own line, or attempt to keep them where they are.
66             preserve-inline will try to preserve inline blocks of curly braces
68     space_before_conditional (default true) - should the space before conditional statement be added, "if(true)" vs "if (true)",
70     unescape_strings (default false) - should printable characters in strings encoded in \xNN notation be unescaped, "example" vs "\x65\x78\x61\x6d\x70\x6c\x65"
72     wrap_line_length (default unlimited) - lines should wrap at next opportunity after this number of characters.
73           NOTE: This is not a hard limit. Lines will continue until a point where a newline would
74                 be preserved if it were present.
76     end_with_newline (default false)  - end output with a newline
79     e.g
81     js_beautify(js_source_text, {
82       'indent_size': 1,
83       'indent_char': '\t'
84     });
86 */
88 (function() {
90 /* GENERATED_BUILD_OUTPUT */
91 var legacy_beautify_js =
92 /******/ (function(modules) { // webpackBootstrap
93 /******/        // The module cache
94 /******/        var installedModules = {};
95 /******/
96 /******/        // The require function
97 /******/        function __webpack_require__(moduleId) {
98 /******/
99 /******/                // Check if module is in cache
100 /******/                if(installedModules[moduleId]) {
101 /******/                        return installedModules[moduleId].exports;
102 /******/                }
103 /******/                // Create a new module (and put it into the cache)
104 /******/                var module = installedModules[moduleId] = {
105 /******/                        i: moduleId,
106 /******/                        l: false,
107 /******/                        exports: {}
108 /******/                };
109 /******/
110 /******/                // Execute the module function
111 /******/                modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
112 /******/
113 /******/                // Flag the module as loaded
114 /******/                module.l = true;
115 /******/
116 /******/                // Return the exports of the module
117 /******/                return module.exports;
118 /******/        }
119 /******/
120 /******/
121 /******/        // expose the modules object (__webpack_modules__)
122 /******/        __webpack_require__.m = modules;
123 /******/
124 /******/        // expose the module cache
125 /******/        __webpack_require__.c = installedModules;
126 /******/
127 /******/        // define getter function for harmony exports
128 /******/        __webpack_require__.d = function(exports, name, getter) {
129 /******/                if(!__webpack_require__.o(exports, name)) {
130 /******/                        Object.defineProperty(exports, name, { enumerable: true, get: getter });
131 /******/                }
132 /******/        };
133 /******/
134 /******/        // define __esModule on exports
135 /******/        __webpack_require__.r = function(exports) {
136 /******/                if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
137 /******/                        Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
138 /******/                }
139 /******/                Object.defineProperty(exports, '__esModule', { value: true });
140 /******/        };
141 /******/
142 /******/        // create a fake namespace object
143 /******/        // mode & 1: value is a module id, require it
144 /******/        // mode & 2: merge all properties of value into the ns
145 /******/        // mode & 4: return value when already ns object
146 /******/        // mode & 8|1: behave like require
147 /******/        __webpack_require__.t = function(value, mode) {
148 /******/                if(mode & 1) value = __webpack_require__(value);
149 /******/                if(mode & 8) return value;
150 /******/                if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
151 /******/                var ns = Object.create(null);
152 /******/                __webpack_require__.r(ns);
153 /******/                Object.defineProperty(ns, 'default', { enumerable: true, value: value });
154 /******/                if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
155 /******/                return ns;
156 /******/        };
157 /******/
158 /******/        // getDefaultExport function for compatibility with non-harmony modules
159 /******/        __webpack_require__.n = function(module) {
160 /******/                var getter = module && module.__esModule ?
161 /******/                        function getDefault() { return module['default']; } :
162 /******/                        function getModuleExports() { return module; };
163 /******/                __webpack_require__.d(getter, 'a', getter);
164 /******/                return getter;
165 /******/        };
166 /******/
167 /******/        // Object.prototype.hasOwnProperty.call
168 /******/        __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
169 /******/
170 /******/        // __webpack_public_path__
171 /******/        __webpack_require__.p = "";
172 /******/
173 /******/
174 /******/        // Load entry module and return exports
175 /******/        return __webpack_require__(__webpack_require__.s = 0);
176 /******/ })
177 /************************************************************************/
178 /******/ ([
179 /* 0 */
180 /***/ (function(module, exports, __webpack_require__) {
182 "use strict";
183 /*jshint node:true */
184 /*
186   The MIT License (MIT)
188   Copyright (c) 2007-2018 Einar Lielmanis, Liam Newman, and contributors.
190   Permission is hereby granted, free of charge, to any person
191   obtaining a copy of this software and associated documentation files
192   (the "Software"), to deal in the Software without restriction,
193   including without limitation the rights to use, copy, modify, merge,
194   publish, distribute, sublicense, and/or sell copies of the Software,
195   and to permit persons to whom the Software is furnished to do so,
196   subject to the following conditions:
198   The above copyright notice and this permission notice shall be
199   included in all copies or substantial portions of the Software.
201   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
202   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
203   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
204   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
205   BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
206   ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
207   CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
208   SOFTWARE.
209 */
213 var Beautifier = __webpack_require__(1).Beautifier,
214   Options = __webpack_require__(5).Options;
216 function js_beautify(js_source_text, options) {
217   var beautifier = new Beautifier(js_source_text, options);
218   return beautifier.beautify();
221 module.exports = js_beautify;
222 module.exports.defaultOptions = function() {
223   return new Options();
224 };
227 /***/ }),
228 /* 1 */
229 /***/ (function(module, exports, __webpack_require__) {
231 "use strict";
232 /*jshint node:true */
233 /*
235   The MIT License (MIT)
237   Copyright (c) 2007-2018 Einar Lielmanis, Liam Newman, and contributors.
239   Permission is hereby granted, free of charge, to any person
240   obtaining a copy of this software and associated documentation files
241   (the "Software"), to deal in the Software without restriction,
242   including without limitation the rights to use, copy, modify, merge,
243   publish, distribute, sublicense, and/or sell copies of the Software,
244   and to permit persons to whom the Software is furnished to do so,
245   subject to the following conditions:
247   The above copyright notice and this permission notice shall be
248   included in all copies or substantial portions of the Software.
250   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
251   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
252   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
253   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
254   BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
255   ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
256   CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
257   SOFTWARE.
258 */
262 var Output = __webpack_require__(2).Output;
263 var Token = __webpack_require__(3).Token;
264 var acorn = __webpack_require__(4);
265 var Options = __webpack_require__(5).Options;
266 var Tokenizer = __webpack_require__(7).Tokenizer;
267 var line_starters = __webpack_require__(7).line_starters;
268 var positionable_operators = __webpack_require__(7).positionable_operators;
269 var TOKEN = __webpack_require__(7).TOKEN;
272 function in_array(what, arr) {
273   return arr.indexOf(what) !== -1;
276 function ltrim(s) {
277   return s.replace(/^\s+/g, '');
280 function generateMapFromStrings(list) {
281   var result = {};
282   for (var x = 0; x < list.length; x++) {
283     // make the mapped names underscored instead of dash
284     result[list[x].replace(/-/g, '_')] = list[x];
285   }
286   return result;
289 function reserved_word(token, word) {
290   return token && token.type === TOKEN.RESERVED && token.text === word;
293 function reserved_array(token, words) {
294   return token && token.type === TOKEN.RESERVED && in_array(token.text, words);
296 // Unsure of what they mean, but they work. Worth cleaning up in future.
297 var special_words = ['case', 'return', 'do', 'if', 'throw', 'else', 'await', 'break', 'continue', 'async'];
299 var validPositionValues = ['before-newline', 'after-newline', 'preserve-newline'];
301 // Generate map from array
302 var OPERATOR_POSITION = generateMapFromStrings(validPositionValues);
304 var OPERATOR_POSITION_BEFORE_OR_PRESERVE = [OPERATOR_POSITION.before_newline, OPERATOR_POSITION.preserve_newline];
306 var MODE = {
307   BlockStatement: 'BlockStatement', // 'BLOCK'
308   Statement: 'Statement', // 'STATEMENT'
309   ObjectLiteral: 'ObjectLiteral', // 'OBJECT',
310   ArrayLiteral: 'ArrayLiteral', //'[EXPRESSION]',
311   ForInitializer: 'ForInitializer', //'(FOR-EXPRESSION)',
312   Conditional: 'Conditional', //'(COND-EXPRESSION)',
313   Expression: 'Expression' //'(EXPRESSION)'
314 };
316 function remove_redundant_indentation(output, frame) {
317   // This implementation is effective but has some issues:
318   //     - can cause line wrap to happen too soon due to indent removal
319   //           after wrap points are calculated
320   // These issues are minor compared to ugly indentation.
322   if (frame.multiline_frame ||
323     frame.mode === MODE.ForInitializer ||
324     frame.mode === MODE.Conditional) {
325     return;
326   }
328   // remove one indent from each line inside this section
329   output.remove_indent(frame.start_line_index);
332 // we could use just string.split, but
333 // IE doesn't like returning empty strings
334 function split_linebreaks(s) {
335   //return s.split(/\x0d\x0a|\x0a/);
337   s = s.replace(acorn.allLineBreaks, '\n');
338   var out = [],
339     idx = s.indexOf("\n");
340   while (idx !== -1) {
341     out.push(s.substring(0, idx));
342     s = s.substring(idx + 1);
343     idx = s.indexOf("\n");
344   }
345   if (s.length) {
346     out.push(s);
347   }
348   return out;
351 function is_array(mode) {
352   return mode === MODE.ArrayLiteral;
355 function is_expression(mode) {
356   return in_array(mode, [MODE.Expression, MODE.ForInitializer, MODE.Conditional]);
359 function all_lines_start_with(lines, c) {
360   for (var i = 0; i < lines.length; i++) {
361     var line = lines[i].trim();
362     if (line.charAt(0) !== c) {
363       return false;
364     }
365   }
366   return true;
369 function each_line_matches_indent(lines, indent) {
370   var i = 0,
371     len = lines.length,
372     line;
373   for (; i < len; i++) {
374     line = lines[i];
375     // allow empty lines to pass through
376     if (line && line.indexOf(indent) !== 0) {
377       return false;
378     }
379   }
380   return true;
384 function Beautifier(source_text, options) {
385   options = options || {};
386   this._source_text = source_text || '';
388   this._output = null;
389   this._tokens = null;
390   this._last_last_text = null;
391   this._flags = null;
392   this._previous_flags = null;
394   this._flag_store = null;
395   this._options = new Options(options);
398 Beautifier.prototype.create_flags = function(flags_base, mode) {
399   var next_indent_level = 0;
400   if (flags_base) {
401     next_indent_level = flags_base.indentation_level;
402     if (!this._output.just_added_newline() &&
403       flags_base.line_indent_level > next_indent_level) {
404       next_indent_level = flags_base.line_indent_level;
405     }
406   }
408   var next_flags = {
409     mode: mode,
410     parent: flags_base,
411     last_token: flags_base ? flags_base.last_token : new Token(TOKEN.START_BLOCK, ''), // last token text
412     last_word: flags_base ? flags_base.last_word : '', // last TOKEN.WORD passed
413     declaration_statement: false,
414     declaration_assignment: false,
415     multiline_frame: false,
416     inline_frame: false,
417     if_block: false,
418     else_block: false,
419     do_block: false,
420     do_while: false,
421     import_block: false,
422     in_case_statement: false, // switch(..){ INSIDE HERE }
423     in_case: false, // we're on the exact line with "case 0:"
424     case_body: false, // the indented case-action block
425     indentation_level: next_indent_level,
426     alignment: 0,
427     line_indent_level: flags_base ? flags_base.line_indent_level : next_indent_level,
428     start_line_index: this._output.get_line_number(),
429     ternary_depth: 0
430   };
431   return next_flags;
432 };
434 Beautifier.prototype._reset = function(source_text) {
435   var baseIndentString = source_text.match(/^[\t ]*/)[0];
437   this._last_last_text = ''; // pre-last token text
438   this._output = new Output(this._options, baseIndentString);
440   // If testing the ignore directive, start with output disable set to true
441   this._output.raw = this._options.test_output_raw;
444   // Stack of parsing/formatting states, including MODE.
445   // We tokenize, parse, and output in an almost purely a forward-only stream of token input
446   // and formatted output.  This makes the beautifier less accurate than full parsers
447   // but also far more tolerant of syntax errors.
448   //
449   // For example, the default mode is MODE.BlockStatement. If we see a '{' we push a new frame of type
450   // MODE.BlockStatement on the the stack, even though it could be object literal.  If we later
451   // encounter a ":", we'll switch to to MODE.ObjectLiteral.  If we then see a ";",
452   // most full parsers would die, but the beautifier gracefully falls back to
453   // MODE.BlockStatement and continues on.
454   this._flag_store = [];
455   this.set_mode(MODE.BlockStatement);
456   var tokenizer = new Tokenizer(source_text, this._options);
457   this._tokens = tokenizer.tokenize();
458   return source_text;
459 };
461 Beautifier.prototype.beautify = function() {
462   // if disabled, return the input unchanged.
463   if (this._options.disabled) {
464     return this._source_text;
465   }
467   var sweet_code;
468   var source_text = this._reset(this._source_text);
470   var eol = this._options.eol;
471   if (this._options.eol === 'auto') {
472     eol = '\n';
473     if (source_text && acorn.lineBreak.test(source_text || '')) {
474       eol = source_text.match(acorn.lineBreak)[0];
475     }
476   }
478   var current_token = this._tokens.next();
479   while (current_token) {
480     this.handle_token(current_token);
482     this._last_last_text = this._flags.last_token.text;
483     this._flags.last_token = current_token;
485     current_token = this._tokens.next();
486   }
488   sweet_code = this._output.get_code(eol);
490   return sweet_code;
491 };
493 Beautifier.prototype.handle_token = function(current_token, preserve_statement_flags) {
494   if (current_token.type === TOKEN.START_EXPR) {
495     this.handle_start_expr(current_token);
496   } else if (current_token.type === TOKEN.END_EXPR) {
497     this.handle_end_expr(current_token);
498   } else if (current_token.type === TOKEN.START_BLOCK) {
499     this.handle_start_block(current_token);
500   } else if (current_token.type === TOKEN.END_BLOCK) {
501     this.handle_end_block(current_token);
502   } else if (current_token.type === TOKEN.WORD) {
503     this.handle_word(current_token);
504   } else if (current_token.type === TOKEN.RESERVED) {
505     this.handle_word(current_token);
506   } else if (current_token.type === TOKEN.SEMICOLON) {
507     this.handle_semicolon(current_token);
508   } else if (current_token.type === TOKEN.STRING) {
509     this.handle_string(current_token);
510   } else if (current_token.type === TOKEN.EQUALS) {
511     this.handle_equals(current_token);
512   } else if (current_token.type === TOKEN.OPERATOR) {
513     this.handle_operator(current_token);
514   } else if (current_token.type === TOKEN.COMMA) {
515     this.handle_comma(current_token);
516   } else if (current_token.type === TOKEN.BLOCK_COMMENT) {
517     this.handle_block_comment(current_token, preserve_statement_flags);
518   } else if (current_token.type === TOKEN.COMMENT) {
519     this.handle_comment(current_token, preserve_statement_flags);
520   } else if (current_token.type === TOKEN.DOT) {
521     this.handle_dot(current_token);
522   } else if (current_token.type === TOKEN.EOF) {
523     this.handle_eof(current_token);
524   } else if (current_token.type === TOKEN.UNKNOWN) {
525     this.handle_unknown(current_token, preserve_statement_flags);
526   } else {
527     this.handle_unknown(current_token, preserve_statement_flags);
528   }
529 };
531 Beautifier.prototype.handle_whitespace_and_comments = function(current_token, preserve_statement_flags) {
532   var newlines = current_token.newlines;
533   var keep_whitespace = this._options.keep_array_indentation && is_array(this._flags.mode);
535   if (current_token.comments_before) {
536     var comment_token = current_token.comments_before.next();
537     while (comment_token) {
538       // The cleanest handling of inline comments is to treat them as though they aren't there.
539       // Just continue formatting and the behavior should be logical.
540       // Also ignore unknown tokens.  Again, this should result in better behavior.
541       this.handle_whitespace_and_comments(comment_token, preserve_statement_flags);
542       this.handle_token(comment_token, preserve_statement_flags);
543       comment_token = current_token.comments_before.next();
544     }
545   }
547   if (keep_whitespace) {
548     for (var i = 0; i < newlines; i += 1) {
549       this.print_newline(i > 0, preserve_statement_flags);
550     }
551   } else {
552     if (this._options.max_preserve_newlines && newlines > this._options.max_preserve_newlines) {
553       newlines = this._options.max_preserve_newlines;
554     }
556     if (this._options.preserve_newlines) {
557       if (newlines > 1) {
558         this.print_newline(false, preserve_statement_flags);
559         for (var j = 1; j < newlines; j += 1) {
560           this.print_newline(true, preserve_statement_flags);
561         }
562       }
563     }
564   }
566 };
568 var newline_restricted_tokens = ['async', 'break', 'continue', 'return', 'throw', 'yield'];
570 Beautifier.prototype.allow_wrap_or_preserved_newline = function(current_token, force_linewrap) {
571   force_linewrap = (force_linewrap === undefined) ? false : force_linewrap;
573   // Never wrap the first token on a line
574   if (this._output.just_added_newline()) {
575     return;
576   }
578   var shouldPreserveOrForce = (this._options.preserve_newlines && current_token.newlines) || force_linewrap;
579   var operatorLogicApplies = in_array(this._flags.last_token.text, positionable_operators) ||
580     in_array(current_token.text, positionable_operators);
582   if (operatorLogicApplies) {
583     var shouldPrintOperatorNewline = (
584         in_array(this._flags.last_token.text, positionable_operators) &&
585         in_array(this._options.operator_position, OPERATOR_POSITION_BEFORE_OR_PRESERVE)
586       ) ||
587       in_array(current_token.text, positionable_operators);
588     shouldPreserveOrForce = shouldPreserveOrForce && shouldPrintOperatorNewline;
589   }
591   if (shouldPreserveOrForce) {
592     this.print_newline(false, true);
593   } else if (this._options.wrap_line_length) {
594     if (reserved_array(this._flags.last_token, newline_restricted_tokens)) {
595       // These tokens should never have a newline inserted
596       // between them and the following expression.
597       return;
598     }
599     this._output.set_wrap_point();
600   }
601 };
603 Beautifier.prototype.print_newline = function(force_newline, preserve_statement_flags) {
604   if (!preserve_statement_flags) {
605     if (this._flags.last_token.text !== ';' && this._flags.last_token.text !== ',' && this._flags.last_token.text !== '=' && (this._flags.last_token.type !== TOKEN.OPERATOR || this._flags.last_token.text === '--' || this._flags.last_token.text === '++')) {
606       var next_token = this._tokens.peek();
607       while (this._flags.mode === MODE.Statement &&
608         !(this._flags.if_block && reserved_word(next_token, 'else')) &&
609         !this._flags.do_block) {
610         this.restore_mode();
611       }
612     }
613   }
615   if (this._output.add_new_line(force_newline)) {
616     this._flags.multiline_frame = true;
617   }
618 };
620 Beautifier.prototype.print_token_line_indentation = function(current_token) {
621   if (this._output.just_added_newline()) {
622     if (this._options.keep_array_indentation &&
623       current_token.newlines &&
624       (current_token.text === '[' || is_array(this._flags.mode))) {
625       this._output.current_line.set_indent(-1);
626       this._output.current_line.push(current_token.whitespace_before);
627       this._output.space_before_token = false;
628     } else if (this._output.set_indent(this._flags.indentation_level, this._flags.alignment)) {
629       this._flags.line_indent_level = this._flags.indentation_level;
630     }
631   }
632 };
634 Beautifier.prototype.print_token = function(current_token) {
635   if (this._output.raw) {
636     this._output.add_raw_token(current_token);
637     return;
638   }
640   if (this._options.comma_first && current_token.previous && current_token.previous.type === TOKEN.COMMA &&
641     this._output.just_added_newline()) {
642     if (this._output.previous_line.last() === ',') {
643       var popped = this._output.previous_line.pop();
644       // if the comma was already at the start of the line,
645       // pull back onto that line and reprint the indentation
646       if (this._output.previous_line.is_empty()) {
647         this._output.previous_line.push(popped);
648         this._output.trim(true);
649         this._output.current_line.pop();
650         this._output.trim();
651       }
653       // add the comma in front of the next token
654       this.print_token_line_indentation(current_token);
655       this._output.add_token(',');
656       this._output.space_before_token = true;
657     }
658   }
660   this.print_token_line_indentation(current_token);
661   this._output.non_breaking_space = true;
662   this._output.add_token(current_token.text);
663   if (this._output.previous_token_wrapped) {
664     this._flags.multiline_frame = true;
665   }
666 };
668 Beautifier.prototype.indent = function() {
669   this._flags.indentation_level += 1;
670   this._output.set_indent(this._flags.indentation_level, this._flags.alignment);
671 };
673 Beautifier.prototype.deindent = function() {
674   if (this._flags.indentation_level > 0 &&
675     ((!this._flags.parent) || this._flags.indentation_level > this._flags.parent.indentation_level)) {
676     this._flags.indentation_level -= 1;
677     this._output.set_indent(this._flags.indentation_level, this._flags.alignment);
678   }
679 };
681 Beautifier.prototype.set_mode = function(mode) {
682   if (this._flags) {
683     this._flag_store.push(this._flags);
684     this._previous_flags = this._flags;
685   } else {
686     this._previous_flags = this.create_flags(null, mode);
687   }
689   this._flags = this.create_flags(this._previous_flags, mode);
690   this._output.set_indent(this._flags.indentation_level, this._flags.alignment);
691 };
694 Beautifier.prototype.restore_mode = function() {
695   if (this._flag_store.length > 0) {
696     this._previous_flags = this._flags;
697     this._flags = this._flag_store.pop();
698     if (this._previous_flags.mode === MODE.Statement) {
699       remove_redundant_indentation(this._output, this._previous_flags);
700     }
701     this._output.set_indent(this._flags.indentation_level, this._flags.alignment);
702   }
703 };
705 Beautifier.prototype.start_of_object_property = function() {
706   return this._flags.parent.mode === MODE.ObjectLiteral && this._flags.mode === MODE.Statement && (
707     (this._flags.last_token.text === ':' && this._flags.ternary_depth === 0) || (reserved_array(this._flags.last_token, ['get', 'set'])));
708 };
710 Beautifier.prototype.start_of_statement = function(current_token) {
711   var start = false;
712   start = start || reserved_array(this._flags.last_token, ['var', 'let', 'const']) && current_token.type === TOKEN.WORD;
713   start = start || reserved_word(this._flags.last_token, 'do');
714   start = start || (!(this._flags.parent.mode === MODE.ObjectLiteral && this._flags.mode === MODE.Statement)) && reserved_array(this._flags.last_token, newline_restricted_tokens) && !current_token.newlines;
715   start = start || reserved_word(this._flags.last_token, 'else') &&
716     !(reserved_word(current_token, 'if') && !current_token.comments_before);
717   start = start || (this._flags.last_token.type === TOKEN.END_EXPR && (this._previous_flags.mode === MODE.ForInitializer || this._previous_flags.mode === MODE.Conditional));
718   start = start || (this._flags.last_token.type === TOKEN.WORD && this._flags.mode === MODE.BlockStatement &&
719     !this._flags.in_case &&
720     !(current_token.text === '--' || current_token.text === '++') &&
721     this._last_last_text !== 'function' &&
722     current_token.type !== TOKEN.WORD && current_token.type !== TOKEN.RESERVED);
723   start = start || (this._flags.mode === MODE.ObjectLiteral && (
724     (this._flags.last_token.text === ':' && this._flags.ternary_depth === 0) || reserved_array(this._flags.last_token, ['get', 'set'])));
726   if (start) {
727     this.set_mode(MODE.Statement);
728     this.indent();
730     this.handle_whitespace_and_comments(current_token, true);
732     // Issue #276:
733     // If starting a new statement with [if, for, while, do], push to a new line.
734     // if (a) if (b) if(c) d(); else e(); else f();
735     if (!this.start_of_object_property()) {
736       this.allow_wrap_or_preserved_newline(current_token,
737         reserved_array(current_token, ['do', 'for', 'if', 'while']));
738     }
739     return true;
740   }
741   return false;
742 };
744 Beautifier.prototype.handle_start_expr = function(current_token) {
745   // The conditional starts the statement if appropriate.
746   if (!this.start_of_statement(current_token)) {
747     this.handle_whitespace_and_comments(current_token);
748   }
750   var next_mode = MODE.Expression;
751   if (current_token.text === '[') {
753     if (this._flags.last_token.type === TOKEN.WORD || this._flags.last_token.text === ')') {
754       // this is array index specifier, break immediately
755       // a[x], fn()[x]
756       if (reserved_array(this._flags.last_token, line_starters)) {
757         this._output.space_before_token = true;
758       }
759       this.print_token(current_token);
760       this.set_mode(next_mode);
761       this.indent();
762       if (this._options.space_in_paren) {
763         this._output.space_before_token = true;
764       }
765       return;
766     }
768     next_mode = MODE.ArrayLiteral;
769     if (is_array(this._flags.mode)) {
770       if (this._flags.last_token.text === '[' ||
771         (this._flags.last_token.text === ',' && (this._last_last_text === ']' || this._last_last_text === '}'))) {
772         // ], [ goes to new line
773         // }, [ goes to new line
774         if (!this._options.keep_array_indentation) {
775           this.print_newline();
776         }
777       }
778     }
780     if (!in_array(this._flags.last_token.type, [TOKEN.START_EXPR, TOKEN.END_EXPR, TOKEN.WORD, TOKEN.OPERATOR])) {
781       this._output.space_before_token = true;
782     }
783   } else {
784     if (this._flags.last_token.type === TOKEN.RESERVED) {
785       if (this._flags.last_token.text === 'for') {
786         this._output.space_before_token = this._options.space_before_conditional;
787         next_mode = MODE.ForInitializer;
788       } else if (in_array(this._flags.last_token.text, ['if', 'while'])) {
789         this._output.space_before_token = this._options.space_before_conditional;
790         next_mode = MODE.Conditional;
791       } else if (in_array(this._flags.last_word, ['await', 'async'])) {
792         // Should be a space between await and an IIFE, or async and an arrow function
793         this._output.space_before_token = true;
794       } else if (this._flags.last_token.text === 'import' && current_token.whitespace_before === '') {
795         this._output.space_before_token = false;
796       } else if (in_array(this._flags.last_token.text, line_starters) || this._flags.last_token.text === 'catch') {
797         this._output.space_before_token = true;
798       }
799     } else if (this._flags.last_token.type === TOKEN.EQUALS || this._flags.last_token.type === TOKEN.OPERATOR) {
800       // Support of this kind of newline preservation.
801       // a = (b &&
802       //     (c || d));
803       if (!this.start_of_object_property()) {
804         this.allow_wrap_or_preserved_newline(current_token);
805       }
806     } else if (this._flags.last_token.type === TOKEN.WORD) {
807       this._output.space_before_token = false;
809       // function name() vs function name ()
810       // function* name() vs function* name ()
811       // async name() vs async name ()
812       // In ES6, you can also define the method properties of an object
813       // var obj = {a: function() {}}
814       // It can be abbreviated
815       // var obj = {a() {}}
816       // var obj = { a() {}} vs var obj = { a () {}}
817       // var obj = { * a() {}} vs var obj = { * a () {}}
818       var peek_back_two = this._tokens.peek(-3);
819       if (this._options.space_after_named_function && peek_back_two) {
820         // peek starts at next character so -1 is current token
821         var peek_back_three = this._tokens.peek(-4);
822         if (reserved_array(peek_back_two, ['async', 'function']) ||
823           (peek_back_two.text === '*' && reserved_array(peek_back_three, ['async', 'function']))) {
824           this._output.space_before_token = true;
825         } else if (this._flags.mode === MODE.ObjectLiteral) {
826           if ((peek_back_two.text === '{' || peek_back_two.text === ',') ||
827             (peek_back_two.text === '*' && (peek_back_three.text === '{' || peek_back_three.text === ','))) {
828             this._output.space_before_token = true;
829           }
830         }
831       }
832     } else {
833       // Support preserving wrapped arrow function expressions
834       // a.b('c',
835       //     () => d.e
836       // )
837       this.allow_wrap_or_preserved_newline(current_token);
838     }
840     // function() vs function ()
841     // yield*() vs yield* ()
842     // function*() vs function* ()
843     if ((this._flags.last_token.type === TOKEN.RESERVED && (this._flags.last_word === 'function' || this._flags.last_word === 'typeof')) ||
844       (this._flags.last_token.text === '*' &&
845         (in_array(this._last_last_text, ['function', 'yield']) ||
846           (this._flags.mode === MODE.ObjectLiteral && in_array(this._last_last_text, ['{', ',']))))) {
847       this._output.space_before_token = this._options.space_after_anon_function;
848     }
849   }
851   if (this._flags.last_token.text === ';' || this._flags.last_token.type === TOKEN.START_BLOCK) {
852     this.print_newline();
853   } else if (this._flags.last_token.type === TOKEN.END_EXPR || this._flags.last_token.type === TOKEN.START_EXPR || this._flags.last_token.type === TOKEN.END_BLOCK || this._flags.last_token.text === '.' || this._flags.last_token.type === TOKEN.COMMA) {
854     // do nothing on (( and )( and ][ and ]( and .(
855     // TODO: Consider whether forcing this is required.  Review failing tests when removed.
856     this.allow_wrap_or_preserved_newline(current_token, current_token.newlines);
857   }
859   this.print_token(current_token);
860   this.set_mode(next_mode);
861   if (this._options.space_in_paren) {
862     this._output.space_before_token = true;
863   }
865   // In all cases, if we newline while inside an expression it should be indented.
866   this.indent();
867 };
869 Beautifier.prototype.handle_end_expr = function(current_token) {
870   // statements inside expressions are not valid syntax, but...
871   // statements must all be closed when their container closes
872   while (this._flags.mode === MODE.Statement) {
873     this.restore_mode();
874   }
876   this.handle_whitespace_and_comments(current_token);
878   if (this._flags.multiline_frame) {
879     this.allow_wrap_or_preserved_newline(current_token,
880       current_token.text === ']' && is_array(this._flags.mode) && !this._options.keep_array_indentation);
881   }
883   if (this._options.space_in_paren) {
884     if (this._flags.last_token.type === TOKEN.START_EXPR && !this._options.space_in_empty_paren) {
885       // () [] no inner space in empty parens like these, ever, ref #320
886       this._output.trim();
887       this._output.space_before_token = false;
888     } else {
889       this._output.space_before_token = true;
890     }
891   }
892   this.deindent();
893   this.print_token(current_token);
894   this.restore_mode();
896   remove_redundant_indentation(this._output, this._previous_flags);
898   // do {} while () // no statement required after
899   if (this._flags.do_while && this._previous_flags.mode === MODE.Conditional) {
900     this._previous_flags.mode = MODE.Expression;
901     this._flags.do_block = false;
902     this._flags.do_while = false;
904   }
905 };
907 Beautifier.prototype.handle_start_block = function(current_token) {
908   this.handle_whitespace_and_comments(current_token);
910   // Check if this is should be treated as a ObjectLiteral
911   var next_token = this._tokens.peek();
912   var second_token = this._tokens.peek(1);
913   if (this._flags.last_word === 'switch' && this._flags.last_token.type === TOKEN.END_EXPR) {
914     this.set_mode(MODE.BlockStatement);
915     this._flags.in_case_statement = true;
916   } else if (this._flags.case_body) {
917     this.set_mode(MODE.BlockStatement);
918   } else if (second_token && (
919       (in_array(second_token.text, [':', ',']) && in_array(next_token.type, [TOKEN.STRING, TOKEN.WORD, TOKEN.RESERVED])) ||
920       (in_array(next_token.text, ['get', 'set', '...']) && in_array(second_token.type, [TOKEN.WORD, TOKEN.RESERVED]))
921     )) {
922     // We don't support TypeScript,but we didn't break it for a very long time.
923     // We'll try to keep not breaking it.
924     if (!in_array(this._last_last_text, ['class', 'interface'])) {
925       this.set_mode(MODE.ObjectLiteral);
926     } else {
927       this.set_mode(MODE.BlockStatement);
928     }
929   } else if (this._flags.last_token.type === TOKEN.OPERATOR && this._flags.last_token.text === '=>') {
930     // arrow function: (param1, paramN) => { statements }
931     this.set_mode(MODE.BlockStatement);
932   } else if (in_array(this._flags.last_token.type, [TOKEN.EQUALS, TOKEN.START_EXPR, TOKEN.COMMA, TOKEN.OPERATOR]) ||
933     reserved_array(this._flags.last_token, ['return', 'throw', 'import', 'default'])
934   ) {
935     // Detecting shorthand function syntax is difficult by scanning forward,
936     //     so check the surrounding context.
937     // If the block is being returned, imported, export default, passed as arg,
938     //     assigned with = or assigned in a nested object, treat as an ObjectLiteral.
939     this.set_mode(MODE.ObjectLiteral);
940   } else {
941     this.set_mode(MODE.BlockStatement);
942   }
944   var empty_braces = !next_token.comments_before && next_token.text === '}';
945   var empty_anonymous_function = empty_braces && this._flags.last_word === 'function' &&
946     this._flags.last_token.type === TOKEN.END_EXPR;
948   if (this._options.brace_preserve_inline) // check for inline, set inline_frame if so
949   {
950     // search forward for a newline wanted inside this block
951     var index = 0;
952     var check_token = null;
953     this._flags.inline_frame = true;
954     do {
955       index += 1;
956       check_token = this._tokens.peek(index - 1);
957       if (check_token.newlines) {
958         this._flags.inline_frame = false;
959         break;
960       }
961     } while (check_token.type !== TOKEN.EOF &&
962       !(check_token.type === TOKEN.END_BLOCK && check_token.opened === current_token));
963   }
965   if ((this._options.brace_style === "expand" ||
966       (this._options.brace_style === "none" && current_token.newlines)) &&
967     !this._flags.inline_frame) {
968     if (this._flags.last_token.type !== TOKEN.OPERATOR &&
969       (empty_anonymous_function ||
970         this._flags.last_token.type === TOKEN.EQUALS ||
971         (reserved_array(this._flags.last_token, special_words) && this._flags.last_token.text !== 'else'))) {
972       this._output.space_before_token = true;
973     } else {
974       this.print_newline(false, true);
975     }
976   } else { // collapse || inline_frame
977     if (is_array(this._previous_flags.mode) && (this._flags.last_token.type === TOKEN.START_EXPR || this._flags.last_token.type === TOKEN.COMMA)) {
978       if (this._flags.last_token.type === TOKEN.COMMA || this._options.space_in_paren) {
979         this._output.space_before_token = true;
980       }
982       if (this._flags.last_token.type === TOKEN.COMMA || (this._flags.last_token.type === TOKEN.START_EXPR && this._flags.inline_frame)) {
983         this.allow_wrap_or_preserved_newline(current_token);
984         this._previous_flags.multiline_frame = this._previous_flags.multiline_frame || this._flags.multiline_frame;
985         this._flags.multiline_frame = false;
986       }
987     }
988     if (this._flags.last_token.type !== TOKEN.OPERATOR && this._flags.last_token.type !== TOKEN.START_EXPR) {
989       if (this._flags.last_token.type === TOKEN.START_BLOCK && !this._flags.inline_frame) {
990         this.print_newline();
991       } else {
992         this._output.space_before_token = true;
993       }
994     }
995   }
996   this.print_token(current_token);
997   this.indent();
999   // Except for specific cases, open braces are followed by a new line.
1000   if (!empty_braces && !(this._options.brace_preserve_inline && this._flags.inline_frame)) {
1001     this.print_newline();
1002   }
1003 };
1005 Beautifier.prototype.handle_end_block = function(current_token) {
1006   // statements must all be closed when their container closes
1007   this.handle_whitespace_and_comments(current_token);
1009   while (this._flags.mode === MODE.Statement) {
1010     this.restore_mode();
1011   }
1013   var empty_braces = this._flags.last_token.type === TOKEN.START_BLOCK;
1015   if (this._flags.inline_frame && !empty_braces) { // try inline_frame (only set if this._options.braces-preserve-inline) first
1016     this._output.space_before_token = true;
1017   } else if (this._options.brace_style === "expand") {
1018     if (!empty_braces) {
1019       this.print_newline();
1020     }
1021   } else {
1022     // skip {}
1023     if (!empty_braces) {
1024       if (is_array(this._flags.mode) && this._options.keep_array_indentation) {
1025         // we REALLY need a newline here, but newliner would skip that
1026         this._options.keep_array_indentation = false;
1027         this.print_newline();
1028         this._options.keep_array_indentation = true;
1030       } else {
1031         this.print_newline();
1032       }
1033     }
1034   }
1035   this.restore_mode();
1036   this.print_token(current_token);
1037 };
1039 Beautifier.prototype.handle_word = function(current_token) {
1040   if (current_token.type === TOKEN.RESERVED) {
1041     if (in_array(current_token.text, ['set', 'get']) && this._flags.mode !== MODE.ObjectLiteral) {
1042       current_token.type = TOKEN.WORD;
1043     } else if (current_token.text === 'import' && this._tokens.peek().text === '(') {
1044       current_token.type = TOKEN.WORD;
1045     } else if (in_array(current_token.text, ['as', 'from']) && !this._flags.import_block) {
1046       current_token.type = TOKEN.WORD;
1047     } else if (this._flags.mode === MODE.ObjectLiteral) {
1048       var next_token = this._tokens.peek();
1049       if (next_token.text === ':') {
1050         current_token.type = TOKEN.WORD;
1051       }
1052     }
1053   }
1055   if (this.start_of_statement(current_token)) {
1056     // The conditional starts the statement if appropriate.
1057     if (reserved_array(this._flags.last_token, ['var', 'let', 'const']) && current_token.type === TOKEN.WORD) {
1058       this._flags.declaration_statement = true;
1059     }
1060   } else if (current_token.newlines && !is_expression(this._flags.mode) &&
1061     (this._flags.last_token.type !== TOKEN.OPERATOR || (this._flags.last_token.text === '--' || this._flags.last_token.text === '++')) &&
1062     this._flags.last_token.type !== TOKEN.EQUALS &&
1063     (this._options.preserve_newlines || !reserved_array(this._flags.last_token, ['var', 'let', 'const', 'set', 'get']))) {
1064     this.handle_whitespace_and_comments(current_token);
1065     this.print_newline();
1066   } else {
1067     this.handle_whitespace_and_comments(current_token);
1068   }
1070   if (this._flags.do_block && !this._flags.do_while) {
1071     if (reserved_word(current_token, 'while')) {
1072       // do {} ## while ()
1073       this._output.space_before_token = true;
1074       this.print_token(current_token);
1075       this._output.space_before_token = true;
1076       this._flags.do_while = true;
1077       return;
1078     } else {
1079       // do {} should always have while as the next word.
1080       // if we don't see the expected while, recover
1081       this.print_newline();
1082       this._flags.do_block = false;
1083     }
1084   }
1086   // if may be followed by else, or not
1087   // Bare/inline ifs are tricky
1088   // Need to unwind the modes correctly: if (a) if (b) c(); else d(); else e();
1089   if (this._flags.if_block) {
1090     if (!this._flags.else_block && reserved_word(current_token, 'else')) {
1091       this._flags.else_block = true;
1092     } else {
1093       while (this._flags.mode === MODE.Statement) {
1094         this.restore_mode();
1095       }
1096       this._flags.if_block = false;
1097       this._flags.else_block = false;
1098     }
1099   }
1101   if (this._flags.in_case_statement && reserved_array(current_token, ['case', 'default'])) {
1102     this.print_newline();
1103     if (this._flags.last_token.type !== TOKEN.END_BLOCK && (this._flags.case_body || this._options.jslint_happy)) {
1104       // switch cases following one another
1105       this.deindent();
1106     }
1107     this._flags.case_body = false;
1109     this.print_token(current_token);
1110     this._flags.in_case = true;
1111     return;
1112   }
1114   if (this._flags.last_token.type === TOKEN.COMMA || this._flags.last_token.type === TOKEN.START_EXPR || this._flags.last_token.type === TOKEN.EQUALS || this._flags.last_token.type === TOKEN.OPERATOR) {
1115     if (!this.start_of_object_property()) {
1116       this.allow_wrap_or_preserved_newline(current_token);
1117     }
1118   }
1120   if (reserved_word(current_token, 'function')) {
1121     if (in_array(this._flags.last_token.text, ['}', ';']) ||
1122       (this._output.just_added_newline() && !(in_array(this._flags.last_token.text, ['(', '[', '{', ':', '=', ',']) || this._flags.last_token.type === TOKEN.OPERATOR))) {
1123       // make sure there is a nice clean space of at least one blank line
1124       // before a new function definition
1125       if (!this._output.just_added_blankline() && !current_token.comments_before) {
1126         this.print_newline();
1127         this.print_newline(true);
1128       }
1129     }
1130     if (this._flags.last_token.type === TOKEN.RESERVED || this._flags.last_token.type === TOKEN.WORD) {
1131       if (reserved_array(this._flags.last_token, ['get', 'set', 'new', 'export']) ||
1132         reserved_array(this._flags.last_token, newline_restricted_tokens)) {
1133         this._output.space_before_token = true;
1134       } else if (reserved_word(this._flags.last_token, 'default') && this._last_last_text === 'export') {
1135         this._output.space_before_token = true;
1136       } else if (this._flags.last_token.text === 'declare') {
1137         // accomodates Typescript declare function formatting
1138         this._output.space_before_token = true;
1139       } else {
1140         this.print_newline();
1141       }
1142     } else if (this._flags.last_token.type === TOKEN.OPERATOR || this._flags.last_token.text === '=') {
1143       // foo = function
1144       this._output.space_before_token = true;
1145     } else if (!this._flags.multiline_frame && (is_expression(this._flags.mode) || is_array(this._flags.mode))) {
1146       // (function
1147     } else {
1148       this.print_newline();
1149     }
1151     this.print_token(current_token);
1152     this._flags.last_word = current_token.text;
1153     return;
1154   }
1156   var prefix = 'NONE';
1158   if (this._flags.last_token.type === TOKEN.END_BLOCK) {
1160     if (this._previous_flags.inline_frame) {
1161       prefix = 'SPACE';
1162     } else if (!reserved_array(current_token, ['else', 'catch', 'finally', 'from'])) {
1163       prefix = 'NEWLINE';
1164     } else {
1165       if (this._options.brace_style === "expand" ||
1166         this._options.brace_style === "end-expand" ||
1167         (this._options.brace_style === "none" && current_token.newlines)) {
1168         prefix = 'NEWLINE';
1169       } else {
1170         prefix = 'SPACE';
1171         this._output.space_before_token = true;
1172       }
1173     }
1174   } else if (this._flags.last_token.type === TOKEN.SEMICOLON && this._flags.mode === MODE.BlockStatement) {
1175     // TODO: Should this be for STATEMENT as well?
1176     prefix = 'NEWLINE';
1177   } else if (this._flags.last_token.type === TOKEN.SEMICOLON && is_expression(this._flags.mode)) {
1178     prefix = 'SPACE';
1179   } else if (this._flags.last_token.type === TOKEN.STRING) {
1180     prefix = 'NEWLINE';
1181   } else if (this._flags.last_token.type === TOKEN.RESERVED || this._flags.last_token.type === TOKEN.WORD ||
1182     (this._flags.last_token.text === '*' &&
1183       (in_array(this._last_last_text, ['function', 'yield']) ||
1184         (this._flags.mode === MODE.ObjectLiteral && in_array(this._last_last_text, ['{', ',']))))) {
1185     prefix = 'SPACE';
1186   } else if (this._flags.last_token.type === TOKEN.START_BLOCK) {
1187     if (this._flags.inline_frame) {
1188       prefix = 'SPACE';
1189     } else {
1190       prefix = 'NEWLINE';
1191     }
1192   } else if (this._flags.last_token.type === TOKEN.END_EXPR) {
1193     this._output.space_before_token = true;
1194     prefix = 'NEWLINE';
1195   }
1197   if (reserved_array(current_token, line_starters) && this._flags.last_token.text !== ')') {
1198     if (this._flags.inline_frame || this._flags.last_token.text === 'else' || this._flags.last_token.text === 'export') {
1199       prefix = 'SPACE';
1200     } else {
1201       prefix = 'NEWLINE';
1202     }
1204   }
1206   if (reserved_array(current_token, ['else', 'catch', 'finally'])) {
1207     if ((!(this._flags.last_token.type === TOKEN.END_BLOCK && this._previous_flags.mode === MODE.BlockStatement) ||
1208         this._options.brace_style === "expand" ||
1209         this._options.brace_style === "end-expand" ||
1210         (this._options.brace_style === "none" && current_token.newlines)) &&
1211       !this._flags.inline_frame) {
1212       this.print_newline();
1213     } else {
1214       this._output.trim(true);
1215       var line = this._output.current_line;
1216       // If we trimmed and there's something other than a close block before us
1217       // put a newline back in.  Handles '} // comment' scenario.
1218       if (line.last() !== '}') {
1219         this.print_newline();
1220       }
1221       this._output.space_before_token = true;
1222     }
1223   } else if (prefix === 'NEWLINE') {
1224     if (reserved_array(this._flags.last_token, special_words)) {
1225       // no newline between 'return nnn'
1226       this._output.space_before_token = true;
1227     } else if (this._flags.last_token.text === 'declare' && reserved_array(current_token, ['var', 'let', 'const'])) {
1228       // accomodates Typescript declare formatting
1229       this._output.space_before_token = true;
1230     } else if (this._flags.last_token.type !== TOKEN.END_EXPR) {
1231       if ((this._flags.last_token.type !== TOKEN.START_EXPR || !reserved_array(current_token, ['var', 'let', 'const'])) && this._flags.last_token.text !== ':') {
1232         // no need to force newline on 'var': for (var x = 0...)
1233         if (reserved_word(current_token, 'if') && reserved_word(current_token.previous, 'else')) {
1234           // no newline for } else if {
1235           this._output.space_before_token = true;
1236         } else {
1237           this.print_newline();
1238         }
1239       }
1240     } else if (reserved_array(current_token, line_starters) && this._flags.last_token.text !== ')') {
1241       this.print_newline();
1242     }
1243   } else if (this._flags.multiline_frame && is_array(this._flags.mode) && this._flags.last_token.text === ',' && this._last_last_text === '}') {
1244     this.print_newline(); // }, in lists get a newline treatment
1245   } else if (prefix === 'SPACE') {
1246     this._output.space_before_token = true;
1247   }
1248   if (current_token.previous && (current_token.previous.type === TOKEN.WORD || current_token.previous.type === TOKEN.RESERVED)) {
1249     this._output.space_before_token = true;
1250   }
1251   this.print_token(current_token);
1252   this._flags.last_word = current_token.text;
1254   if (current_token.type === TOKEN.RESERVED) {
1255     if (current_token.text === 'do') {
1256       this._flags.do_block = true;
1257     } else if (current_token.text === 'if') {
1258       this._flags.if_block = true;
1259     } else if (current_token.text === 'import') {
1260       this._flags.import_block = true;
1261     } else if (this._flags.import_block && reserved_word(current_token, 'from')) {
1262       this._flags.import_block = false;
1263     }
1264   }
1265 };
1267 Beautifier.prototype.handle_semicolon = function(current_token) {
1268   if (this.start_of_statement(current_token)) {
1269     // The conditional starts the statement if appropriate.
1270     // Semicolon can be the start (and end) of a statement
1271     this._output.space_before_token = false;
1272   } else {
1273     this.handle_whitespace_and_comments(current_token);
1274   }
1276   var next_token = this._tokens.peek();
1277   while (this._flags.mode === MODE.Statement &&
1278     !(this._flags.if_block && reserved_word(next_token, 'else')) &&
1279     !this._flags.do_block) {
1280     this.restore_mode();
1281   }
1283   // hacky but effective for the moment
1284   if (this._flags.import_block) {
1285     this._flags.import_block = false;
1286   }
1287   this.print_token(current_token);
1288 };
1290 Beautifier.prototype.handle_string = function(current_token) {
1291   if (this.start_of_statement(current_token)) {
1292     // The conditional starts the statement if appropriate.
1293     // One difference - strings want at least a space before
1294     this._output.space_before_token = true;
1295   } else {
1296     this.handle_whitespace_and_comments(current_token);
1297     if (this._flags.last_token.type === TOKEN.RESERVED || this._flags.last_token.type === TOKEN.WORD || this._flags.inline_frame) {
1298       this._output.space_before_token = true;
1299     } else if (this._flags.last_token.type === TOKEN.COMMA || this._flags.last_token.type === TOKEN.START_EXPR || this._flags.last_token.type === TOKEN.EQUALS || this._flags.last_token.type === TOKEN.OPERATOR) {
1300       if (!this.start_of_object_property()) {
1301         this.allow_wrap_or_preserved_newline(current_token);
1302       }
1303     } else {
1304       this.print_newline();
1305     }
1306   }
1307   this.print_token(current_token);
1308 };
1310 Beautifier.prototype.handle_equals = function(current_token) {
1311   if (this.start_of_statement(current_token)) {
1312     // The conditional starts the statement if appropriate.
1313   } else {
1314     this.handle_whitespace_and_comments(current_token);
1315   }
1317   if (this._flags.declaration_statement) {
1318     // just got an '=' in a var-line, different formatting/line-breaking, etc will now be done
1319     this._flags.declaration_assignment = true;
1320   }
1321   this._output.space_before_token = true;
1322   this.print_token(current_token);
1323   this._output.space_before_token = true;
1324 };
1326 Beautifier.prototype.handle_comma = function(current_token) {
1327   this.handle_whitespace_and_comments(current_token, true);
1329   this.print_token(current_token);
1330   this._output.space_before_token = true;
1331   if (this._flags.declaration_statement) {
1332     if (is_expression(this._flags.parent.mode)) {
1333       // do not break on comma, for(var a = 1, b = 2)
1334       this._flags.declaration_assignment = false;
1335     }
1337     if (this._flags.declaration_assignment) {
1338       this._flags.declaration_assignment = false;
1339       this.print_newline(false, true);
1340     } else if (this._options.comma_first) {
1341       // for comma-first, we want to allow a newline before the comma
1342       // to turn into a newline after the comma, which we will fixup later
1343       this.allow_wrap_or_preserved_newline(current_token);
1344     }
1345   } else if (this._flags.mode === MODE.ObjectLiteral ||
1346     (this._flags.mode === MODE.Statement && this._flags.parent.mode === MODE.ObjectLiteral)) {
1347     if (this._flags.mode === MODE.Statement) {
1348       this.restore_mode();
1349     }
1351     if (!this._flags.inline_frame) {
1352       this.print_newline();
1353     }
1354   } else if (this._options.comma_first) {
1355     // EXPR or DO_BLOCK
1356     // for comma-first, we want to allow a newline before the comma
1357     // to turn into a newline after the comma, which we will fixup later
1358     this.allow_wrap_or_preserved_newline(current_token);
1359   }
1360 };
1362 Beautifier.prototype.handle_operator = function(current_token) {
1363   var isGeneratorAsterisk = current_token.text === '*' &&
1364     (reserved_array(this._flags.last_token, ['function', 'yield']) ||
1365       (in_array(this._flags.last_token.type, [TOKEN.START_BLOCK, TOKEN.COMMA, TOKEN.END_BLOCK, TOKEN.SEMICOLON]))
1366     );
1367   var isUnary = in_array(current_token.text, ['-', '+']) && (
1368     in_array(this._flags.last_token.type, [TOKEN.START_BLOCK, TOKEN.START_EXPR, TOKEN.EQUALS, TOKEN.OPERATOR]) ||
1369     in_array(this._flags.last_token.text, line_starters) ||
1370     this._flags.last_token.text === ','
1371   );
1373   if (this.start_of_statement(current_token)) {
1374     // The conditional starts the statement if appropriate.
1375   } else {
1376     var preserve_statement_flags = !isGeneratorAsterisk;
1377     this.handle_whitespace_and_comments(current_token, preserve_statement_flags);
1378   }
1380   if (reserved_array(this._flags.last_token, special_words)) {
1381     // "return" had a special handling in TK_WORD. Now we need to return the favor
1382     this._output.space_before_token = true;
1383     this.print_token(current_token);
1384     return;
1385   }
1387   // hack for actionscript's import .*;
1388   if (current_token.text === '*' && this._flags.last_token.type === TOKEN.DOT) {
1389     this.print_token(current_token);
1390     return;
1391   }
1393   if (current_token.text === '::') {
1394     // no spaces around exotic namespacing syntax operator
1395     this.print_token(current_token);
1396     return;
1397   }
1399   // Allow line wrapping between operators when operator_position is
1400   //   set to before or preserve
1401   if (this._flags.last_token.type === TOKEN.OPERATOR && in_array(this._options.operator_position, OPERATOR_POSITION_BEFORE_OR_PRESERVE)) {
1402     this.allow_wrap_or_preserved_newline(current_token);
1403   }
1405   if (current_token.text === ':' && this._flags.in_case) {
1406     this.print_token(current_token);
1408     this._flags.in_case = false;
1409     this._flags.case_body = true;
1410     if (this._tokens.peek().type !== TOKEN.START_BLOCK) {
1411       this.indent();
1412       this.print_newline();
1413     } else {
1414       this._output.space_before_token = true;
1415     }
1416     return;
1417   }
1419   var space_before = true;
1420   var space_after = true;
1421   var in_ternary = false;
1422   if (current_token.text === ':') {
1423     if (this._flags.ternary_depth === 0) {
1424       // Colon is invalid javascript outside of ternary and object, but do our best to guess what was meant.
1425       space_before = false;
1426     } else {
1427       this._flags.ternary_depth -= 1;
1428       in_ternary = true;
1429     }
1430   } else if (current_token.text === '?') {
1431     this._flags.ternary_depth += 1;
1432   }
1434   // let's handle the operator_position option prior to any conflicting logic
1435   if (!isUnary && !isGeneratorAsterisk && this._options.preserve_newlines && in_array(current_token.text, positionable_operators)) {
1436     var isColon = current_token.text === ':';
1437     var isTernaryColon = (isColon && in_ternary);
1438     var isOtherColon = (isColon && !in_ternary);
1440     switch (this._options.operator_position) {
1441       case OPERATOR_POSITION.before_newline:
1442         // if the current token is : and it's not a ternary statement then we set space_before to false
1443         this._output.space_before_token = !isOtherColon;
1445         this.print_token(current_token);
1447         if (!isColon || isTernaryColon) {
1448           this.allow_wrap_or_preserved_newline(current_token);
1449         }
1451         this._output.space_before_token = true;
1452         return;
1454       case OPERATOR_POSITION.after_newline:
1455         // if the current token is anything but colon, or (via deduction) it's a colon and in a ternary statement,
1456         //   then print a newline.
1458         this._output.space_before_token = true;
1460         if (!isColon || isTernaryColon) {
1461           if (this._tokens.peek().newlines) {
1462             this.print_newline(false, true);
1463           } else {
1464             this.allow_wrap_or_preserved_newline(current_token);
1465           }
1466         } else {
1467           this._output.space_before_token = false;
1468         }
1470         this.print_token(current_token);
1472         this._output.space_before_token = true;
1473         return;
1475       case OPERATOR_POSITION.preserve_newline:
1476         if (!isOtherColon) {
1477           this.allow_wrap_or_preserved_newline(current_token);
1478         }
1480         // if we just added a newline, or the current token is : and it's not a ternary statement,
1481         //   then we set space_before to false
1482         space_before = !(this._output.just_added_newline() || isOtherColon);
1484         this._output.space_before_token = space_before;
1485         this.print_token(current_token);
1486         this._output.space_before_token = true;
1487         return;
1488     }
1489   }
1491   if (isGeneratorAsterisk) {
1492     this.allow_wrap_or_preserved_newline(current_token);
1493     space_before = false;
1494     var next_token = this._tokens.peek();
1495     space_after = next_token && in_array(next_token.type, [TOKEN.WORD, TOKEN.RESERVED]);
1496   } else if (current_token.text === '...') {
1497     this.allow_wrap_or_preserved_newline(current_token);
1498     space_before = this._flags.last_token.type === TOKEN.START_BLOCK;
1499     space_after = false;
1500   } else if (in_array(current_token.text, ['--', '++', '!', '~']) || isUnary) {
1501     // unary operators (and binary +/- pretending to be unary) special cases
1502     if (this._flags.last_token.type === TOKEN.COMMA || this._flags.last_token.type === TOKEN.START_EXPR) {
1503       this.allow_wrap_or_preserved_newline(current_token);
1504     }
1506     space_before = false;
1507     space_after = false;
1509     // http://www.ecma-international.org/ecma-262/5.1/#sec-7.9.1
1510     // if there is a newline between -- or ++ and anything else we should preserve it.
1511     if (current_token.newlines && (current_token.text === '--' || current_token.text === '++')) {
1512       this.print_newline(false, true);
1513     }
1515     if (this._flags.last_token.text === ';' && is_expression(this._flags.mode)) {
1516       // for (;; ++i)
1517       //        ^^^
1518       space_before = true;
1519     }
1521     if (this._flags.last_token.type === TOKEN.RESERVED) {
1522       space_before = true;
1523     } else if (this._flags.last_token.type === TOKEN.END_EXPR) {
1524       space_before = !(this._flags.last_token.text === ']' && (current_token.text === '--' || current_token.text === '++'));
1525     } else if (this._flags.last_token.type === TOKEN.OPERATOR) {
1526       // a++ + ++b;
1527       // a - -b
1528       space_before = in_array(current_token.text, ['--', '-', '++', '+']) && in_array(this._flags.last_token.text, ['--', '-', '++', '+']);
1529       // + and - are not unary when preceeded by -- or ++ operator
1530       // a-- + b
1531       // a * +b
1532       // a - -b
1533       if (in_array(current_token.text, ['+', '-']) && in_array(this._flags.last_token.text, ['--', '++'])) {
1534         space_after = true;
1535       }
1536     }
1539     if (((this._flags.mode === MODE.BlockStatement && !this._flags.inline_frame) || this._flags.mode === MODE.Statement) &&
1540       (this._flags.last_token.text === '{' || this._flags.last_token.text === ';')) {
1541       // { foo; --i }
1542       // foo(); --bar;
1543       this.print_newline();
1544     }
1545   }
1547   this._output.space_before_token = this._output.space_before_token || space_before;
1548   this.print_token(current_token);
1549   this._output.space_before_token = space_after;
1550 };
1552 Beautifier.prototype.handle_block_comment = function(current_token, preserve_statement_flags) {
1553   if (this._output.raw) {
1554     this._output.add_raw_token(current_token);
1555     if (current_token.directives && current_token.directives.preserve === 'end') {
1556       // If we're testing the raw output behavior, do not allow a directive to turn it off.
1557       this._output.raw = this._options.test_output_raw;
1558     }
1559     return;
1560   }
1562   if (current_token.directives) {
1563     this.print_newline(false, preserve_statement_flags);
1564     this.print_token(current_token);
1565     if (current_token.directives.preserve === 'start') {
1566       this._output.raw = true;
1567     }
1568     this.print_newline(false, true);
1569     return;
1570   }
1572   // inline block
1573   if (!acorn.newline.test(current_token.text) && !current_token.newlines) {
1574     this._output.space_before_token = true;
1575     this.print_token(current_token);
1576     this._output.space_before_token = true;
1577     return;
1578   } else {
1579     this.print_block_commment(current_token, preserve_statement_flags);
1580   }
1581 };
1583 Beautifier.prototype.print_block_commment = function(current_token, preserve_statement_flags) {
1584   var lines = split_linebreaks(current_token.text);
1585   var j; // iterator for this case
1586   var javadoc = false;
1587   var starless = false;
1588   var lastIndent = current_token.whitespace_before;
1589   var lastIndentLength = lastIndent.length;
1591   // block comment starts with a new line
1592   this.print_newline(false, preserve_statement_flags);
1594   // first line always indented
1595   this.print_token_line_indentation(current_token);
1596   this._output.add_token(lines[0]);
1597   this.print_newline(false, preserve_statement_flags);
1600   if (lines.length > 1) {
1601     lines = lines.slice(1);
1602     javadoc = all_lines_start_with(lines, '*');
1603     starless = each_line_matches_indent(lines, lastIndent);
1605     if (javadoc) {
1606       this._flags.alignment = 1;
1607     }
1609     for (j = 0; j < lines.length; j++) {
1610       if (javadoc) {
1611         // javadoc: reformat and re-indent
1612         this.print_token_line_indentation(current_token);
1613         this._output.add_token(ltrim(lines[j]));
1614       } else if (starless && lines[j]) {
1615         // starless: re-indent non-empty content, avoiding trim
1616         this.print_token_line_indentation(current_token);
1617         this._output.add_token(lines[j].substring(lastIndentLength));
1618       } else {
1619         // normal comments output raw
1620         this._output.current_line.set_indent(-1);
1621         this._output.add_token(lines[j]);
1622       }
1624       // for comments on their own line or  more than one line, make sure there's a new line after
1625       this.print_newline(false, preserve_statement_flags);
1626     }
1628     this._flags.alignment = 0;
1629   }
1630 };
1633 Beautifier.prototype.handle_comment = function(current_token, preserve_statement_flags) {
1634   if (current_token.newlines) {
1635     this.print_newline(false, preserve_statement_flags);
1636   } else {
1637     this._output.trim(true);
1638   }
1640   this._output.space_before_token = true;
1641   this.print_token(current_token);
1642   this.print_newline(false, preserve_statement_flags);
1643 };
1645 Beautifier.prototype.handle_dot = function(current_token) {
1646   if (this.start_of_statement(current_token)) {
1647     // The conditional starts the statement if appropriate.
1648   } else {
1649     this.handle_whitespace_and_comments(current_token, true);
1650   }
1652   if (reserved_array(this._flags.last_token, special_words)) {
1653     this._output.space_before_token = false;
1654   } else {
1655     // allow preserved newlines before dots in general
1656     // force newlines on dots after close paren when break_chained - for bar().baz()
1657     this.allow_wrap_or_preserved_newline(current_token,
1658       this._flags.last_token.text === ')' && this._options.break_chained_methods);
1659   }
1661   // Only unindent chained method dot if this dot starts a new line.
1662   // Otherwise the automatic extra indentation removal will handle the over indent
1663   if (this._options.unindent_chained_methods && this._output.just_added_newline()) {
1664     this.deindent();
1665   }
1667   this.print_token(current_token);
1668 };
1670 Beautifier.prototype.handle_unknown = function(current_token, preserve_statement_flags) {
1671   this.print_token(current_token);
1673   if (current_token.text[current_token.text.length - 1] === '\n') {
1674     this.print_newline(false, preserve_statement_flags);
1675   }
1676 };
1678 Beautifier.prototype.handle_eof = function(current_token) {
1679   // Unwind any open statements
1680   while (this._flags.mode === MODE.Statement) {
1681     this.restore_mode();
1682   }
1683   this.handle_whitespace_and_comments(current_token);
1684 };
1686 module.exports.Beautifier = Beautifier;
1689 /***/ }),
1690 /* 2 */
1691 /***/ (function(module, exports, __webpack_require__) {
1693 "use strict";
1694 /*jshint node:true */
1695 /*
1696   The MIT License (MIT)
1698   Copyright (c) 2007-2018 Einar Lielmanis, Liam Newman, and contributors.
1700   Permission is hereby granted, free of charge, to any person
1701   obtaining a copy of this software and associated documentation files
1702   (the "Software"), to deal in the Software without restriction,
1703   including without limitation the rights to use, copy, modify, merge,
1704   publish, distribute, sublicense, and/or sell copies of the Software,
1705   and to permit persons to whom the Software is furnished to do so,
1706   subject to the following conditions:
1708   The above copyright notice and this permission notice shall be
1709   included in all copies or substantial portions of the Software.
1711   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
1712   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
1713   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
1714   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
1715   BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
1716   ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
1717   CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
1718   SOFTWARE.
1719 */
1723 function OutputLine(parent) {
1724   this.__parent = parent;
1725   this.__character_count = 0;
1726   // use indent_count as a marker for this.__lines that have preserved indentation
1727   this.__indent_count = -1;
1728   this.__alignment_count = 0;
1729   this.__wrap_point_index = 0;
1730   this.__wrap_point_character_count = 0;
1731   this.__wrap_point_indent_count = -1;
1732   this.__wrap_point_alignment_count = 0;
1734   this.__items = [];
1737 OutputLine.prototype.clone_empty = function() {
1738   var line = new OutputLine(this.__parent);
1739   line.set_indent(this.__indent_count, this.__alignment_count);
1740   return line;
1741 };
1743 OutputLine.prototype.item = function(index) {
1744   if (index < 0) {
1745     return this.__items[this.__items.length + index];
1746   } else {
1747     return this.__items[index];
1748   }
1749 };
1751 OutputLine.prototype.has_match = function(pattern) {
1752   for (var lastCheckedOutput = this.__items.length - 1; lastCheckedOutput >= 0; lastCheckedOutput--) {
1753     if (this.__items[lastCheckedOutput].match(pattern)) {
1754       return true;
1755     }
1756   }
1757   return false;
1758 };
1760 OutputLine.prototype.set_indent = function(indent, alignment) {
1761   if (this.is_empty()) {
1762     this.__indent_count = indent || 0;
1763     this.__alignment_count = alignment || 0;
1764     this.__character_count = this.__parent.get_indent_size(this.__indent_count, this.__alignment_count);
1765   }
1766 };
1768 OutputLine.prototype._set_wrap_point = function() {
1769   if (this.__parent.wrap_line_length) {
1770     this.__wrap_point_index = this.__items.length;
1771     this.__wrap_point_character_count = this.__character_count;
1772     this.__wrap_point_indent_count = this.__parent.next_line.__indent_count;
1773     this.__wrap_point_alignment_count = this.__parent.next_line.__alignment_count;
1774   }
1775 };
1777 OutputLine.prototype._should_wrap = function() {
1778   return this.__wrap_point_index &&
1779     this.__character_count > this.__parent.wrap_line_length &&
1780     this.__wrap_point_character_count > this.__parent.next_line.__character_count;
1781 };
1783 OutputLine.prototype._allow_wrap = function() {
1784   if (this._should_wrap()) {
1785     this.__parent.add_new_line();
1786     var next = this.__parent.current_line;
1787     next.set_indent(this.__wrap_point_indent_count, this.__wrap_point_alignment_count);
1788     next.__items = this.__items.slice(this.__wrap_point_index);
1789     this.__items = this.__items.slice(0, this.__wrap_point_index);
1791     next.__character_count += this.__character_count - this.__wrap_point_character_count;
1792     this.__character_count = this.__wrap_point_character_count;
1794     if (next.__items[0] === " ") {
1795       next.__items.splice(0, 1);
1796       next.__character_count -= 1;
1797     }
1798     return true;
1799   }
1800   return false;
1801 };
1803 OutputLine.prototype.is_empty = function() {
1804   return this.__items.length === 0;
1805 };
1807 OutputLine.prototype.last = function() {
1808   if (!this.is_empty()) {
1809     return this.__items[this.__items.length - 1];
1810   } else {
1811     return null;
1812   }
1813 };
1815 OutputLine.prototype.push = function(item) {
1816   this.__items.push(item);
1817   var last_newline_index = item.lastIndexOf('\n');
1818   if (last_newline_index !== -1) {
1819     this.__character_count = item.length - last_newline_index;
1820   } else {
1821     this.__character_count += item.length;
1822   }
1823 };
1825 OutputLine.prototype.pop = function() {
1826   var item = null;
1827   if (!this.is_empty()) {
1828     item = this.__items.pop();
1829     this.__character_count -= item.length;
1830   }
1831   return item;
1832 };
1835 OutputLine.prototype._remove_indent = function() {
1836   if (this.__indent_count > 0) {
1837     this.__indent_count -= 1;
1838     this.__character_count -= this.__parent.indent_size;
1839   }
1840 };
1842 OutputLine.prototype._remove_wrap_indent = function() {
1843   if (this.__wrap_point_indent_count > 0) {
1844     this.__wrap_point_indent_count -= 1;
1845   }
1846 };
1847 OutputLine.prototype.trim = function() {
1848   while (this.last() === ' ') {
1849     this.__items.pop();
1850     this.__character_count -= 1;
1851   }
1852 };
1854 OutputLine.prototype.toString = function() {
1855   var result = '';
1856   if (this.is_empty()) {
1857     if (this.__parent.indent_empty_lines) {
1858       result = this.__parent.get_indent_string(this.__indent_count);
1859     }
1860   } else {
1861     result = this.__parent.get_indent_string(this.__indent_count, this.__alignment_count);
1862     result += this.__items.join('');
1863   }
1864   return result;
1865 };
1867 function IndentStringCache(options, baseIndentString) {
1868   this.__cache = [''];
1869   this.__indent_size = options.indent_size;
1870   this.__indent_string = options.indent_char;
1871   if (!options.indent_with_tabs) {
1872     this.__indent_string = new Array(options.indent_size + 1).join(options.indent_char);
1873   }
1875   // Set to null to continue support for auto detection of base indent
1876   baseIndentString = baseIndentString || '';
1877   if (options.indent_level > 0) {
1878     baseIndentString = new Array(options.indent_level + 1).join(this.__indent_string);
1879   }
1881   this.__base_string = baseIndentString;
1882   this.__base_string_length = baseIndentString.length;
1885 IndentStringCache.prototype.get_indent_size = function(indent, column) {
1886   var result = this.__base_string_length;
1887   column = column || 0;
1888   if (indent < 0) {
1889     result = 0;
1890   }
1891   result += indent * this.__indent_size;
1892   result += column;
1893   return result;
1894 };
1896 IndentStringCache.prototype.get_indent_string = function(indent_level, column) {
1897   var result = this.__base_string;
1898   column = column || 0;
1899   if (indent_level < 0) {
1900     indent_level = 0;
1901     result = '';
1902   }
1903   column += indent_level * this.__indent_size;
1904   this.__ensure_cache(column);
1905   result += this.__cache[column];
1906   return result;
1907 };
1909 IndentStringCache.prototype.__ensure_cache = function(column) {
1910   while (column >= this.__cache.length) {
1911     this.__add_column();
1912   }
1913 };
1915 IndentStringCache.prototype.__add_column = function() {
1916   var column = this.__cache.length;
1917   var indent = 0;
1918   var result = '';
1919   if (this.__indent_size && column >= this.__indent_size) {
1920     indent = Math.floor(column / this.__indent_size);
1921     column -= indent * this.__indent_size;
1922     result = new Array(indent + 1).join(this.__indent_string);
1923   }
1924   if (column) {
1925     result += new Array(column + 1).join(' ');
1926   }
1928   this.__cache.push(result);
1929 };
1931 function Output(options, baseIndentString) {
1932   this.__indent_cache = new IndentStringCache(options, baseIndentString);
1933   this.raw = false;
1934   this._end_with_newline = options.end_with_newline;
1935   this.indent_size = options.indent_size;
1936   this.wrap_line_length = options.wrap_line_length;
1937   this.indent_empty_lines = options.indent_empty_lines;
1938   this.__lines = [];
1939   this.previous_line = null;
1940   this.current_line = null;
1941   this.next_line = new OutputLine(this);
1942   this.space_before_token = false;
1943   this.non_breaking_space = false;
1944   this.previous_token_wrapped = false;
1945   // initialize
1946   this.__add_outputline();
1949 Output.prototype.__add_outputline = function() {
1950   this.previous_line = this.current_line;
1951   this.current_line = this.next_line.clone_empty();
1952   this.__lines.push(this.current_line);
1953 };
1955 Output.prototype.get_line_number = function() {
1956   return this.__lines.length;
1957 };
1959 Output.prototype.get_indent_string = function(indent, column) {
1960   return this.__indent_cache.get_indent_string(indent, column);
1961 };
1963 Output.prototype.get_indent_size = function(indent, column) {
1964   return this.__indent_cache.get_indent_size(indent, column);
1965 };
1967 Output.prototype.is_empty = function() {
1968   return !this.previous_line && this.current_line.is_empty();
1969 };
1971 Output.prototype.add_new_line = function(force_newline) {
1972   // never newline at the start of file
1973   // otherwise, newline only if we didn't just add one or we're forced
1974   if (this.is_empty() ||
1975     (!force_newline && this.just_added_newline())) {
1976     return false;
1977   }
1979   // if raw output is enabled, don't print additional newlines,
1980   // but still return True as though you had
1981   if (!this.raw) {
1982     this.__add_outputline();
1983   }
1984   return true;
1985 };
1987 Output.prototype.get_code = function(eol) {
1988   this.trim(true);
1990   // handle some edge cases where the last tokens
1991   // has text that ends with newline(s)
1992   var last_item = this.current_line.pop();
1993   if (last_item) {
1994     if (last_item[last_item.length - 1] === '\n') {
1995       last_item = last_item.replace(/\n+$/g, '');
1996     }
1997     this.current_line.push(last_item);
1998   }
2000   if (this._end_with_newline) {
2001     this.__add_outputline();
2002   }
2004   var sweet_code = this.__lines.join('\n');
2006   if (eol !== '\n') {
2007     sweet_code = sweet_code.replace(/[\n]/g, eol);
2008   }
2009   return sweet_code;
2010 };
2012 Output.prototype.set_wrap_point = function() {
2013   this.current_line._set_wrap_point();
2014 };
2016 Output.prototype.set_indent = function(indent, alignment) {
2017   indent = indent || 0;
2018   alignment = alignment || 0;
2020   // Next line stores alignment values
2021   this.next_line.set_indent(indent, alignment);
2023   // Never indent your first output indent at the start of the file
2024   if (this.__lines.length > 1) {
2025     this.current_line.set_indent(indent, alignment);
2026     return true;
2027   }
2029   this.current_line.set_indent();
2030   return false;
2031 };
2033 Output.prototype.add_raw_token = function(token) {
2034   for (var x = 0; x < token.newlines; x++) {
2035     this.__add_outputline();
2036   }
2037   this.current_line.set_indent(-1);
2038   this.current_line.push(token.whitespace_before);
2039   this.current_line.push(token.text);
2040   this.space_before_token = false;
2041   this.non_breaking_space = false;
2042   this.previous_token_wrapped = false;
2043 };
2045 Output.prototype.add_token = function(printable_token) {
2046   this.__add_space_before_token();
2047   this.current_line.push(printable_token);
2048   this.space_before_token = false;
2049   this.non_breaking_space = false;
2050   this.previous_token_wrapped = this.current_line._allow_wrap();
2051 };
2053 Output.prototype.__add_space_before_token = function() {
2054   if (this.space_before_token && !this.just_added_newline()) {
2055     if (!this.non_breaking_space) {
2056       this.set_wrap_point();
2057     }
2058     this.current_line.push(' ');
2059   }
2060 };
2062 Output.prototype.remove_indent = function(index) {
2063   var output_length = this.__lines.length;
2064   while (index < output_length) {
2065     this.__lines[index]._remove_indent();
2066     index++;
2067   }
2068   this.current_line._remove_wrap_indent();
2069 };
2071 Output.prototype.trim = function(eat_newlines) {
2072   eat_newlines = (eat_newlines === undefined) ? false : eat_newlines;
2074   this.current_line.trim();
2076   while (eat_newlines && this.__lines.length > 1 &&
2077     this.current_line.is_empty()) {
2078     this.__lines.pop();
2079     this.current_line = this.__lines[this.__lines.length - 1];
2080     this.current_line.trim();
2081   }
2083   this.previous_line = this.__lines.length > 1 ?
2084     this.__lines[this.__lines.length - 2] : null;
2085 };
2087 Output.prototype.just_added_newline = function() {
2088   return this.current_line.is_empty();
2089 };
2091 Output.prototype.just_added_blankline = function() {
2092   return this.is_empty() ||
2093     (this.current_line.is_empty() && this.previous_line.is_empty());
2094 };
2096 Output.prototype.ensure_empty_line_above = function(starts_with, ends_with) {
2097   var index = this.__lines.length - 2;
2098   while (index >= 0) {
2099     var potentialEmptyLine = this.__lines[index];
2100     if (potentialEmptyLine.is_empty()) {
2101       break;
2102     } else if (potentialEmptyLine.item(0).indexOf(starts_with) !== 0 &&
2103       potentialEmptyLine.item(-1) !== ends_with) {
2104       this.__lines.splice(index + 1, 0, new OutputLine(this));
2105       this.previous_line = this.__lines[this.__lines.length - 2];
2106       break;
2107     }
2108     index--;
2109   }
2110 };
2112 module.exports.Output = Output;
2115 /***/ }),
2116 /* 3 */
2117 /***/ (function(module, exports, __webpack_require__) {
2119 "use strict";
2120 /*jshint node:true */
2121 /*
2123   The MIT License (MIT)
2125   Copyright (c) 2007-2018 Einar Lielmanis, Liam Newman, and contributors.
2127   Permission is hereby granted, free of charge, to any person
2128   obtaining a copy of this software and associated documentation files
2129   (the "Software"), to deal in the Software without restriction,
2130   including without limitation the rights to use, copy, modify, merge,
2131   publish, distribute, sublicense, and/or sell copies of the Software,
2132   and to permit persons to whom the Software is furnished to do so,
2133   subject to the following conditions:
2135   The above copyright notice and this permission notice shall be
2136   included in all copies or substantial portions of the Software.
2138   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
2139   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
2140   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
2141   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
2142   BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
2143   ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
2144   CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2145   SOFTWARE.
2146 */
2150 function Token(type, text, newlines, whitespace_before) {
2151   this.type = type;
2152   this.text = text;
2154   // comments_before are
2155   // comments that have a new line before them
2156   // and may or may not have a newline after
2157   // this is a set of comments before
2158   this.comments_before = null; /* inline comment*/
2161   // this.comments_after =  new TokenStream(); // no new line before and newline after
2162   this.newlines = newlines || 0;
2163   this.whitespace_before = whitespace_before || '';
2164   this.parent = null;
2165   this.next = null;
2166   this.previous = null;
2167   this.opened = null;
2168   this.closed = null;
2169   this.directives = null;
2173 module.exports.Token = Token;
2176 /***/ }),
2177 /* 4 */
2178 /***/ (function(module, exports, __webpack_require__) {
2180 "use strict";
2181 /* jshint node: true, curly: false */
2182 // Parts of this section of code is taken from acorn.
2183 //
2184 // Acorn was written by Marijn Haverbeke and released under an MIT
2185 // license. The Unicode regexps (for identifiers and whitespace) were
2186 // taken from [Esprima](http://esprima.org) by Ariya Hidayat.
2187 //
2188 // Git repositories for Acorn are available at
2189 //
2190 //     http://marijnhaverbeke.nl/git/acorn
2191 //     https://github.com/marijnh/acorn.git
2193 // ## Character categories
2198 // acorn used char codes to squeeze the last bit of performance out
2199 // Beautifier is okay without that, so we're using regex
2200 // permit # (23), $ (36), and @ (64). @ is used in ES7 decorators.
2201 // 65 through 91 are uppercase letters.
2202 // permit _ (95).
2203 // 97 through 123 are lowercase letters.
2204 var baseASCIIidentifierStartChars = "\\x23\\x24\\x40\\x41-\\x5a\\x5f\\x61-\\x7a";
2206 // inside an identifier @ is not allowed but 0-9 are.
2207 var baseASCIIidentifierChars = "\\x24\\x30-\\x39\\x41-\\x5a\\x5f\\x61-\\x7a";
2209 // Big ugly regular expressions that match characters in the
2210 // whitespace, identifier, and identifier-start categories. These
2211 // are only applied when a character is found to actually have a
2212 // code point above 128.
2213 var nonASCIIidentifierStartChars = "\\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";
2214 var nonASCIIidentifierChars = "\\u0300-\\u036f\\u0483-\\u0487\\u0591-\\u05bd\\u05bf\\u05c1\\u05c2\\u05c4\\u05c5\\u05c7\\u0610-\\u061a\\u0620-\\u0649\\u0672-\\u06d3\\u06e7-\\u06e8\\u06fb-\\u06fc\\u0730-\\u074a\\u0800-\\u0814\\u081b-\\u0823\\u0825-\\u0827\\u0829-\\u082d\\u0840-\\u0857\\u08e4-\\u08fe\\u0900-\\u0903\\u093a-\\u093c\\u093e-\\u094f\\u0951-\\u0957\\u0962-\\u0963\\u0966-\\u096f\\u0981-\\u0983\\u09bc\\u09be-\\u09c4\\u09c7\\u09c8\\u09d7\\u09df-\\u09e0\\u0a01-\\u0a03\\u0a3c\\u0a3e-\\u0a42\\u0a47\\u0a48\\u0a4b-\\u0a4d\\u0a51\\u0a66-\\u0a71\\u0a75\\u0a81-\\u0a83\\u0abc\\u0abe-\\u0ac5\\u0ac7-\\u0ac9\\u0acb-\\u0acd\\u0ae2-\\u0ae3\\u0ae6-\\u0aef\\u0b01-\\u0b03\\u0b3c\\u0b3e-\\u0b44\\u0b47\\u0b48\\u0b4b-\\u0b4d\\u0b56\\u0b57\\u0b5f-\\u0b60\\u0b66-\\u0b6f\\u0b82\\u0bbe-\\u0bc2\\u0bc6-\\u0bc8\\u0bca-\\u0bcd\\u0bd7\\u0be6-\\u0bef\\u0c01-\\u0c03\\u0c46-\\u0c48\\u0c4a-\\u0c4d\\u0c55\\u0c56\\u0c62-\\u0c63\\u0c66-\\u0c6f\\u0c82\\u0c83\\u0cbc\\u0cbe-\\u0cc4\\u0cc6-\\u0cc8\\u0cca-\\u0ccd\\u0cd5\\u0cd6\\u0ce2-\\u0ce3\\u0ce6-\\u0cef\\u0d02\\u0d03\\u0d46-\\u0d48\\u0d57\\u0d62-\\u0d63\\u0d66-\\u0d6f\\u0d82\\u0d83\\u0dca\\u0dcf-\\u0dd4\\u0dd6\\u0dd8-\\u0ddf\\u0df2\\u0df3\\u0e34-\\u0e3a\\u0e40-\\u0e45\\u0e50-\\u0e59\\u0eb4-\\u0eb9\\u0ec8-\\u0ecd\\u0ed0-\\u0ed9\\u0f18\\u0f19\\u0f20-\\u0f29\\u0f35\\u0f37\\u0f39\\u0f41-\\u0f47\\u0f71-\\u0f84\\u0f86-\\u0f87\\u0f8d-\\u0f97\\u0f99-\\u0fbc\\u0fc6\\u1000-\\u1029\\u1040-\\u1049\\u1067-\\u106d\\u1071-\\u1074\\u1082-\\u108d\\u108f-\\u109d\\u135d-\\u135f\\u170e-\\u1710\\u1720-\\u1730\\u1740-\\u1750\\u1772\\u1773\\u1780-\\u17b2\\u17dd\\u17e0-\\u17e9\\u180b-\\u180d\\u1810-\\u1819\\u1920-\\u192b\\u1930-\\u193b\\u1951-\\u196d\\u19b0-\\u19c0\\u19c8-\\u19c9\\u19d0-\\u19d9\\u1a00-\\u1a15\\u1a20-\\u1a53\\u1a60-\\u1a7c\\u1a7f-\\u1a89\\u1a90-\\u1a99\\u1b46-\\u1b4b\\u1b50-\\u1b59\\u1b6b-\\u1b73\\u1bb0-\\u1bb9\\u1be6-\\u1bf3\\u1c00-\\u1c22\\u1c40-\\u1c49\\u1c5b-\\u1c7d\\u1cd0-\\u1cd2\\u1d00-\\u1dbe\\u1e01-\\u1f15\\u200c\\u200d\\u203f\\u2040\\u2054\\u20d0-\\u20dc\\u20e1\\u20e5-\\u20f0\\u2d81-\\u2d96\\u2de0-\\u2dff\\u3021-\\u3028\\u3099\\u309a\\ua640-\\ua66d\\ua674-\\ua67d\\ua69f\\ua6f0-\\ua6f1\\ua7f8-\\ua800\\ua806\\ua80b\\ua823-\\ua827\\ua880-\\ua881\\ua8b4-\\ua8c4\\ua8d0-\\ua8d9\\ua8f3-\\ua8f7\\ua900-\\ua909\\ua926-\\ua92d\\ua930-\\ua945\\ua980-\\ua983\\ua9b3-\\ua9c0\\uaa00-\\uaa27\\uaa40-\\uaa41\\uaa4c-\\uaa4d\\uaa50-\\uaa59\\uaa7b\\uaae0-\\uaae9\\uaaf2-\\uaaf3\\uabc0-\\uabe1\\uabec\\uabed\\uabf0-\\uabf9\\ufb20-\\ufb28\\ufe00-\\ufe0f\\ufe20-\\ufe26\\ufe33\\ufe34\\ufe4d-\\ufe4f\\uff10-\\uff19\\uff3f";
2215 //var nonASCIIidentifierStart = new RegExp("[" + nonASCIIidentifierStartChars + "]");
2216 //var nonASCIIidentifier = new RegExp("[" + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "]");
2218 var identifierStart = "(?:\\\\u[0-9a-fA-F]{4}|[" + baseASCIIidentifierStartChars + nonASCIIidentifierStartChars + "])";
2219 var identifierChars = "(?:\\\\u[0-9a-fA-F]{4}|[" + baseASCIIidentifierChars + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "])*";
2221 exports.identifier = new RegExp(identifierStart + identifierChars, 'g');
2222 exports.identifierStart = new RegExp(identifierStart);
2223 exports.identifierMatch = new RegExp("(?:\\\\u[0-9a-fA-F]{4}|[" + baseASCIIidentifierChars + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "])+");
2225 var nonASCIIwhitespace = /[\u1680\u180e\u2000-\u200a\u202f\u205f\u3000\ufeff]/; // jshint ignore:line
2227 // Whether a single character denotes a newline.
2229 exports.newline = /[\n\r\u2028\u2029]/;
2231 // Matches a whole line break (where CRLF is considered a single
2232 // line break). Used to count lines.
2234 // in javascript, these two differ
2235 // in python they are the same, different methods are called on them
2236 exports.lineBreak = new RegExp('\r\n|' + exports.newline.source);
2237 exports.allLineBreaks = new RegExp(exports.lineBreak.source, 'g');
2240 /***/ }),
2241 /* 5 */
2242 /***/ (function(module, exports, __webpack_require__) {
2244 "use strict";
2245 /*jshint node:true */
2246 /*
2248   The MIT License (MIT)
2250   Copyright (c) 2007-2018 Einar Lielmanis, Liam Newman, and contributors.
2252   Permission is hereby granted, free of charge, to any person
2253   obtaining a copy of this software and associated documentation files
2254   (the "Software"), to deal in the Software without restriction,
2255   including without limitation the rights to use, copy, modify, merge,
2256   publish, distribute, sublicense, and/or sell copies of the Software,
2257   and to permit persons to whom the Software is furnished to do so,
2258   subject to the following conditions:
2260   The above copyright notice and this permission notice shall be
2261   included in all copies or substantial portions of the Software.
2263   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
2264   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
2265   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
2266   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
2267   BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
2268   ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
2269   CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2270   SOFTWARE.
2271 */
2275 var BaseOptions = __webpack_require__(6).Options;
2277 var validPositionValues = ['before-newline', 'after-newline', 'preserve-newline'];
2279 function Options(options) {
2280   BaseOptions.call(this, options, 'js');
2282   // compatibility, re
2283   var raw_brace_style = this.raw_options.brace_style || null;
2284   if (raw_brace_style === "expand-strict") { //graceful handling of deprecated option
2285     this.raw_options.brace_style = "expand";
2286   } else if (raw_brace_style === "collapse-preserve-inline") { //graceful handling of deprecated option
2287     this.raw_options.brace_style = "collapse,preserve-inline";
2288   } else if (this.raw_options.braces_on_own_line !== undefined) { //graceful handling of deprecated option
2289     this.raw_options.brace_style = this.raw_options.braces_on_own_line ? "expand" : "collapse";
2290     // } else if (!raw_brace_style) { //Nothing exists to set it
2291     //   raw_brace_style = "collapse";
2292   }
2294   //preserve-inline in delimited string will trigger brace_preserve_inline, everything
2295   //else is considered a brace_style and the last one only will have an effect
2297   var brace_style_split = this._get_selection_list('brace_style', ['collapse', 'expand', 'end-expand', 'none', 'preserve-inline']);
2299   this.brace_preserve_inline = false; //Defaults in case one or other was not specified in meta-option
2300   this.brace_style = "collapse";
2302   for (var bs = 0; bs < brace_style_split.length; bs++) {
2303     if (brace_style_split[bs] === "preserve-inline") {
2304       this.brace_preserve_inline = true;
2305     } else {
2306       this.brace_style = brace_style_split[bs];
2307     }
2308   }
2310   this.unindent_chained_methods = this._get_boolean('unindent_chained_methods');
2311   this.break_chained_methods = this._get_boolean('break_chained_methods');
2312   this.space_in_paren = this._get_boolean('space_in_paren');
2313   this.space_in_empty_paren = this._get_boolean('space_in_empty_paren');
2314   this.jslint_happy = this._get_boolean('jslint_happy');
2315   this.space_after_anon_function = this._get_boolean('space_after_anon_function');
2316   this.space_after_named_function = this._get_boolean('space_after_named_function');
2317   this.keep_array_indentation = this._get_boolean('keep_array_indentation');
2318   this.space_before_conditional = this._get_boolean('space_before_conditional', true);
2319   this.unescape_strings = this._get_boolean('unescape_strings');
2320   this.e4x = this._get_boolean('e4x');
2321   this.comma_first = this._get_boolean('comma_first');
2322   this.operator_position = this._get_selection('operator_position', validPositionValues);
2324   // For testing of beautify preserve:start directive
2325   this.test_output_raw = this._get_boolean('test_output_raw');
2327   // force this._options.space_after_anon_function to true if this._options.jslint_happy
2328   if (this.jslint_happy) {
2329     this.space_after_anon_function = true;
2330   }
2333 Options.prototype = new BaseOptions();
2337 module.exports.Options = Options;
2340 /***/ }),
2341 /* 6 */
2342 /***/ (function(module, exports, __webpack_require__) {
2344 "use strict";
2345 /*jshint node:true */
2346 /*
2348   The MIT License (MIT)
2350   Copyright (c) 2007-2018 Einar Lielmanis, Liam Newman, and contributors.
2352   Permission is hereby granted, free of charge, to any person
2353   obtaining a copy of this software and associated documentation files
2354   (the "Software"), to deal in the Software without restriction,
2355   including without limitation the rights to use, copy, modify, merge,
2356   publish, distribute, sublicense, and/or sell copies of the Software,
2357   and to permit persons to whom the Software is furnished to do so,
2358   subject to the following conditions:
2360   The above copyright notice and this permission notice shall be
2361   included in all copies or substantial portions of the Software.
2363   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
2364   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
2365   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
2366   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
2367   BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
2368   ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
2369   CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2370   SOFTWARE.
2371 */
2375 function Options(options, merge_child_field) {
2376   this.raw_options = _mergeOpts(options, merge_child_field);
2378   // Support passing the source text back with no change
2379   this.disabled = this._get_boolean('disabled');
2381   this.eol = this._get_characters('eol', 'auto');
2382   this.end_with_newline = this._get_boolean('end_with_newline');
2383   this.indent_size = this._get_number('indent_size', 4);
2384   this.indent_char = this._get_characters('indent_char', ' ');
2385   this.indent_level = this._get_number('indent_level');
2387   this.preserve_newlines = this._get_boolean('preserve_newlines', true);
2388   this.max_preserve_newlines = this._get_number('max_preserve_newlines', 32786);
2389   if (!this.preserve_newlines) {
2390     this.max_preserve_newlines = 0;
2391   }
2393   this.indent_with_tabs = this._get_boolean('indent_with_tabs', this.indent_char === '\t');
2394   if (this.indent_with_tabs) {
2395     this.indent_char = '\t';
2397     // indent_size behavior changed after 1.8.6
2398     // It used to be that indent_size would be
2399     // set to 1 for indent_with_tabs. That is no longer needed and
2400     // actually doesn't make sense - why not use spaces? Further,
2401     // that might produce unexpected behavior - tabs being used
2402     // for single-column alignment. So, when indent_with_tabs is true
2403     // and indent_size is 1, reset indent_size to 4.
2404     if (this.indent_size === 1) {
2405       this.indent_size = 4;
2406     }
2407   }
2409   // Backwards compat with 1.3.x
2410   this.wrap_line_length = this._get_number('wrap_line_length', this._get_number('max_char'));
2412   this.indent_empty_lines = this._get_boolean('indent_empty_lines');
2414   // valid templating languages ['django', 'erb', 'handlebars', 'php']
2415   // For now, 'auto' = all off for javascript, all on for html (and inline javascript).
2416   // other values ignored
2417   this.templating = this._get_selection_list('templating', ['auto', 'none', 'django', 'erb', 'handlebars', 'php'], ['auto']);
2420 Options.prototype._get_array = function(name, default_value) {
2421   var option_value = this.raw_options[name];
2422   var result = default_value || [];
2423   if (typeof option_value === 'object') {
2424     if (option_value !== null && typeof option_value.concat === 'function') {
2425       result = option_value.concat();
2426     }
2427   } else if (typeof option_value === 'string') {
2428     result = option_value.split(/[^a-zA-Z0-9_\/\-]+/);
2429   }
2430   return result;
2431 };
2433 Options.prototype._get_boolean = function(name, default_value) {
2434   var option_value = this.raw_options[name];
2435   var result = option_value === undefined ? !!default_value : !!option_value;
2436   return result;
2437 };
2439 Options.prototype._get_characters = function(name, default_value) {
2440   var option_value = this.raw_options[name];
2441   var result = default_value || '';
2442   if (typeof option_value === 'string') {
2443     result = option_value.replace(/\\r/, '\r').replace(/\\n/, '\n').replace(/\\t/, '\t');
2444   }
2445   return result;
2446 };
2448 Options.prototype._get_number = function(name, default_value) {
2449   var option_value = this.raw_options[name];
2450   default_value = parseInt(default_value, 10);
2451   if (isNaN(default_value)) {
2452     default_value = 0;
2453   }
2454   var result = parseInt(option_value, 10);
2455   if (isNaN(result)) {
2456     result = default_value;
2457   }
2458   return result;
2459 };
2461 Options.prototype._get_selection = function(name, selection_list, default_value) {
2462   var result = this._get_selection_list(name, selection_list, default_value);
2463   if (result.length !== 1) {
2464     throw new Error(
2465       "Invalid Option Value: The option '" + name + "' can only be one of the following values:\n" +
2466       selection_list + "\nYou passed in: '" + this.raw_options[name] + "'");
2467   }
2469   return result[0];
2470 };
2473 Options.prototype._get_selection_list = function(name, selection_list, default_value) {
2474   if (!selection_list || selection_list.length === 0) {
2475     throw new Error("Selection list cannot be empty.");
2476   }
2478   default_value = default_value || [selection_list[0]];
2479   if (!this._is_valid_selection(default_value, selection_list)) {
2480     throw new Error("Invalid Default Value!");
2481   }
2483   var result = this._get_array(name, default_value);
2484   if (!this._is_valid_selection(result, selection_list)) {
2485     throw new Error(
2486       "Invalid Option Value: The option '" + name + "' can contain only the following values:\n" +
2487       selection_list + "\nYou passed in: '" + this.raw_options[name] + "'");
2488   }
2490   return result;
2491 };
2493 Options.prototype._is_valid_selection = function(result, selection_list) {
2494   return result.length && selection_list.length &&
2495     !result.some(function(item) { return selection_list.indexOf(item) === -1; });
2496 };
2499 // merges child options up with the parent options object
2500 // Example: obj = {a: 1, b: {a: 2}}
2501 //          mergeOpts(obj, 'b')
2502 //
2503 //          Returns: {a: 2}
2504 function _mergeOpts(allOptions, childFieldName) {
2505   var finalOpts = {};
2506   allOptions = _normalizeOpts(allOptions);
2507   var name;
2509   for (name in allOptions) {
2510     if (name !== childFieldName) {
2511       finalOpts[name] = allOptions[name];
2512     }
2513   }
2515   //merge in the per type settings for the childFieldName
2516   if (childFieldName && allOptions[childFieldName]) {
2517     for (name in allOptions[childFieldName]) {
2518       finalOpts[name] = allOptions[childFieldName][name];
2519     }
2520   }
2521   return finalOpts;
2524 function _normalizeOpts(options) {
2525   var convertedOpts = {};
2526   var key;
2528   for (key in options) {
2529     var newKey = key.replace(/-/g, "_");
2530     convertedOpts[newKey] = options[key];
2531   }
2532   return convertedOpts;
2535 module.exports.Options = Options;
2536 module.exports.normalizeOpts = _normalizeOpts;
2537 module.exports.mergeOpts = _mergeOpts;
2540 /***/ }),
2541 /* 7 */
2542 /***/ (function(module, exports, __webpack_require__) {
2544 "use strict";
2545 /*jshint node:true */
2546 /*
2548   The MIT License (MIT)
2550   Copyright (c) 2007-2018 Einar Lielmanis, Liam Newman, and contributors.
2552   Permission is hereby granted, free of charge, to any person
2553   obtaining a copy of this software and associated documentation files
2554   (the "Software"), to deal in the Software without restriction,
2555   including without limitation the rights to use, copy, modify, merge,
2556   publish, distribute, sublicense, and/or sell copies of the Software,
2557   and to permit persons to whom the Software is furnished to do so,
2558   subject to the following conditions:
2560   The above copyright notice and this permission notice shall be
2561   included in all copies or substantial portions of the Software.
2563   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
2564   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
2565   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
2566   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
2567   BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
2568   ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
2569   CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2570   SOFTWARE.
2571 */
2575 var InputScanner = __webpack_require__(8).InputScanner;
2576 var BaseTokenizer = __webpack_require__(9).Tokenizer;
2577 var BASETOKEN = __webpack_require__(9).TOKEN;
2578 var Directives = __webpack_require__(13).Directives;
2579 var acorn = __webpack_require__(4);
2580 var Pattern = __webpack_require__(12).Pattern;
2581 var TemplatablePattern = __webpack_require__(14).TemplatablePattern;
2584 function in_array(what, arr) {
2585   return arr.indexOf(what) !== -1;
2589 var TOKEN = {
2590   START_EXPR: 'TK_START_EXPR',
2591   END_EXPR: 'TK_END_EXPR',
2592   START_BLOCK: 'TK_START_BLOCK',
2593   END_BLOCK: 'TK_END_BLOCK',
2594   WORD: 'TK_WORD',
2595   RESERVED: 'TK_RESERVED',
2596   SEMICOLON: 'TK_SEMICOLON',
2597   STRING: 'TK_STRING',
2598   EQUALS: 'TK_EQUALS',
2599   OPERATOR: 'TK_OPERATOR',
2600   COMMA: 'TK_COMMA',
2601   BLOCK_COMMENT: 'TK_BLOCK_COMMENT',
2602   COMMENT: 'TK_COMMENT',
2603   DOT: 'TK_DOT',
2604   UNKNOWN: 'TK_UNKNOWN',
2605   START: BASETOKEN.START,
2606   RAW: BASETOKEN.RAW,
2607   EOF: BASETOKEN.EOF
2608 };
2611 var directives_core = new Directives(/\/\*/, /\*\//);
2613 var number_pattern = /0[xX][0123456789abcdefABCDEF]*|0[oO][01234567]*|0[bB][01]*|\d+n|(?:\.\d+|\d+\.?\d*)(?:[eE][+-]?\d+)?/;
2615 var digit = /[0-9]/;
2617 // Dot "." must be distinguished from "..." and decimal
2618 var dot_pattern = /[^\d\.]/;
2620 var positionable_operators = (
2621   ">>> === !== " +
2622   "<< && >= ** != == <= >> || ?? |> " +
2623   "< / - + > : & % ? ^ | *").split(' ');
2625 // IMPORTANT: this must be sorted longest to shortest or tokenizing many not work.
2626 // Also, you must update possitionable operators separately from punct
2627 var punct =
2628   ">>>= " +
2629   "... >>= <<= === >>> !== **= " +
2630   "=> ^= :: /= << <= == && -= >= >> != -- += ** || ?? ++ %= &= *= |= |> " +
2631   "= ! ? > < : / ^ - + * & % ~ |";
2633 punct = punct.replace(/[-[\]{}()*+?.,\\^$|#]/g, "\\$&");
2634 // ?. but not if followed by a number 
2635 punct = '\\?\\.(?!\\d) ' + punct;
2636 punct = punct.replace(/ /g, '|');
2638 var punct_pattern = new RegExp(punct);
2640 // words which should always start on new line.
2641 var line_starters = 'continue,try,throw,return,var,let,const,if,switch,case,default,for,while,break,function,import,export'.split(',');
2642 var reserved_words = line_starters.concat(['do', 'in', 'of', 'else', 'get', 'set', 'new', 'catch', 'finally', 'typeof', 'yield', 'async', 'await', 'from', 'as']);
2643 var reserved_word_pattern = new RegExp('^(?:' + reserved_words.join('|') + ')$');
2645 // var template_pattern = /(?:(?:<\?php|<\?=)[\s\S]*?\?>)|(?:<%[\s\S]*?%>)/g;
2647 var in_html_comment;
2649 var Tokenizer = function(input_string, options) {
2650   BaseTokenizer.call(this, input_string, options);
2652   this._patterns.whitespace = this._patterns.whitespace.matching(
2653     /\u00A0\u1680\u180e\u2000-\u200a\u202f\u205f\u3000\ufeff/.source,
2654     /\u2028\u2029/.source);
2656   var pattern_reader = new Pattern(this._input);
2657   var templatable = new TemplatablePattern(this._input)
2658     .read_options(this._options);
2660   this.__patterns = {
2661     template: templatable,
2662     identifier: templatable.starting_with(acorn.identifier).matching(acorn.identifierMatch),
2663     number: pattern_reader.matching(number_pattern),
2664     punct: pattern_reader.matching(punct_pattern),
2665     // comment ends just before nearest linefeed or end of file
2666     comment: pattern_reader.starting_with(/\/\//).until(/[\n\r\u2028\u2029]/),
2667     //  /* ... */ comment ends with nearest */ or end of file
2668     block_comment: pattern_reader.starting_with(/\/\*/).until_after(/\*\//),
2669     html_comment_start: pattern_reader.matching(/<!--/),
2670     html_comment_end: pattern_reader.matching(/-->/),
2671     include: pattern_reader.starting_with(/#include/).until_after(acorn.lineBreak),
2672     shebang: pattern_reader.starting_with(/#!/).until_after(acorn.lineBreak),
2673     xml: pattern_reader.matching(/[\s\S]*?<(\/?)([-a-zA-Z:0-9_.]+|{[\s\S]+?}|!\[CDATA\[[\s\S]*?\]\])(\s+{[\s\S]+?}|\s+[-a-zA-Z:0-9_.]+|\s+[-a-zA-Z:0-9_.]+\s*=\s*('[^']*'|"[^"]*"|{[\s\S]+?}))*\s*(\/?)\s*>/),
2674     single_quote: templatable.until(/['\\\n\r\u2028\u2029]/),
2675     double_quote: templatable.until(/["\\\n\r\u2028\u2029]/),
2676     template_text: templatable.until(/[`\\$]/),
2677     template_expression: templatable.until(/[`}\\]/)
2678   };
2680 };
2681 Tokenizer.prototype = new BaseTokenizer();
2683 Tokenizer.prototype._is_comment = function(current_token) {
2684   return current_token.type === TOKEN.COMMENT || current_token.type === TOKEN.BLOCK_COMMENT || current_token.type === TOKEN.UNKNOWN;
2685 };
2687 Tokenizer.prototype._is_opening = function(current_token) {
2688   return current_token.type === TOKEN.START_BLOCK || current_token.type === TOKEN.START_EXPR;
2689 };
2691 Tokenizer.prototype._is_closing = function(current_token, open_token) {
2692   return (current_token.type === TOKEN.END_BLOCK || current_token.type === TOKEN.END_EXPR) &&
2693     (open_token && (
2694       (current_token.text === ']' && open_token.text === '[') ||
2695       (current_token.text === ')' && open_token.text === '(') ||
2696       (current_token.text === '}' && open_token.text === '{')));
2697 };
2699 Tokenizer.prototype._reset = function() {
2700   in_html_comment = false;
2701 };
2703 Tokenizer.prototype._get_next_token = function(previous_token, open_token) { // jshint unused:false
2704   var token = null;
2705   this._readWhitespace();
2706   var c = this._input.peek();
2708   if (c === null) {
2709     return this._create_token(TOKEN.EOF, '');
2710   }
2712   token = token || this._read_non_javascript(c);
2713   token = token || this._read_string(c);
2714   token = token || this._read_word(previous_token);
2715   token = token || this._read_singles(c);
2716   token = token || this._read_comment(c);
2717   token = token || this._read_regexp(c, previous_token);
2718   token = token || this._read_xml(c, previous_token);
2719   token = token || this._read_punctuation();
2720   token = token || this._create_token(TOKEN.UNKNOWN, this._input.next());
2722   return token;
2723 };
2725 Tokenizer.prototype._read_word = function(previous_token) {
2726   var resulting_string;
2727   resulting_string = this.__patterns.identifier.read();
2728   if (resulting_string !== '') {
2729     resulting_string = resulting_string.replace(acorn.allLineBreaks, '\n');
2730     if (!(previous_token.type === TOKEN.DOT ||
2731         (previous_token.type === TOKEN.RESERVED && (previous_token.text === 'set' || previous_token.text === 'get'))) &&
2732       reserved_word_pattern.test(resulting_string)) {
2733       if (resulting_string === 'in' || resulting_string === 'of') { // hack for 'in' and 'of' operators
2734         return this._create_token(TOKEN.OPERATOR, resulting_string);
2735       }
2736       return this._create_token(TOKEN.RESERVED, resulting_string);
2737     }
2738     return this._create_token(TOKEN.WORD, resulting_string);
2739   }
2741   resulting_string = this.__patterns.number.read();
2742   if (resulting_string !== '') {
2743     return this._create_token(TOKEN.WORD, resulting_string);
2744   }
2745 };
2747 Tokenizer.prototype._read_singles = function(c) {
2748   var token = null;
2749   if (c === '(' || c === '[') {
2750     token = this._create_token(TOKEN.START_EXPR, c);
2751   } else if (c === ')' || c === ']') {
2752     token = this._create_token(TOKEN.END_EXPR, c);
2753   } else if (c === '{') {
2754     token = this._create_token(TOKEN.START_BLOCK, c);
2755   } else if (c === '}') {
2756     token = this._create_token(TOKEN.END_BLOCK, c);
2757   } else if (c === ';') {
2758     token = this._create_token(TOKEN.SEMICOLON, c);
2759   } else if (c === '.' && dot_pattern.test(this._input.peek(1))) {
2760     token = this._create_token(TOKEN.DOT, c);
2761   } else if (c === ',') {
2762     token = this._create_token(TOKEN.COMMA, c);
2763   }
2765   if (token) {
2766     this._input.next();
2767   }
2768   return token;
2769 };
2771 Tokenizer.prototype._read_punctuation = function() {
2772   var resulting_string = this.__patterns.punct.read();
2774   if (resulting_string !== '') {
2775     if (resulting_string === '=') {
2776       return this._create_token(TOKEN.EQUALS, resulting_string);
2777     } else if (resulting_string === '?.') {
2778       return this._create_token(TOKEN.DOT, resulting_string);
2779     } else {
2780       return this._create_token(TOKEN.OPERATOR, resulting_string);
2781     }
2782   }
2783 };
2785 Tokenizer.prototype._read_non_javascript = function(c) {
2786   var resulting_string = '';
2788   if (c === '#') {
2789     if (this._is_first_token()) {
2790       resulting_string = this.__patterns.shebang.read();
2792       if (resulting_string) {
2793         return this._create_token(TOKEN.UNKNOWN, resulting_string.trim() + '\n');
2794       }
2795     }
2797     // handles extendscript #includes
2798     resulting_string = this.__patterns.include.read();
2800     if (resulting_string) {
2801       return this._create_token(TOKEN.UNKNOWN, resulting_string.trim() + '\n');
2802     }
2804     c = this._input.next();
2806     // Spidermonkey-specific sharp variables for circular references. Considered obsolete.
2807     var sharp = '#';
2808     if (this._input.hasNext() && this._input.testChar(digit)) {
2809       do {
2810         c = this._input.next();
2811         sharp += c;
2812       } while (this._input.hasNext() && c !== '#' && c !== '=');
2813       if (c === '#') {
2814         //
2815       } else if (this._input.peek() === '[' && this._input.peek(1) === ']') {
2816         sharp += '[]';
2817         this._input.next();
2818         this._input.next();
2819       } else if (this._input.peek() === '{' && this._input.peek(1) === '}') {
2820         sharp += '{}';
2821         this._input.next();
2822         this._input.next();
2823       }
2824       return this._create_token(TOKEN.WORD, sharp);
2825     }
2827     this._input.back();
2829   } else if (c === '<' && this._is_first_token()) {
2830     resulting_string = this.__patterns.html_comment_start.read();
2831     if (resulting_string) {
2832       while (this._input.hasNext() && !this._input.testChar(acorn.newline)) {
2833         resulting_string += this._input.next();
2834       }
2835       in_html_comment = true;
2836       return this._create_token(TOKEN.COMMENT, resulting_string);
2837     }
2838   } else if (in_html_comment && c === '-') {
2839     resulting_string = this.__patterns.html_comment_end.read();
2840     if (resulting_string) {
2841       in_html_comment = false;
2842       return this._create_token(TOKEN.COMMENT, resulting_string);
2843     }
2844   }
2846   return null;
2847 };
2849 Tokenizer.prototype._read_comment = function(c) {
2850   var token = null;
2851   if (c === '/') {
2852     var comment = '';
2853     if (this._input.peek(1) === '*') {
2854       // peek for comment /* ... */
2855       comment = this.__patterns.block_comment.read();
2856       var directives = directives_core.get_directives(comment);
2857       if (directives && directives.ignore === 'start') {
2858         comment += directives_core.readIgnored(this._input);
2859       }
2860       comment = comment.replace(acorn.allLineBreaks, '\n');
2861       token = this._create_token(TOKEN.BLOCK_COMMENT, comment);
2862       token.directives = directives;
2863     } else if (this._input.peek(1) === '/') {
2864       // peek for comment // ...
2865       comment = this.__patterns.comment.read();
2866       token = this._create_token(TOKEN.COMMENT, comment);
2867     }
2868   }
2869   return token;
2870 };
2872 Tokenizer.prototype._read_string = function(c) {
2873   if (c === '`' || c === "'" || c === '"') {
2874     var resulting_string = this._input.next();
2875     this.has_char_escapes = false;
2877     if (c === '`') {
2878       resulting_string += this._read_string_recursive('`', true, '${');
2879     } else {
2880       resulting_string += this._read_string_recursive(c);
2881     }
2883     if (this.has_char_escapes && this._options.unescape_strings) {
2884       resulting_string = unescape_string(resulting_string);
2885     }
2887     if (this._input.peek() === c) {
2888       resulting_string += this._input.next();
2889     }
2891     resulting_string = resulting_string.replace(acorn.allLineBreaks, '\n');
2893     return this._create_token(TOKEN.STRING, resulting_string);
2894   }
2896   return null;
2897 };
2899 Tokenizer.prototype._allow_regexp_or_xml = function(previous_token) {
2900   // regex and xml can only appear in specific locations during parsing
2901   return (previous_token.type === TOKEN.RESERVED && in_array(previous_token.text, ['return', 'case', 'throw', 'else', 'do', 'typeof', 'yield'])) ||
2902     (previous_token.type === TOKEN.END_EXPR && previous_token.text === ')' &&
2903       previous_token.opened.previous.type === TOKEN.RESERVED && in_array(previous_token.opened.previous.text, ['if', 'while', 'for'])) ||
2904     (in_array(previous_token.type, [TOKEN.COMMENT, TOKEN.START_EXPR, TOKEN.START_BLOCK, TOKEN.START,
2905       TOKEN.END_BLOCK, TOKEN.OPERATOR, TOKEN.EQUALS, TOKEN.EOF, TOKEN.SEMICOLON, TOKEN.COMMA
2906     ]));
2907 };
2909 Tokenizer.prototype._read_regexp = function(c, previous_token) {
2911   if (c === '/' && this._allow_regexp_or_xml(previous_token)) {
2912     // handle regexp
2913     //
2914     var resulting_string = this._input.next();
2915     var esc = false;
2917     var in_char_class = false;
2918     while (this._input.hasNext() &&
2919       ((esc || in_char_class || this._input.peek() !== c) &&
2920         !this._input.testChar(acorn.newline))) {
2921       resulting_string += this._input.peek();
2922       if (!esc) {
2923         esc = this._input.peek() === '\\';
2924         if (this._input.peek() === '[') {
2925           in_char_class = true;
2926         } else if (this._input.peek() === ']') {
2927           in_char_class = false;
2928         }
2929       } else {
2930         esc = false;
2931       }
2932       this._input.next();
2933     }
2935     if (this._input.peek() === c) {
2936       resulting_string += this._input.next();
2938       // regexps may have modifiers /regexp/MOD , so fetch those, too
2939       // Only [gim] are valid, but if the user puts in garbage, do what we can to take it.
2940       resulting_string += this._input.read(acorn.identifier);
2941     }
2942     return this._create_token(TOKEN.STRING, resulting_string);
2943   }
2944   return null;
2945 };
2947 Tokenizer.prototype._read_xml = function(c, previous_token) {
2949   if (this._options.e4x && c === "<" && this._allow_regexp_or_xml(previous_token)) {
2950     var xmlStr = '';
2951     var match = this.__patterns.xml.read_match();
2952     // handle e4x xml literals
2953     //
2954     if (match) {
2955       // Trim root tag to attempt to
2956       var rootTag = match[2].replace(/^{\s+/, '{').replace(/\s+}$/, '}');
2957       var isCurlyRoot = rootTag.indexOf('{') === 0;
2958       var depth = 0;
2959       while (match) {
2960         var isEndTag = !!match[1];
2961         var tagName = match[2];
2962         var isSingletonTag = (!!match[match.length - 1]) || (tagName.slice(0, 8) === "![CDATA[");
2963         if (!isSingletonTag &&
2964           (tagName === rootTag || (isCurlyRoot && tagName.replace(/^{\s+/, '{').replace(/\s+}$/, '}')))) {
2965           if (isEndTag) {
2966             --depth;
2967           } else {
2968             ++depth;
2969           }
2970         }
2971         xmlStr += match[0];
2972         if (depth <= 0) {
2973           break;
2974         }
2975         match = this.__patterns.xml.read_match();
2976       }
2977       // if we didn't close correctly, keep unformatted.
2978       if (!match) {
2979         xmlStr += this._input.match(/[\s\S]*/g)[0];
2980       }
2981       xmlStr = xmlStr.replace(acorn.allLineBreaks, '\n');
2982       return this._create_token(TOKEN.STRING, xmlStr);
2983     }
2984   }
2986   return null;
2987 };
2989 function unescape_string(s) {
2990   // You think that a regex would work for this
2991   // return s.replace(/\\x([0-9a-f]{2})/gi, function(match, val) {
2992   //         return String.fromCharCode(parseInt(val, 16));
2993   //     })
2994   // However, dealing with '\xff', '\\xff', '\\\xff' makes this more fun.
2995   var out = '',
2996     escaped = 0;
2998   var input_scan = new InputScanner(s);
2999   var matched = null;
3001   while (input_scan.hasNext()) {
3002     // Keep any whitespace, non-slash characters
3003     // also keep slash pairs.
3004     matched = input_scan.match(/([\s]|[^\\]|\\\\)+/g);
3006     if (matched) {
3007       out += matched[0];
3008     }
3010     if (input_scan.peek() === '\\') {
3011       input_scan.next();
3012       if (input_scan.peek() === 'x') {
3013         matched = input_scan.match(/x([0-9A-Fa-f]{2})/g);
3014       } else if (input_scan.peek() === 'u') {
3015         matched = input_scan.match(/u([0-9A-Fa-f]{4})/g);
3016       } else {
3017         out += '\\';
3018         if (input_scan.hasNext()) {
3019           out += input_scan.next();
3020         }
3021         continue;
3022       }
3024       // If there's some error decoding, return the original string
3025       if (!matched) {
3026         return s;
3027       }
3029       escaped = parseInt(matched[1], 16);
3031       if (escaped > 0x7e && escaped <= 0xff && matched[0].indexOf('x') === 0) {
3032         // we bail out on \x7f..\xff,
3033         // leaving whole string escaped,
3034         // as it's probably completely binary
3035         return s;
3036       } else if (escaped >= 0x00 && escaped < 0x20) {
3037         // leave 0x00...0x1f escaped
3038         out += '\\' + matched[0];
3039         continue;
3040       } else if (escaped === 0x22 || escaped === 0x27 || escaped === 0x5c) {
3041         // single-quote, apostrophe, backslash - escape these
3042         out += '\\' + String.fromCharCode(escaped);
3043       } else {
3044         out += String.fromCharCode(escaped);
3045       }
3046     }
3047   }
3049   return out;
3052 // handle string
3053 //
3054 Tokenizer.prototype._read_string_recursive = function(delimiter, allow_unescaped_newlines, start_sub) {
3055   var current_char;
3056   var pattern;
3057   if (delimiter === '\'') {
3058     pattern = this.__patterns.single_quote;
3059   } else if (delimiter === '"') {
3060     pattern = this.__patterns.double_quote;
3061   } else if (delimiter === '`') {
3062     pattern = this.__patterns.template_text;
3063   } else if (delimiter === '}') {
3064     pattern = this.__patterns.template_expression;
3065   }
3067   var resulting_string = pattern.read();
3068   var next = '';
3069   while (this._input.hasNext()) {
3070     next = this._input.next();
3071     if (next === delimiter ||
3072       (!allow_unescaped_newlines && acorn.newline.test(next))) {
3073       this._input.back();
3074       break;
3075     } else if (next === '\\' && this._input.hasNext()) {
3076       current_char = this._input.peek();
3078       if (current_char === 'x' || current_char === 'u') {
3079         this.has_char_escapes = true;
3080       } else if (current_char === '\r' && this._input.peek(1) === '\n') {
3081         this._input.next();
3082       }
3083       next += this._input.next();
3084     } else if (start_sub) {
3085       if (start_sub === '${' && next === '$' && this._input.peek() === '{') {
3086         next += this._input.next();
3087       }
3089       if (start_sub === next) {
3090         if (delimiter === '`') {
3091           next += this._read_string_recursive('}', allow_unescaped_newlines, '`');
3092         } else {
3093           next += this._read_string_recursive('`', allow_unescaped_newlines, '${');
3094         }
3095         if (this._input.hasNext()) {
3096           next += this._input.next();
3097         }
3098       }
3099     }
3100     next += pattern.read();
3101     resulting_string += next;
3102   }
3104   return resulting_string;
3105 };
3107 module.exports.Tokenizer = Tokenizer;
3108 module.exports.TOKEN = TOKEN;
3109 module.exports.positionable_operators = positionable_operators.slice();
3110 module.exports.line_starters = line_starters.slice();
3113 /***/ }),
3114 /* 8 */
3115 /***/ (function(module, exports, __webpack_require__) {
3117 "use strict";
3118 /*jshint node:true */
3119 /*
3121   The MIT License (MIT)
3123   Copyright (c) 2007-2018 Einar Lielmanis, Liam Newman, and contributors.
3125   Permission is hereby granted, free of charge, to any person
3126   obtaining a copy of this software and associated documentation files
3127   (the "Software"), to deal in the Software without restriction,
3128   including without limitation the rights to use, copy, modify, merge,
3129   publish, distribute, sublicense, and/or sell copies of the Software,
3130   and to permit persons to whom the Software is furnished to do so,
3131   subject to the following conditions:
3133   The above copyright notice and this permission notice shall be
3134   included in all copies or substantial portions of the Software.
3136   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
3137   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
3138   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
3139   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
3140   BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
3141   ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
3142   CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
3143   SOFTWARE.
3144 */
3148 var regexp_has_sticky = RegExp.prototype.hasOwnProperty('sticky');
3150 function InputScanner(input_string) {
3151   this.__input = input_string || '';
3152   this.__input_length = this.__input.length;
3153   this.__position = 0;
3156 InputScanner.prototype.restart = function() {
3157   this.__position = 0;
3158 };
3160 InputScanner.prototype.back = function() {
3161   if (this.__position > 0) {
3162     this.__position -= 1;
3163   }
3164 };
3166 InputScanner.prototype.hasNext = function() {
3167   return this.__position < this.__input_length;
3168 };
3170 InputScanner.prototype.next = function() {
3171   var val = null;
3172   if (this.hasNext()) {
3173     val = this.__input.charAt(this.__position);
3174     this.__position += 1;
3175   }
3176   return val;
3177 };
3179 InputScanner.prototype.peek = function(index) {
3180   var val = null;
3181   index = index || 0;
3182   index += this.__position;
3183   if (index >= 0 && index < this.__input_length) {
3184     val = this.__input.charAt(index);
3185   }
3186   return val;
3187 };
3189 // This is a JavaScript only helper function (not in python)
3190 // Javascript doesn't have a match method
3191 // and not all implementation support "sticky" flag.
3192 // If they do not support sticky then both this.match() and this.test() method
3193 // must get the match and check the index of the match.
3194 // If sticky is supported and set, this method will use it.
3195 // Otherwise it will check that global is set, and fall back to the slower method.
3196 InputScanner.prototype.__match = function(pattern, index) {
3197   pattern.lastIndex = index;
3198   var pattern_match = pattern.exec(this.__input);
3200   if (pattern_match && !(regexp_has_sticky && pattern.sticky)) {
3201     if (pattern_match.index !== index) {
3202       pattern_match = null;
3203     }
3204   }
3206   return pattern_match;
3207 };
3209 InputScanner.prototype.test = function(pattern, index) {
3210   index = index || 0;
3211   index += this.__position;
3213   if (index >= 0 && index < this.__input_length) {
3214     return !!this.__match(pattern, index);
3215   } else {
3216     return false;
3217   }
3218 };
3220 InputScanner.prototype.testChar = function(pattern, index) {
3221   // test one character regex match
3222   var val = this.peek(index);
3223   pattern.lastIndex = 0;
3224   return val !== null && pattern.test(val);
3225 };
3227 InputScanner.prototype.match = function(pattern) {
3228   var pattern_match = this.__match(pattern, this.__position);
3229   if (pattern_match) {
3230     this.__position += pattern_match[0].length;
3231   } else {
3232     pattern_match = null;
3233   }
3234   return pattern_match;
3235 };
3237 InputScanner.prototype.read = function(starting_pattern, until_pattern, until_after) {
3238   var val = '';
3239   var match;
3240   if (starting_pattern) {
3241     match = this.match(starting_pattern);
3242     if (match) {
3243       val += match[0];
3244     }
3245   }
3246   if (until_pattern && (match || !starting_pattern)) {
3247     val += this.readUntil(until_pattern, until_after);
3248   }
3249   return val;
3250 };
3252 InputScanner.prototype.readUntil = function(pattern, until_after) {
3253   var val = '';
3254   var match_index = this.__position;
3255   pattern.lastIndex = this.__position;
3256   var pattern_match = pattern.exec(this.__input);
3257   if (pattern_match) {
3258     match_index = pattern_match.index;
3259     if (until_after) {
3260       match_index += pattern_match[0].length;
3261     }
3262   } else {
3263     match_index = this.__input_length;
3264   }
3266   val = this.__input.substring(this.__position, match_index);
3267   this.__position = match_index;
3268   return val;
3269 };
3271 InputScanner.prototype.readUntilAfter = function(pattern) {
3272   return this.readUntil(pattern, true);
3273 };
3275 InputScanner.prototype.get_regexp = function(pattern, match_from) {
3276   var result = null;
3277   var flags = 'g';
3278   if (match_from && regexp_has_sticky) {
3279     flags = 'y';
3280   }
3281   // strings are converted to regexp
3282   if (typeof pattern === "string" && pattern !== '') {
3283     // result = new RegExp(pattern.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'), flags);
3284     result = new RegExp(pattern, flags);
3285   } else if (pattern) {