zoukankan      html  css  js  c++  java
  • jsbeautifier + CScript/WScript/JavaScript 编程实现 JavaScript、HTML、CSS 代码格式化 js 脚本命令行工具 并集成到 EditPlus

    
    /*
     * Source Code File Name:
     *            Microshaoft.beautify.CScript.js
     * Microshaoft invent for EditPlus user tool by using WScript");
     * Thanks for "http://jsbeautifier.org/" supply \"https://github.com/einars/js-beautify\"");
     * JavaScript Source References:
     * https://github.com/einars/js-beautify/blob/master/beautify-css.js
     * https://github.com/einars/js-beautify/blob/master/beautify-html.js
     * https://github.com/einars/js-beautify/blob/master/beautify.js
     * https://github.com/einars/js-beautify/blob/master/unpackers/javascriptobfuscator_unpacker.js
     * https://github.com/einars/js-beautify/blob/master/unpackers/myobfuscate_unpacker.js
     * https://github.com/einars/js-beautify/blob/master/unpackers/p_a_c_k_e_r_unpacker.js
     * https://github.com/einars/js-beautify/blob/master/unpackers/urlencode_unpacker.js
     * https://github.com/einars/js-beautify/blob/master/tests/sanitytest.js
     * http://jsbeautifier.org/ HTML source
     */
    // add by Microshaoft begin ===========================================================
    //程序开始
    var args  = WScript.Arguments;
    var s = args(0);
    var fso = new ActiveXObject("Scripting.FileSystemObject");
    // Open the file for input.
    var f = fso.OpenTextFile(s, 1);
    s = "";
    // Read from the file and display the results.
    while (!f.AtEndOfStream)
    {
        s += f.ReadAll();
    }
    f.Close();
    //var s = "adsaasd";
    // add by Microshaoft end ===========================================================
    /*jslint onevar: false, plusplus: false */
    /*
     JS Beautifier
    ---------------
      Written by Einar Lielmanis, <einar@jsbeautifier.org>
          http://jsbeautifier.org/
      Originally converted to javascript by Vital, <vital76@gmail.com>
      "End braces on own line" added by Chris J. Shull, <chrisjshull@gmail.com>
      You are free to use this in any way you want, in case you find this useful or working for you.
      Usage:
        js_beautify(js_source_text);
        js_beautify(js_source_text, options);
      The options are:
        indent_size (default 4)          ?? indentation size,
        indent_char (default space)      ?? character to indent with,
        preserve_newlines (default true) ?? whether existing line breaks should be preserved,
        preserve_max_newlines (default unlimited) - maximum number of line breaks to be preserved in one chunk,
        jslint_happy (default false) ?? if true, then jslint-stricter mode is enforced.
                jslint_happy   !jslint_happy
                ---------------------------------
                 function ()      function()
        brace_style (default "collapse") - "collapse" | "expand" | "end-expand" | "expand-strict"
                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.
                expand-strict: put brace on own line even in such cases:
                    var a =
                    {
                        a: 5,
                        b: 6
                    }
                This mode may break your scripts - e.g "return { a: 1 }" will be broken into two lines, so beware.
        space_before_conditional: should the space before conditional statement be added, "if(true)" vs "if (true)"
        e.g
        js_beautify(js_source_text, {
          'indent_size': 1,
          'indent_char': '\t'
        });
    */
    function js_beautify(js_source_text, options)
    // add by Microshaoft begin ===========================================================::
    //: String
    // add by Microshaoft end ===========================================================
    {
        //return "";
        var input, output, token_text, last_type, last_text, last_last_text, last_word, flags, flag_store, indent_string;
        var whitespace, wordchar, punct, parser_pos, line_starters, digits;
        var prefix, token_type, do_block_just_closed;
        var wanted_newline, just_added_newline, n_newlines;
        var preindent_string = '';
        // Some interpreters have unexpected results with foo = baz || bar;
        options = options ? options : {};
        var opt_brace_style;
        // compatibility
        if (options.space_after_anon_function !== undefined && options.jslint_happy === undefined)
        {
            options.jslint_happy = options.space_after_anon_function;
        }
        if (options.braces_on_own_line !== undefined)
        { //graceful handling of deprecated option
            opt_brace_style = options.braces_on_own_line ? "expand" : "collapse";
        }
        opt_brace_style = options.brace_style ? options.brace_style : (opt_brace_style ? opt_brace_style : "collapse");
        var opt_indent_size = options.indent_size ? options.indent_size : 4;
        var opt_indent_char = options.indent_char ? options.indent_char : ' ';
        var opt_preserve_newlines = typeof options.preserve_newlines === 'undefined' ? true : options.preserve_newlines;
        var opt_max_preserve_newlines = typeof options.max_preserve_newlines === 'undefined' ? false : options.max_preserve_newlines;
        var opt_jslint_happy = options.jslint_happy === 'undefined' ? false : options.jslint_happy;
        var opt_keep_array_indentation = typeof options.keep_array_indentation === 'undefined' ? false : options.keep_array_indentation;
        var opt_space_before_conditional = typeof options.space_before_conditional === 'undefined' ? true : options.space_before_conditional;
        var opt_indent_case = typeof options.indent_case === 'undefined' ? false : options.indent_case;
        just_added_newline = false;
        // cache the source's length.
        var input_length = js_source_text.length;
        function trim_output(eat_newlines)
        {
            eat_newlines = typeof eat_newlines === 'undefined' ? false : eat_newlines;
            while (output.length && (output[output.length - 1] === ' ' || output[output.length - 1] === indent_string || output[output.length - 1] === preindent_string || (eat_newlines && (output[output.length - 1] === '\n' || output[output.length - 1] === '\r'))))
            {
                output.pop();
            }
        }
        function trim(s)
        {
            return s.replace(/^\s\s*|\s\s*$/, '');
        }
        function force_newline()
        {
            var old_keep_array_indentation = opt_keep_array_indentation;
            opt_keep_array_indentation = false;
            print_newline()
            opt_keep_array_indentation = old_keep_array_indentation;
        }
        function print_newline(ignore_repeated)
        {
            flags.eat_next_space = false;
            if (opt_keep_array_indentation && is_array(flags.mode))
            {
                return;
            }
            ignore_repeated = typeof ignore_repeated === 'undefined' ? true : ignore_repeated;
            flags.if_line = false;
            trim_output();
            if (!output.length)
            {
                return; // no newline on start of file
            }
            if (output[output.length - 1] !== "\n" || !ignore_repeated)
            {
                just_added_newline = true;
                output.push("\n");
            }
            if (preindent_string)
            {
                output.push(preindent_string);
            }
            for (var i = 0; i < flags.indentation_level; i += 1)
            {
                output.push(indent_string);
            }
            if (flags.var_line && flags.var_line_reindented)
            {
                output.push(indent_string); // skip space-stuffing, if indenting with a tab
            }
            if (flags.case_body)
            {
                output.push(indent_string);
            }
        }
        function print_single_space()
        {
            if (last_type === 'TK_COMMENT')
            {
                // no you will not print just a space after a comment
                return print_newline(true);
            }
            if (flags.eat_next_space)
            {
                flags.eat_next_space = false;
                return;
            }
            var last_output = ' ';
            if (output.length)
            {
                last_output = output[output.length - 1];
            }
            if (last_output !== ' ' && last_output !== '\n' && last_output !== indent_string)
            { // prevent occassional duplicate space
                output.push(' ');
            }
        }
        function print_token()
        {
            just_added_newline = false;
            flags.eat_next_space = false;
            output.push(token_text);
        }
        function indent()
        {
            flags.indentation_level += 1;
        }
        function remove_indent()
        {
            if (output.length && output[output.length - 1] === indent_string)
            {
                output.pop();
            }
        }
        function set_mode(mode)
        {
            if (flags)
            {
                flag_store.push(flags);
            }
            flags =
            {
                previous_mode: flags ? flags.mode : 'BLOCK',
                mode: mode,
                var_line: false,
                var_line_tainted: false,
                var_line_reindented: false,
                in_html_comment: false,
                if_line: false,
                in_case: false,
                case_body: false,
                eat_next_space: false,
                indentation_baseline: -1,
                indentation_level: (flags ? flags.indentation_level + (flags.case_body ? 1 : 0) + ((flags.var_line && flags.var_line_reindented) ? 1 : 0) : 0),
                ternary_depth: 0
            };
        }
        function is_array(mode)
        {
            return mode === '[EXPRESSION]' || mode === '[INDENTED-EXPRESSION]';
        }
        function is_expression(mode)
        {
            return in_array(mode, ['[EXPRESSION]', '(EXPRESSION)', '(FOR-EXPRESSION)', '(COND-EXPRESSION)']);
        }
        function restore_mode()
        {
            do_block_just_closed = flags.mode === 'DO_BLOCK';
            if (flag_store.length > 0)
            {
                var mode = flags.mode;
                flags = flag_store.pop();
                flags.previous_mode = mode;
            }
        }
        function all_lines_start_with(lines, c)
        {
            for (var i = 0; i < lines.length; i++)
            {
                if (trim(lines[i])[0] != c)
                {
                    return false;
                }
            }
            return true;
        }
        function is_special_word(word)
        {
            return in_array(word, ['case', 'return', 'do', 'if', 'throw', 'else']);
        }
        function in_array(what, arr)
        {
            for (var i = 0; i < arr.length; i += 1)
            {
                if (arr[i] === what)
                {
                    return true;
                }
            }
            return false;
        }
        function look_up(exclude)
        {
            var local_pos = parser_pos;
            var c = input.charAt(local_pos);
            while (in_array(c, whitespace) && c != exclude)
            {
                local_pos++;
                if (local_pos >= input_length) return 0;
                c = input.charAt(local_pos);
            }
            return c;
        }
        function get_next_token()
        {
            n_newlines = 0;
            if (parser_pos >= input_length)
            {
                return ['', 'TK_EOF'];
            }
            wanted_newline = false;
            var c = input.charAt(parser_pos);
            parser_pos += 1;
            var keep_whitespace = opt_keep_array_indentation && is_array(flags.mode);
            if (keep_whitespace)
            {
                //
                // slight mess to allow nice preservation of array indentation and reindent that correctly
                // first time when we get to the arrays:
                // var a = [
                // ....'something'
                // we make note of whitespace_count = 4 into flags.indentation_baseline
                // so we know that 4 whitespaces in original source match indent_level of reindented source
                //
                // and afterwards, when we get to
                //    'something,
                // .......'something else'
                // we know that this should be indented to indent_level + (7 - indentation_baseline) spaces
                //
                var whitespace_count = 0;
                while (in_array(c, whitespace))
                {
                    if (c === "\n")
                    {
                        trim_output();
                        output.push("\n");
                        just_added_newline = true;
                        whitespace_count = 0;
                    }
                    else
                    {
                        if (c === '\t')
                        {
                            whitespace_count += 4;
                        }
                        else if (c === '\r')
                        {
                            // nothing
                        }
                        else
                        {
                            whitespace_count += 1;
                        }
                    }
                    if (parser_pos >= input_length)
                    {
                        return ['', 'TK_EOF'];
                    }
                    c = input.charAt(parser_pos);
                    parser_pos += 1;
                }
                if (flags.indentation_baseline === -1)
                {
                    flags.indentation_baseline = whitespace_count;
                }
                if (just_added_newline)
                {
                    var i;
                    for (i = 0; i < flags.indentation_level + 1; i += 1)
                    {
                        output.push(indent_string);
                    }
                    if (flags.indentation_baseline !== -1)
                    {
                        for (i = 0; i < whitespace_count - flags.indentation_baseline; i++)
                        {
                            output.push(' ');
                        }
                    }
                }
            }
            else
            {
                while (in_array(c, whitespace))
                {
                    if (c === "\n")
                    {
                        n_newlines += ((opt_max_preserve_newlines) ? (n_newlines <= opt_max_preserve_newlines) ? 1 : 0 : 1);
                    }
                    if (parser_pos >= input_length)
                    {
                        return ['', 'TK_EOF'];
                    }
                    c = input.charAt(parser_pos);
                    parser_pos += 1;
                }
                if (opt_preserve_newlines)
                {
                    if (n_newlines > 1)
                    {
                        for (i = 0; i < n_newlines; i += 1)
                        {
                            print_newline(i === 0);
                            just_added_newline = true;
                        }
                    }
                }
                wanted_newline = n_newlines > 0;
            }
            if (in_array(c, wordchar))
            {
                if (parser_pos < input_length)
                {
                    while (in_array(input.charAt(parser_pos), wordchar))
                    {
                        c += input.charAt(parser_pos);
                        parser_pos += 1;
                        if (parser_pos === input_length)
                        {
                            break;
                        }
                    }
                }
                // small and surprisingly unugly hack for 1E-10 representation
                if (parser_pos !== input_length && c.match(/^[0-9]+[Ee]$/) && (input.charAt(parser_pos) === '-' || input.charAt(parser_pos) === '+'))
                {
                    var sign = input.charAt(parser_pos);
                    parser_pos += 1;
                    var t = get_next_token(parser_pos);
                    c += sign + t[0];
                    return [c, 'TK_WORD'];
                }
                if (c === 'in')
                { // hack for 'in' operator
                    return [c, 'TK_OPERATOR'];
                }
                if (wanted_newline && last_type !== 'TK_OPERATOR' && last_type !== 'TK_EQUALS' && !flags.if_line && (opt_preserve_newlines || last_text !== 'var'))
                {
                    print_newline();
                }
                return [c, 'TK_WORD'];
            }
            if (c === '(' || c === '[')
            {
                return [c, 'TK_START_EXPR'];
            }
            if (c === ')' || c === ']')
            {
                return [c, 'TK_END_EXPR'];
            }
            if (c === '{')
            {
                return [c, 'TK_START_BLOCK'];
            }
            if (c === '}')
            {
                return [c, 'TK_END_BLOCK'];
            }
            if (c === ';')
            {
                return [c, 'TK_SEMICOLON'];
            }
            if (c === '/')
            {
                var comment = '';
                // peek for comment /* ... */
                var inline_comment = true;
                if (input.charAt(parser_pos) === '*')
                {
                    parser_pos += 1;
                    if (parser_pos < input_length)
                    {
                        while (!(input.charAt(parser_pos) === '*' && input.charAt(parser_pos + 1) && input.charAt(parser_pos + 1) === '/') && parser_pos < input_length)
                        {
                            c = input.charAt(parser_pos);
                            comment += c;
                            if (c === '\x0d' || c === '\x0a')
                            {
                                inline_comment = false;
                            }
                            parser_pos += 1;
                            if (parser_pos >= input_length)
                            {
                                break;
                            }
                        }
                    }
                    parser_pos += 2;
                    if (inline_comment && n_newlines == 0)
                    {
                        return ['/*' + comment + '*/', 'TK_INLINE_COMMENT'];
                    }
                    else
                    {
                        return ['/*' + comment + '*/', 'TK_BLOCK_COMMENT'];
                    }
                }
                // peek for comment // ...
                if (input.charAt(parser_pos) === '/')
                {
                    comment = c;
                    while (input.charAt(parser_pos) !== '\r' && input.charAt(parser_pos) !== '\n')
                    {
                        comment += input.charAt(parser_pos);
                        parser_pos += 1;
                        if (parser_pos >= input_length)
                        {
                            break;
                        }
                    }
                    parser_pos += 1;
                    if (wanted_newline)
                    {
                        print_newline();
                    }
                    return [comment, 'TK_COMMENT'];
                }
            }
            if (c === "'" || // string
            c === '"' || // string
            (c === '/' && ((last_type === 'TK_WORD' && is_special_word(last_text)) || (last_text === ')' && in_array(flags.previous_mode, ['(COND-EXPRESSION)', '(FOR-EXPRESSION)'])) || (last_type === 'TK_COMMENT' || last_type === 'TK_START_EXPR' || last_type === 'TK_START_BLOCK' || last_type === 'TK_END_BLOCK' || last_type === 'TK_OPERATOR' || last_type === 'TK_EQUALS' || last_type === 'TK_EOF' || last_type === 'TK_SEMICOLON'))))
            { // regexp
                var sep = c;
                var esc = false;
                var resulting_string = c;
                if (parser_pos < input_length)
                {
                    if (sep === '/')
                    {
                        //
                        // handle regexp separately...
                        //
                        var in_char_class = false;
                        while (esc || in_char_class || input.charAt(parser_pos) !== sep)
                        {
                            resulting_string += input.charAt(parser_pos);
                            if (!esc)
                            {
                                esc = input.charAt(parser_pos) === '\\';
                                if (input.charAt(parser_pos) === '[')
                                {
                                    in_char_class = true;
                                }
                                else if (input.charAt(parser_pos) === ']')
                                {
                                    in_char_class = false;
                                }
                            }
                            else
                            {
                                esc = false;
                            }
                            parser_pos += 1;
                            if (parser_pos >= input_length)
                            {
                                // incomplete string/rexp when end-of-file reached.
                                // bail out with what had been received so far.
                                return [resulting_string, 'TK_STRING'];
                            }
                        }
                    }
                    else
                    {
                        //
                        // and handle string also separately
                        //
                        while (esc || input.charAt(parser_pos) !== sep)
                        {
                            resulting_string += input.charAt(parser_pos);
                            if (!esc)
                            {
                                esc = input.charAt(parser_pos) === '\\';
                            }
                            else
                            {
                                esc = false;
                            }
                            parser_pos += 1;
                            if (parser_pos >= input_length)
                            {
                                // incomplete string/rexp when end-of-file reached.
                                // bail out with what had been received so far.
                                return [resulting_string, 'TK_STRING'];
                            }
                        }
                    }
                }
                parser_pos += 1;
                resulting_string += sep;
                if (sep === '/')
                {
                    // regexps may have modifiers /regexp/MOD , so fetch those, too
                    while (parser_pos < input_length && in_array(input.charAt(parser_pos), wordchar))
                    {
                        resulting_string += input.charAt(parser_pos);
                        parser_pos += 1;
                    }
                }
                return [resulting_string, 'TK_STRING'];
            }
            if (c === '#')
            {
                if (output.length === 0 && input.charAt(parser_pos) === '!')
                {
                    // shebang
                    resulting_string = c;
                    while (parser_pos < input_length && c != '\n')
                    {
                        c = input.charAt(parser_pos);
                        resulting_string += c;
                        parser_pos += 1;
                    }
                    output.push(trim(resulting_string) + '\n');
                    print_newline();
                    return get_next_token();
                }
                // Spidermonkey-specific sharp variables for circular references
                // https://developer.mozilla.org/En/Sharp_variables_in_JavaScript
                // http://mxr.mozilla.org/mozilla-central/source/js/src/jsscan.cpp around line 1935
                var sharp = '#';
                if (parser_pos < input_length && in_array(input.charAt(parser_pos), digits))
                {
                    do
                    {
                        c = input.charAt(parser_pos);
                        sharp += c;
                        parser_pos += 1;
                    } while (parser_pos < input_length && c !== '#' && c !== '=');
                    if (c === '#')
                    {
                        //
                    }
                    else if (input.charAt(parser_pos) === '[' && input.charAt(parser_pos + 1) === ']')
                    {
                        sharp += '[]';
                        parser_pos += 2;
                    }
                    else if (input.charAt(parser_pos) === '{' && input.charAt(parser_pos + 1) === '}')
                    {
                        sharp += '{}';
                        parser_pos += 2;
                    }
                    return [sharp, 'TK_WORD'];
                }
            }
            if (c === '<' && input.substring(parser_pos - 1, parser_pos + 3) === '<!--')
            {
                parser_pos += 3;
                c = '<!--';
                while (input[parser_pos] != '\n' && parser_pos < input_length)
                {
                    c += input[parser_pos];
                    parser_pos++;
                }
                flags.in_html_comment = true;
                return [c, 'TK_COMMENT'];
            }
            if (c === '-' && flags.in_html_comment && input.substring(parser_pos - 1, parser_pos + 2) === '-->')
            {
                flags.in_html_comment = false;
                parser_pos += 2;
                if (wanted_newline)
                {
                    print_newline();
                }
                return ['-->', 'TK_COMMENT'];
            }
            if (in_array(c, punct))
            {
                while (parser_pos < input_length && in_array(c + input.charAt(parser_pos), punct))
                {
                    c += input.charAt(parser_pos);
                    parser_pos += 1;
                    if (parser_pos >= input_length)
                    {
                        break;
                    }
                }
                if (c === '=')
                {
                    return [c, 'TK_EQUALS'];
                }
                else
                {
                    return [c, 'TK_OPERATOR'];
                }
            }
            return [c, 'TK_UNKNOWN'];
        }
        //----------------------------------
        indent_string = '';
        while (opt_indent_size > 0)
        {
            indent_string += opt_indent_char;
            opt_indent_size -= 1;
        }
        while (js_source_text && (js_source_text[0] === ' ' || js_source_text[0] === '\t'))
        {
            preindent_string += js_source_text[0];
            js_source_text = js_source_text.substring(1);
        }
        input = js_source_text;
        last_word = ''; // last 'TK_WORD' passed
        last_type = 'TK_START_EXPR'; // last token type
        last_text = ''; // last token text
        last_last_text = ''; // pre-last token text
        output = [];
        do_block_just_closed = false;
        whitespace = "\n\r\t ".split('');
        wordchar = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_$'.split('');
        digits = '0123456789'.split('');
        punct = '+ - * / % & ++ -- = += -= *= /= %= == === != !== > < >= <= >> << >>> >>>= >>= <<= && &= | || ! !! , : ? ^ ^= |= ::';
        punct += ' <%= <% %> <?= <? ?>'; // try to be a good boy and try not to break the markup language identifiers
        punct = punct.split(' ');
        // words which should always start on new line.
        line_starters = 'continue,try,throw,return,var,if,switch,case,default,for,while,break,function'.split(',');
        // states showing if we are currently in expression (i.e. "if" case) - 'EXPRESSION', or in usual block (like, procedure), 'BLOCK'.
        // some formatting depends on that.
        flag_store = [];
        set_mode('BLOCK');
        parser_pos = 0;
        while (true)
        {
            var t = get_next_token(parser_pos);
            token_text = t[0];
            token_type = t[1];
            if (token_type === 'TK_EOF')
            {
                break;
            }
            switch (token_type)
            {
            case 'TK_START_EXPR':
                if (token_text === '[')
                {
                    if (last_type === 'TK_WORD' || last_text === ')')
                    {
                        // this is array index specifier, break immediately
                        // a[x], fn()[x]
                        if (in_array(last_text, line_starters))
                        {
                            print_single_space();
                        }
                        set_mode('(EXPRESSION)');
                        print_token();
                        break;
                    }
                    if (flags.mode === '[EXPRESSION]' || flags.mode === '[INDENTED-EXPRESSION]')
                    {
                        if (last_last_text === ']' && last_text === ',')
                        {
                            // ], [ goes to new line
                            if (flags.mode === '[EXPRESSION]')
                            {
                                flags.mode = '[INDENTED-EXPRESSION]';
                                if (!opt_keep_array_indentation)
                                {
                                    indent();
                                }
                            }
                            set_mode('[EXPRESSION]');
                            if (!opt_keep_array_indentation)
                            {
                                print_newline();
                            }
                        }
                        else if (last_text === '[')
                        {
                            if (flags.mode === '[EXPRESSION]')
                            {
                                flags.mode = '[INDENTED-EXPRESSION]';
                                if (!opt_keep_array_indentation)
                                {
                                    indent();
                                }
                            }
                            set_mode('[EXPRESSION]');
                            if (!opt_keep_array_indentation)
                            {
                                print_newline();
                            }
                        }
                        else
                        {
                            set_mode('[EXPRESSION]');
                        }
                    }
                    else
                    {
                        set_mode('[EXPRESSION]');
                    }
                }
                else
                {
                    if (last_word === 'for')
                    {
                        set_mode('(FOR-EXPRESSION)');
                    }
                    else if (in_array(last_word, ['if', 'while']))
                    {
                        set_mode('(COND-EXPRESSION)');
                    }
                    else
                    {
                        set_mode('(EXPRESSION)');
                    }
                }
                if (last_text === ';' || last_type === 'TK_START_BLOCK')
                {
                    print_newline();
                }
                else if (last_type === 'TK_END_EXPR' || last_type === 'TK_START_EXPR' || last_type === 'TK_END_BLOCK' || last_text === '.')
                {
                    if (wanted_newline)
                    {
                        print_newline();
                    }
                    // do nothing on (( and )( and ][ and ]( and .(
                }
                else if (last_type !== 'TK_WORD' && last_type !== 'TK_OPERATOR')
                {
                    print_single_space();
                }
                else if (last_word === 'function' || last_word === 'typeof')
                {
                    // function() vs function ()
                    if (opt_jslint_happy)
                    {
                        print_single_space();
                    }
                }
                else if (in_array(last_text, line_starters) || last_text === 'catch')
                {
                    if (opt_space_before_conditional)
                    {
                        print_single_space();
                    }
                }
                print_token();
                break;
            case 'TK_END_EXPR':
                if (token_text === ']')
                {
                    if (opt_keep_array_indentation)
                    {
                        if (last_text === '}')
                        {
                            // trim_output();
                            // print_newline(true);
                            remove_indent();
                            print_token();
                            restore_mode();
                            break;
                        }
                    }
                    else
                    {
                        if (flags.mode === '[INDENTED-EXPRESSION]')
                        {
                            if (last_text === ']')
                            {
                                restore_mode();
                                print_newline();
                                print_token();
                                break;
                            }
                        }
                    }
                }
                restore_mode();
                print_token();
                break;
            case 'TK_START_BLOCK':
                if (last_word === 'do')
                {
                    set_mode('DO_BLOCK');
                }
                else
                {
                    set_mode('BLOCK');
                }
                if (opt_brace_style == "expand" || opt_brace_style == "expand-strict")
                {
                    var empty_braces = false;
                    if (opt_brace_style == "expand-strict")
                    {
                        empty_braces = (look_up() == '}');
                        if (!empty_braces)
                        {
                            print_newline(true);
                        }
                    }
                    else
                    {
                        if (last_type !== 'TK_OPERATOR')
                        {
                            if (last_text === '=' || (is_special_word(last_text) && last_text !== 'else'))
                            {
                                print_single_space();
                            }
                            else
                            {
                                print_newline(true);
                            }
                        }
                    }
                    print_token();
                    if (!empty_braces) indent();
                }
                else
                {
                    if (last_type !== 'TK_OPERATOR' && last_type !== 'TK_START_EXPR')
                    {
                        if (last_type === 'TK_START_BLOCK')
                        {
                            print_newline();
                        }
                        else
                        {
                            print_single_space();
                        }
                    }
                    else
                    {
                        // if TK_OPERATOR or TK_START_EXPR
                        if (is_array(flags.previous_mode) && last_text === ',')
                        {
                            if (last_last_text === '}')
                            {
                                // }, { in array context
                                print_single_space();
                            }
                            else
                            {
                                print_newline(); // [a, b, c, {
                            }
                        }
                    }
                    indent();
                    print_token();
                }
                break;
            case 'TK_END_BLOCK':
                restore_mode();
                if (opt_brace_style == "expand" || opt_brace_style == "expand-strict")
                {
                    if (last_text !== '{')
                    {
                        print_newline();
                    }
                    print_token();
                }
                else
                {
                    if (last_type === 'TK_START_BLOCK')
                    {
                        // nothing
                        if (just_added_newline)
                        {
                            remove_indent();
                        }
                        else
                        {
                            // {}
                            trim_output();
                        }
                    }
                    else
                    {
                        if (is_array(flags.mode) && opt_keep_array_indentation)
                        {
                            // we REALLY need a newline here, but newliner would skip that
                            opt_keep_array_indentation = false;
                            print_newline();
                            opt_keep_array_indentation = true;
                        }
                        else
                        {
                            print_newline();
                        }
                    }
                    print_token();
                }
                break;
            case 'TK_WORD':
                // no, it's not you. even I have problems understanding how this works
                // and what does what.
                if (do_block_just_closed)
                {
                    // do {} ## while ()
                    print_single_space();
                    print_token();
                    print_single_space();
                    do_block_just_closed = false;
                    break;
                }
                if (token_text === 'function')
                {
                    if (flags.var_line)
                    {
                        flags.var_line_reindented = true;
                    }
                    if ((just_added_newline || last_text === ';') && last_text !== '{' && last_type != 'TK_BLOCK_COMMENT' && last_type != 'TK_COMMENT')
                    {
                        // make sure there is a nice clean space of at least one blank line
                        // before a new function definition
                        n_newlines = just_added_newline ? n_newlines : 0;
                        if (!opt_preserve_newlines)
                        {
                            n_newlines = 1;
                        }
                        for (var i = 0; i < 2 - n_newlines; i++)
                        {
                            print_newline(false);
                        }
                    }
                }
                if (token_text === 'case' || token_text === 'default')
                {
                    if (last_text === ':' || flags.case_body)
                    {
                        // switch cases following one another
                        remove_indent();
                    }
                    else
                    {
                        // case statement starts in the same line where switch
                        if (!opt_indent_case) flags.indentation_level--;
                        print_newline();
                        if (!opt_indent_case) flags.indentation_level++;
                    }
                    print_token();
                    flags.in_case = true;
                    flags.case_body = false;
                    break;
                }
                prefix = 'NONE';
                if (last_type === 'TK_END_BLOCK')
                {
                    if (!in_array(token_text.toLowerCase(), ['else', 'catch', 'finally']))
                    {
                        prefix = 'NEWLINE';
                    }
                    else
                    {
                        if (opt_brace_style == "expand" || opt_brace_style == "end-expand" || opt_brace_style == "expand-strict")
                        {
                            prefix = 'NEWLINE';
                        }
                        else
                        {
                            prefix = 'SPACE';
                            print_single_space();
                        }
                    }
                }
                else if (last_type === 'TK_SEMICOLON' && (flags.mode === 'BLOCK' || flags.mode === 'DO_BLOCK'))
                {
                    prefix = 'NEWLINE';
                }
                else if (last_type === 'TK_SEMICOLON' && is_expression(flags.mode))
                {
                    prefix = 'SPACE';
                }
                else if (last_type === 'TK_STRING')
                {
                    prefix = 'NEWLINE';
                }
                else if (last_type === 'TK_WORD')
                {
                    if (last_text === 'else')
                    {
                        // eat newlines between ...else *** some_op...
                        // won't preserve extra newlines in this place (if any), but don't care that much
                        trim_output(true);
                    }
                    prefix = 'SPACE';
                }
                else if (last_type === 'TK_START_BLOCK')
                {
                    prefix = 'NEWLINE';
                }
                else if (last_type === 'TK_END_EXPR')
                {
                    print_single_space();
                    prefix = 'NEWLINE';
                }
                if (in_array(token_text, line_starters) && last_text !== ')')
                {
                    if (last_text == 'else')
                    {
                        prefix = 'SPACE';
                    }
                    else
                    {
                        prefix = 'NEWLINE';
                    }
                    if (token_text === 'function' && (last_text === 'get' || last_text === 'set'))
                    {
                        prefix = 'SPACE';
                    }
                }
                if (flags.if_line && last_type === 'TK_END_EXPR')
                {
                    flags.if_line = false;
                }
                if (in_array(token_text.toLowerCase(), ['else', 'catch', 'finally']))
                {
                    if (last_type !== 'TK_END_BLOCK' || opt_brace_style == "expand" || opt_brace_style == "end-expand" || opt_brace_style == "expand-strict")
                    {
                        print_newline();
                    }
                    else
                    {
                        trim_output(true);
                        print_single_space();
                    }
                }
                else if (prefix === 'NEWLINE')
                {
                    if ((last_type === 'TK_START_EXPR' || last_text === '=' || last_text === ',') && token_text === 'function')
                    {
                        // no need to force newline on 'function': (function
                        // DONOTHING
                    }
                    else if (token_text === 'function' && last_text == 'new')
                    {
                        print_single_space();
                    }
                    else if (is_special_word(last_text))
                    {
                        // no newline between 'return nnn'
                        print_single_space();
                    }
                    else if (last_type !== 'TK_END_EXPR')
                    {
                        if ((last_type !== 'TK_START_EXPR' || token_text !== 'var') && last_text !== ':')
                        {
                            // no need to force newline on 'var': for (var x = 0...)
                            if (token_text === 'if' && last_word === 'else' && last_text !== '{')
                            {
                                // no newline for } else if {
                                print_single_space();
                            }
                            else
                            {
                                flags.var_line = false;
                                flags.var_line_reindented = false;
                                print_newline();
                            }
                        }
                    }
                    else if (in_array(token_text, line_starters) && last_text != ')')
                    {
                        flags.var_line = false;
                        flags.var_line_reindented = false;
                        print_newline();
                    }
                }
                else if (is_array(flags.mode) && last_text === ',' && last_last_text === '}')
                {
                    print_newline(); // }, in lists get a newline treatment
                }
                else if (prefix === 'SPACE')
                {
                    print_single_space();
                }
                print_token();
                last_word = token_text;
                if (token_text === 'var')
                {
                    flags.var_line = true;
                    flags.var_line_reindented = false;
                    flags.var_line_tainted = false;
                }
                if (token_text === 'if')
                {
                    flags.if_line = true;
                }
                if (token_text === 'else')
                {
                    flags.if_line = false;
                }
                break;
            case 'TK_SEMICOLON':
                print_token();
                flags.var_line = false;
                flags.var_line_reindented = false;
                if (flags.mode == 'OBJECT')
                {
                    // OBJECT mode is weird and doesn't get reset too well.
                    flags.mode = 'BLOCK';
                }
                break;
            case 'TK_STRING':
                if (last_type === 'TK_END_EXPR' && in_array(flags.previous_mode, ['(COND-EXPRESSION)', '(FOR-EXPRESSION)']))
                {
                    print_single_space();
                }
                else if (last_type == 'TK_STRING' || last_type === 'TK_START_BLOCK' || last_type === 'TK_END_BLOCK' || last_type === 'TK_SEMICOLON')
                {
                    print_newline();
                }
                else if (last_type === 'TK_WORD')
                {
                    print_single_space();
                }
                print_token();
                break;
            case 'TK_EQUALS':
                if (flags.var_line)
                {
                    // just got an '=' in a var-line, different formatting/line-breaking, etc will now be done
                    flags.var_line_tainted = true;
                }
                print_single_space();
                print_token();
                print_single_space();
                break;
            case 'TK_OPERATOR':
                var space_before = true;
                var space_after = true;
                if (flags.var_line && token_text === ',' && (is_expression(flags.mode)))
                {
                    // do not break on comma, for(var a = 1, b = 2)
                    flags.var_line_tainted = false;
                }
                if (flags.var_line)
                {
                    if (token_text === ',')
                    {
                        if (flags.var_line_tainted)
                        {
                            print_token();
                            flags.var_line_reindented = true;
                            flags.var_line_tainted = false;
                            print_newline();
                            break;
                        }
                        else
                        {
                            flags.var_line_tainted = false;
                        }
                        // } else if (token_text === ':') {
                        // hmm, when does this happen? tests don't catch this
                        // flags.var_line = false;
                    }
                }
                if (is_special_word(last_text))
                {
                    // "return" had a special handling in TK_WORD. Now we need to return the favor
                    print_single_space();
                    print_token();
                    break;
                }
                if (token_text === ':' && flags.in_case)
                {
                    if (opt_indent_case) flags.case_body = true;
                    print_token(); // colon really asks for separate treatment
                    print_newline();
                    flags.in_case = false;
                    break;
                }
                if (token_text === '::')
                {
                    // no spaces around exotic namespacing syntax operator
                    print_token();
                    break;
                }
                if (token_text === ',')
                {
                    if (flags.var_line)
                    {
                        if (flags.var_line_tainted)
                        {
                            print_token();
                            print_newline();
                            flags.var_line_tainted = false;
                        }
                        else
                        {
                            print_token();
                            print_single_space();
                        }
                    }
                    else if (last_type === 'TK_END_BLOCK' && flags.mode !== "(EXPRESSION)")
                    {
                        print_token();
                        if (flags.mode === 'OBJECT' && last_text === '}')
                        {
                            print_newline();
                        }
                        else
                        {
                            print_single_space();
                        }
                    }
                    else
                    {
                        if (flags.mode === 'OBJECT')
                        {
                            print_token();
                            print_newline();
                        }
                        else
                        {
                            // EXPR or DO_BLOCK
                            print_token();
                            print_single_space();
                        }
                    }
                    break;
                    // } else if (in_array(token_text, ['--', '++', '!']) || (in_array(token_text, ['-', '+']) && (in_array(last_type, ['TK_START_BLOCK', 'TK_START_EXPR', 'TK_EQUALS']) || in_array(last_text, line_starters) || in_array(last_text, ['==', '!=', '+=', '-=', '*=', '/=', '+', '-'])))) {
                }
                else if (in_array(token_text, ['--', '++', '!']) || (in_array(token_text, ['-', '+']) && (in_array(last_type, ['TK_START_BLOCK', 'TK_START_EXPR', 'TK_EQUALS', 'TK_OPERATOR']) || in_array(last_text, line_starters))))
                {
                    // unary operators (and binary +/- pretending to be unary) special cases
                    space_before = false;
                    space_after = false;
                    if (last_text === ';' && is_expression(flags.mode))
                    {
                        // for (;; ++i)
                        //        ^^^
                        space_before = true;
                    }
                    if (last_type === 'TK_WORD' && in_array(last_text, line_starters))
                    {
                        space_before = true;
                    }
                    if (flags.mode === 'BLOCK' && (last_text === '{' || last_text === ';'))
                    {
                        // { foo; --i }
                        // foo(); --bar;
                        print_newline();
                    }
                }
                else if (token_text === '.')
                {
                    // decimal digits or object.property
                    space_before = false;
                }
                else if (token_text === ':')
                {
                    if (flags.ternary_depth == 0)
                    {
                        flags.mode = 'OBJECT';
                        space_before = false;
                    }
                    else
                    {
                        flags.ternary_depth -= 1;
                    }
                }
                else if (token_text === '?')
                {
                    flags.ternary_depth += 1;
                }
                if (space_before)
                {
                    print_single_space();
                }
                print_token();
                if (space_after)
                {
                    print_single_space();
                }
                if (token_text === '!')
                {
                    // flags.eat_next_space = true;
                }
                break;
            case 'TK_BLOCK_COMMENT':
                var lines = token_text.split(/\x0a|\x0d\x0a/);
                if (all_lines_start_with(lines.slice(1), '*'))
                {
                    // javadoc: reformat and reindent
                    print_newline();
                    output.push(lines[0]);
                    for (i = 1; i < lines.length; i++)
                    {
                        print_newline();
                        output.push(' ');
                        output.push(trim(lines[i]));
                    }
                }
                else
                {
                    // simple block comment: leave intact
                    if (lines.length > 1)
                    {
                        // multiline comment block starts with a new line
                        print_newline();
                    }
                    else
                    {
                        // single-line /* comment */ stays where it is
                        if (last_type === 'TK_END_BLOCK')
                        {
                            print_newline();
                        }
                        else
                        {
                            print_single_space();
                        }
                    }
                    for (i = 0; i < lines.length; i++)
                    {
                        output.push(lines[i]);
                        output.push('\n');
                    }
                }
                if (look_up('\n') != '\n') print_newline();
                break;
            case 'TK_INLINE_COMMENT':
                print_single_space();
                print_token();
                if (is_expression(flags.mode))
                {
                    print_single_space();
                }
                else
                {
                    force_newline();
                }
                break;
            case 'TK_COMMENT':
                // print_newline();
                if (wanted_newline)
                {
                    print_newline();
                }
                else
                {
                    print_single_space();
                }
                print_token();
                if (look_up('\n') != '\n') force_newline();
                break;
            case 'TK_UNKNOWN':
                if (is_special_word(last_text))
                {
                    print_single_space();
                }
                print_token();
                break;
            }
            last_last_text = last_text;
            last_type = token_type;
            last_text = token_text;
        }
        var sweet_code = preindent_string + output.join('').replace(/[\n ]+$/, '');
        return sweet_code;
    }
    // Add support for CommonJS. Just put this file somewhere on your require.paths
    // and you will be able to `var js_beautify = require("beautify").js_beautify`.
    // comments by Microshaoft begin ===========================================================
    /*
        if (typeof exports !== "undefined")
            exports.js_beautify = js_beautify;
    */
    // comments by Microshaoft end ===========================================================
    /*
     Style HTML
    ---------------
      Written by Nochum Sossonko, (nsossonko@hotmail.com)
      Based on code initially developed by: Einar Lielmanis, <elfz@laacz.lv>
        http://jsbeautifier.org/
      You are free to use this in any way you want, in case you find this useful or working for you.
      Usage:
        style_html(html_source);
        style_html(html_source, options);
      The options are:
        indent_size (default 4)          ?? indentation size,
        indent_char (default space)      ?? character to indent with,
        max_char (default 70)            -  maximum amount of characters per line,
        brace_style (default "collapse") - "collapse" | "expand" | "end-expand"
                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.
        unformatted (default ['a'])      - list of tags, that shouldn't be reformatted
        indent_scripts (default normal)  - "keep"|"separate"|"normal"
        e.g.
        style_html(html_source, {
          'indent_size': 2,
          'indent_char': ' ',
          'max_char': 78,
          'brace_style': 'expand',
          'unformatted': ['a', 'sub', 'sup', 'b', 'i', 'u']
        });
    */
    function style_html(html_source, options)
    {
        //Wrapper function to invoke all the necessary constructors and deal with the output.
        var multi_parser, indent_size, indent_character, max_char, brace_style;
        options = options || {};
        indent_size = options.indent_size || 4;
        indent_character = options.indent_char || ' ';
        brace_style = options.brace_style || 'collapse';
        max_char = options.max_char == 0 ? Infinity : options.max_char || 70;
        var unformatted = options.unformatted || ['a'];
        function Parser()
        {
            this.pos = 0; //Parser position
            this.token = '';
            this.current_mode = 'CONTENT'; //reflects the current Parser mode: TAG/CONTENT
            this.tags =
            { //An object to hold tags, their position, and their parent-tags, initiated with default values
                parent: 'parent1',
                parentcount: 1,
                parent1: ''
            };
            this.tag_type = '';
            this.token_text = this.last_token = this.last_text = this.token_type = '';
            this.Utils =
            { //Uilities made available to the various functions
                whitespace: "\n\r\t ".split(''),
                single_token: 'br,input,link,meta,!doctype,basefont,base,area,hr,wbr,param,img,isindex,?xml,embed'.split(','),
                //all the single tags for HTML
                extra_liners: 'head,body,/html'.split(','),
                //for tags that need a line of whitespace before them
                in_array: function (what, arr)
                {
                    for (var i = 0; i < arr.length; i++)
                    {
                        if (what === arr[i])
                        {
                            return true;
                        }
                    }
                    return false;
                }
            }
            this.get_content = function ()
            { //function to capture regular content between tags
                var input_char = '';
                var content = [];
                var space = false; //if a space is needed
                while (this.input.charAt(this.pos) !== '<')
                {
                    if (this.pos >= this.input.length)
                    {
                        return content.length ? content.join('') : ['', 'TK_EOF'];
                    }
                    input_char = this.input.charAt(this.pos);
                    this.pos++;
                    this.line_char_count++;
                    if (this.Utils.in_array(input_char, this.Utils.whitespace))
                    {
                        if (content.length)
                        {
                            space = true;
                        }
                        this.line_char_count--;
                        continue; //don't want to insert unnecessary space
                    }
                    else if (space)
                    {
                        if (this.line_char_count >= this.max_char)
                        { //insert a line when the max_char is reached
                            content.push('\n');
                            for (var i = 0; i < this.indent_level; i++)
                            {
                                content.push(this.indent_string);
                            }
                            this.line_char_count = 0;
                        }
                        else
                        {
                            content.push(' ');
                            this.line_char_count++;
                        }
                        space = false;
                    }
                    content.push(input_char); //letter at-a-time (or string) inserted to an array
                }
                return content.length ? content.join('') : '';
            }
            this.get_contents_to = function (name)
            { //get the full content of a script or style to pass to js_beautify
                if (this.pos == this.input.length)
                {
                    return ['', 'TK_EOF'];
                }
                var input_char = '';
                var content = '';
                var reg_match = new RegExp('\<\/' + name + '\\s*\>', 'igm');
                reg_match.lastIndex = this.pos;
                var reg_array = reg_match.exec(this.input);
                var end_script = reg_array ? reg_array.index : this.input.length; //absolute end of script
                if (this.pos < end_script)
                { //get everything in between the script tags
                    content = this.input.substring(this.pos, end_script);
                    this.pos = end_script;
                }
                return content;
            }
            this.record_tag = function (tag)
            { //function to record a tag and its parent in this.tags Object
                if (this.tags[tag + 'count'])
                { //check for the existence of this tag type
                    this.tags[tag + 'count']++;
                    this.tags[tag + this.tags[tag + 'count']] = this.indent_level; //and record the present indent level
                }
                else
                { //otherwise initialize this tag type
                    this.tags[tag + 'count'] = 1;
                    this.tags[tag + this.tags[tag + 'count']] = this.indent_level; //and record the present indent level
                }
                this.tags[tag + this.tags[tag + 'count'] + 'parent'] = this.tags.parent; //set the parent (i.e. in the case of a div this.tags.div1parent)
                this.tags.parent = tag + this.tags[tag + 'count']; //and make this the current parent (i.e. in the case of a div 'div1')
            }
            this.retrieve_tag = function (tag)
            { //function to retrieve the opening tag to the corresponding closer
                if (this.tags[tag + 'count'])
                { //if the openener is not in the Object we ignore it
                    var temp_parent = this.tags.parent; //check to see if it's a closable tag.
                    while (temp_parent)
                    { //till we reach '' (the initial value);
                        if (tag + this.tags[tag + 'count'] === temp_parent)
                        { //if this is it use it
                            break;
                        }
                        temp_parent = this.tags[temp_parent + 'parent']; //otherwise keep on climbing up the DOM Tree
                    }
                    if (temp_parent)
                    { //if we caught something
                        this.indent_level = this.tags[tag + this.tags[tag + 'count']]; //set the indent_level accordingly
                        this.tags.parent = this.tags[temp_parent + 'parent']; //and set the current parent
                    }
                    delete this.tags[tag + this.tags[tag + 'count'] + 'parent']; //delete the closed tags parent reference...
                    delete this.tags[tag + this.tags[tag + 'count']]; //...and the tag itself
                    if (this.tags[tag + 'count'] == 1)
                    {
                        delete this.tags[tag + 'count'];
                    }
                    else
                    {
                        this.tags[tag + 'count']--;
                    }
                }
            }
            this.get_tag = function ()
            { //function to get a full tag and parse its type
                var input_char = '';
                var content = [];
                var space = false;
                do
                {
                    if (this.pos >= this.input.length)
                    {
                        return content.length ? content.join('') : ['', 'TK_EOF'];
                    }
                    input_char = this.input.charAt(this.pos);
                    this.pos++;
                    this.line_char_count++;
                    if (this.Utils.in_array(input_char, this.Utils.whitespace))
                    { //don't want to insert unnecessary space
                        space = true;
                        this.line_char_count--;
                        continue;
                    }
                    if (input_char === "'" || input_char === '"')
                    {
                        if (!content[1] || content[1] !== '!')
                        { //if we're in a comment strings don't get treated specially
                            input_char += this.get_unformatted(input_char);
                            space = true;
                        }
                    }
                    if (input_char === '=')
                    { //no space before =
                        space = false;
                    }
                    if (content.length && content[content.length - 1] !== '=' && input_char !== '>' && space)
                    { //no space after = or before >
                        if (this.line_char_count >= this.max_char)
                        {
                            this.print_newline(false, content);
                            this.line_char_count = 0;
                        }
                        else
                        {
                            content.push(' ');
                            this.line_char_count++;
                        }
                        space = false;
                    }
                    content.push(input_char); //inserts character at-a-time (or string)
                } while (input_char !== '>');
                var tag_complete = content.join('');
                var tag_index;
                if (tag_complete.indexOf(' ') != -1)
                { //if there's whitespace, thats where the tag name ends
                    tag_index = tag_complete.indexOf(' ');
                }
                else
                { //otherwise go with the tag ending
                    tag_index = tag_complete.indexOf('>');
                }
                var tag_check = tag_complete.substring(1, tag_index).toLowerCase();
                if (tag_complete.charAt(tag_complete.length - 2) === '/' || this.Utils.in_array(tag_check, this.Utils.single_token))
                { //if this tag name is a single tag type (either in the list or has a closing /)
                    this.tag_type = 'SINGLE';
                }
                else if (tag_check === 'script')
                { //for later script handling
                    this.record_tag(tag_check);
                    this.tag_type = 'SCRIPT';
                }
                else if (tag_check === 'style')
                { //for future style handling (for now it justs uses get_content)
                    this.record_tag(tag_check);
                    this.tag_type = 'STYLE';
                }
                else if (this.Utils.in_array(tag_check, unformatted))
                { // do not reformat the "unformatted" tags
                    var comment = this.get_unformatted('</' + tag_check + '>', tag_complete); //...delegate to get_unformatted function
                    content.push(comment);
                    this.tag_type = 'SINGLE';
                }
                else if (tag_check.charAt(0) === '!')
                { //peek for <!-- comment
                    if (tag_check.indexOf('[if') != -1)
                    { //peek for <!--[if conditional comment
                        if (tag_complete.indexOf('!IE') != -1)
                        { //this type needs a closing --> so...
                            var comment = this.get_unformatted('-->', tag_complete); //...delegate to get_unformatted
                            content.push(comment);
                        }
                        this.tag_type = 'START';
                    }
                    else if (tag_check.indexOf('[endif') != -1)
                    { //peek for <!--[endif end conditional comment
                        this.tag_type = 'END';
                        this.unindent();
                    }
                    else if (tag_check.indexOf('[cdata[') != -1)
                    { //if it's a <[cdata[ comment...
                        var comment = this.get_unformatted(']]>', tag_complete); //...delegate to get_unformatted function
                        content.push(comment);
                        this.tag_type = 'SINGLE'; //<![CDATA[ comments are treated like single tags
                    }
                    else
                    {
                        var comment = this.get_unformatted('-->', tag_complete);
                        content.push(comment);
                        this.tag_type = 'SINGLE';
                    }
                }
                else
                {
                    if (tag_check.charAt(0) === '/')
                    { //this tag is a double tag so check for tag-ending
                        this.retrieve_tag(tag_check.substring(1)); //remove it and all ancestors
                        this.tag_type = 'END';
                    }
                    else
                    { //otherwise it's a start-tag
                        this.record_tag(tag_check); //push it on the tag stack
                        this.tag_type = 'START';
                    }
                    if (this.Utils.in_array(tag_check, this.Utils.extra_liners))
                    { //check if this double needs an extra line
                        this.print_newline(true, this.output);
                    }
                }
                return content.join(''); //returns fully formatted tag
            }
            this.get_unformatted = function (delimiter, orig_tag)
            { //function to return unformatted content in its entirety
                if (orig_tag && orig_tag.indexOf(delimiter) != -1)
                {
                    return '';
                }
                var input_char = '';
                var content = '';
                var space = true;
                do
                {
                    if (this.pos >= this.input.length)
                    {
                        return content;
                    }
                    input_char = this.input.charAt(this.pos);
                    this.pos++
                    if (this.Utils.in_array(input_char, this.Utils.whitespace))
                    {
                        if (!space)
                        {
                            this.line_char_count--;
                            continue;
                        }
                        if (input_char === '\n' || input_char === '\r')
                        {
                            content += '\n';
                            /*  Don't change tab indention for unformatted blocks.  If using code for html editing, this will greatly affect <pre> tags if they are specified in the 'unformatted array'
                for (var i=0; i<this.indent_level; i++) {
                  content += this.indent_string;
                }
                space = false; //...and make sure other indentation is erased
                */
                            this.line_char_count = 0;
                            continue;
                        }
                    }
                    content += input_char;
                    this.line_char_count++;
                    space = true;
                } while (content.indexOf(delimiter) == -1);
                return content;
            }
            this.get_token = function ()
            { //initial handler for token-retrieval
                var token;
                if (this.last_token === 'TK_TAG_SCRIPT' || this.last_token === 'TK_TAG_STYLE')
                { //check if we need to format javascript
                    var type = this.last_token.substr(7)
                    token = this.get_contents_to(type);
                    if (typeof token !== 'string')
                    {
                        return token;
                    }
                    return [token, 'TK_' + type];
                }
                if (this.current_mode === 'CONTENT')
                {
                    token = this.get_content();
                    if (typeof token !== 'string')
                    {
                        return token;
                    }
                    else
                    {
                        return [token, 'TK_CONTENT'];
                    }
                }
                if (this.current_mode === 'TAG')
                {
                    token = this.get_tag();
                    if (typeof token !== 'string')
                    {
                        return token;
                    }
                    else
                    {
                        var tag_name_type = 'TK_TAG_' + this.tag_type;
                        return [token, tag_name_type];
                    }
                }
            }
            this.get_full_indent = function (level)
            {
                level = this.indent_level + level || 0;
                if (level < 1) return '';
                return Array(level + 1).join(this.indent_string);
            }
            this.printer = function (js_source, indent_character, indent_size, max_char, brace_style)
            { //handles input/output and some other printing functions
                this.input = js_source || ''; //gets the input for the Parser
                this.output = [];
                this.indent_character = indent_character;
                this.indent_string = '';
                this.indent_size = indent_size;
                this.brace_style = brace_style;
                this.indent_level = 0;
                this.max_char = max_char;
                this.line_char_count = 0; //count to see if max_char was exceeded
                for (var i = 0; i < this.indent_size; i++)
                {
                    this.indent_string += this.indent_character;
                }
                this.print_newline = function (ignore, arr)
                {
                    this.line_char_count = 0;
                    if (!arr || !arr.length)
                    {
                        return;
                    }
                    if (!ignore)
                    { //we might want the extra line
                        while (this.Utils.in_array(arr[arr.length - 1], this.Utils.whitespace))
                        {
                            arr.pop();
                        }
                    }
                    arr.push('\n');
                    for (var i = 0; i < this.indent_level; i++)
                    {
                        arr.push(this.indent_string);
                    }
                }
                this.print_token = function (text)
                {
                    this.output.push(text);
                }
                this.indent = function ()
                {
                    this.indent_level++;
                }
                this.unindent = function ()
                {
                    if (this.indent_level > 0)
                    {
                        this.indent_level--;
                    }
                }
            }
            return this;
        }
        /*_____________________--------------------_____________________*/
        multi_parser = new Parser(); //wrapping functions Parser
        multi_parser.printer(html_source, indent_character, indent_size, max_char, brace_style); //initialize starting values
        while (true)
        {
            var t = multi_parser.get_token();
            multi_parser.token_text = t[0];
            multi_parser.token_type = t[1];
            if (multi_parser.token_type === 'TK_EOF')
            {
                break;
            }
            switch (multi_parser.token_type)
            {
            case 'TK_TAG_START':
                multi_parser.print_newline(false, multi_parser.output);
                multi_parser.print_token(multi_parser.token_text);
                multi_parser.indent();
                multi_parser.current_mode = 'CONTENT';
                break;
            case 'TK_TAG_STYLE':
            case 'TK_TAG_SCRIPT':
                multi_parser.print_newline(false, multi_parser.output);
                multi_parser.print_token(multi_parser.token_text);
                multi_parser.current_mode = 'CONTENT';
                break;
            case 'TK_TAG_END':
                //Print new line only if the tag has no content and has child
                if (multi_parser.last_token === 'TK_CONTENT' && multi_parser.last_text === '')
                {
                    var tag_name = multi_parser.token_text.match(/\w+/)[0];
                    var tag_extracted_from_last_output = multi_parser.output[multi_parser.output.length - 1].match(/<\s*(\w+)/);
                    if (tag_extracted_from_last_output === null || tag_extracted_from_last_output[1] !== tag_name) multi_parser.print_newline(true, multi_parser.output);
                }
                multi_parser.print_token(multi_parser.token_text);
                multi_parser.current_mode = 'CONTENT';
                break;
            case 'TK_TAG_SINGLE':
                multi_parser.print_newline(false, multi_parser.output);
                multi_parser.print_token(multi_parser.token_text);
                multi_parser.current_mode = 'CONTENT';
                break;
            case 'TK_CONTENT':
                if (multi_parser.token_text !== '')
                {
                    multi_parser.print_token(multi_parser.token_text);
                }
                multi_parser.current_mode = 'TAG';
                break;
            case 'TK_STYLE':
            case 'TK_SCRIPT':
                if (multi_parser.token_text !== '')
                {
                    multi_parser.output.push('\n');
                    var text = multi_parser.token_text;
                    if (multi_parser.token_type == 'TK_SCRIPT')
                    {
                        var _beautifier = typeof js_beautify == 'function' && js_beautify;
                    }
                    else if (multi_parser.token_type == 'TK_STYLE')
                    {
                        var _beautifier = typeof css_beautify == 'function' && css_beautify;
                    }
                    if (options.indent_scripts == "keep")
                    {
                        var script_indent_level = 0;
                    }
                    else if (options.indent_scripts == "separate")
                    {
                        var script_indent_level = -multi_parser.indent_level;
                    }
                    else
                    {
                        var script_indent_level = 1;
                    }
                    var indentation = multi_parser.get_full_indent(script_indent_level);
                    if (_beautifier)
                    {
                        // call the Beautifier if avaliable
                        text = _beautifier(text.replace(/^\s*/, indentation), options);
                    }
                    else
                    {
                        // simply indent the string otherwise
                        var white = text.match(/^\s*/)[0];
                        var _level = white.match(/[^\n\r]*$/)[0].split(multi_parser.indent_string).length - 1;
                        var reindent = multi_parser.get_full_indent(script_indent_level - _level);
                        text = text.replace(/^\s*/, indentation).replace(/\r\n|\r|\n/g, '\n' + reindent).replace(/\s*$/, '');
                    }
                    if (text)
                    {
                        multi_parser.print_token(text);
                        multi_parser.print_newline(true, multi_parser.output);
                    }
                }
                multi_parser.current_mode = 'TAG';
                break;
            }
            multi_parser.last_token = multi_parser.token_type;
            multi_parser.last_text = multi_parser.token_text;
        }
        return multi_parser.output.join('');
    }
    /*
     CSS Beautifier
    ---------------
        Written by Harutyun Amirjanyan, (amirjanyan@gmail.com)
        Based on code initially developed by: Einar Lielmanis, <elfz@laacz.lv>
            http://jsbeautifier.org/
        You are free to use this in any way you want, in case you find this useful or working for you.
        Usage:
            css_beautify(source_text);
            css_beautify(source_text, options);
        The options are:
            indent_size (default 4)          ?? indentation size,
            indent_char (default space)      ?? character to indent with,
        e.g
        css_beautify(css_source_text, {
          'indent_size': 1,
          'indent_char': '\t'
        });
    */
    // http://www.w3.org/TR/CSS21/syndata.html#tokenization
    // http://www.w3.org/TR/css3-syntax/
    function css_beautify(source_text, options)
    {
        options = options || {};
        var indentSize = options.indent_size || 4;
        var indentCharacter = options.indent_char || ' ';
        // compatibility
        if (typeof indentSize == "string") indentSize = parseInt(indentSize);
        // tokenizer
        var whiteRe = /^\s+$/;
        var wordRe = /[\w$\-_]/;
        var pos = -1,
            ch;
        function next()
        {
            return ch = source_text.charAt(++pos)
        }
        function peek()
        {
            return source_text.charAt(pos + 1)
        }
        function eatString(comma)
        {
            var start = pos;
            while (next())
            {
                if (ch == "\\")
                {
                    next();
                    next();
                }
                else if (ch == comma)
                {
                    break;
                }
                else if (ch == "\n")
                {
                    break;
                }
            }
            return source_text.substring(start, pos + 1);
        }
        function eatWhitespace()
        {
            var start = pos;
            while (whiteRe.test(peek()))
            pos++;
            return pos != start;
        }
        function skipWhitespace()
        {
            var start = pos;
            do{} while (whiteRe.test(next()))
            return pos != start + 1;
        }
        function eatComment()
        {
            var start = pos;
            next();
            while (next())
            {
                if (ch == "*" && peek() == "/")
                {
                    pos++;
                    break;
                }
            }
            return source_text.substring(start, pos + 1);
        }
        function lookBack(str, index)
        {
            return output.slice(-str.length + (index || 0), index).join("").toLowerCase() == str;
        }
        // printer
        var indentString = source_text.match(/^[\r\n]*[\t ]*/)[0];
        var singleIndent = Array(indentSize + 1).join(indentCharacter);
        var indentLevel = 0;
        function indent()
        {
            indentLevel++;
            indentString += singleIndent;
        }
        function outdent()
        {
            indentLevel--;
            indentString = indentString.slice(0, -indentSize);
        }
        //print = {}
        // modified by Microshaoft
        print = {}
        print["{"] = function (ch)
        {
            print.singleSpace();
            output.push(ch);
            print.newLine();
        }
        print["}"] = function (ch)
        {
            print.newLine();
            output.push(ch);
            print.newLine();
        }
        print.newLine = function (keepWhitespace)
        {
            if (!keepWhitespace) while (whiteRe.test(output[output.length - 1]))
            output.pop();
            if (output.length) output.push('\n');
            if (indentString) output.push(indentString);
        }
        print.singleSpace = function ()
        {
            if (output.length && !whiteRe.test(output[output.length - 1])) output.push(' ');
        }
        var output = [];
        if (indentString) output.push(indentString);
        /*_____________________--------------------_____________________*/
        while (true)
        {
            var isAfterSpace = skipWhitespace();
            if (!ch) break;
            if (ch == '{')
            {
                indent();
                print["{"](ch);
            }
            else if (ch == '}')
            {
                outdent();
                print["}"](ch);
            }
            else if (ch == '"' || ch == '\'')
            {
                output.push(eatString(ch))
            }
            else if (ch == ';')
            {
                output.push(ch, '\n', indentString);
            }
            else if (ch == '/' && peek() == '*')
            { // comment
                print.newLine();
                output.push(eatComment(), "\n", indentString);
            }
            else if (ch == '(')
            { // may be a url
                output.push(ch);
                eatWhitespace();
                if (lookBack("url", -1) && next())
                {
                    if (ch != ')' && ch != '"' && ch != '\'') output.push(eatString(')'));
                    else pos--;
                }
            }
            else if (ch == ')')
            {
                output.push(ch);
            }
            else if (ch == ',')
            {
                eatWhitespace();
                output.push(ch);
                print.singleSpace();
            }
            else if (ch == ']')
            {
                output.push(ch);
            }
            else if (ch == '[' || ch == '=')
            { // no whitespace before or after
                eatWhitespace();
                output.push(ch);
            }
            else
            {
                if (isAfterSpace) print.singleSpace();
                output.push(ch);
            }
        }
        var sweetCode = output.join('').replace(/[\n ]+$/, '');
        return sweetCode;
    }
    //if (typeof exports !== "undefined")
    //    exports.css_beautify = css_beautify;
    function unpacker_filter(source)
    {
        var trailing_comments = '';
        var comment = '';
        var found = false;
        do
        {
            found = false;
            if (/^\s*\/\*/.test(source))
            {
                found = true;
                comment = source.substr(0, source.indexOf('*/') + 2);
                source = source.substr(comment.length).replace(/^\s+/, '');
                trailing_comments += comment + "\n";
            }
            else if (/^\s*\/\//.test(source))
            {
                found = true;
                comment = source.match(/^\s*\/\/.*/)[0];
                source = source.substr(comment.length).replace(/^\s+/, '');
                trailing_comments += comment + "\n";
            }
        } while (found);
        if (P_A_C_K_E_R.detect(source))
        {
            // P.A.C.K.E.R unpacking may fail, even though it is detected
            var unpacked = P_A_C_K_E_R.unpack(source);
            if (unpacked != source)
            {
                source = unpacker_filter(unpacked);
            }
        }
        if (Urlencoded.detect(source))
        {
            source = unpacker_filter(Urlencoded.unpack(source))
        }
        if (JavascriptObfuscator.detect(source))
        {
            source = unpacker_filter(JavascriptObfuscator.unpack(source))
        }
        if (MyObfuscate.detect(source))
        {
            source = unpacker_filter(MyObfuscate.unpack(source))
        }
        return trailing_comments + source;
    }
    function looks_like_html(source)
    {
        // <foo> - looks like html
        // <!--\nalert('foo!');\n--> - doesn't look like html
        var trimmed = source; //.replace(/^[ \t\n\r]+/, '');
        var comment_mark = '<!-' + '-';
        return (trimmed && (trimmed.substring(0, 1) === '<' && trimmed.substring(0, 4) !== comment_mark));
    }
    function beautify(source, options)
    {
        //    if (the.beautify_in_progress) return;
        //
        //    store_settings_to_cookie();
        //
        //    the.beautify_in_progress = true;
        //    var opts = {
        //                indent_size: indent_size,
        //                indent_char: indent_char,
        //                preserve_newlines:preserve_newlines,
        //                brace_style: brace_style,
        //                keep_array_indentation:keep_array_indentation,
        //                space_after_anon_function:true,
        //                space_before_conditional: space_before_conditional,
        //                indent_scripts:indent_scripts};
        if (looks_like_html(source))
        {
            // modified by Microshaoft
            return style_html(source, options);
        }
        else
        {
            // modified by Microshaoft
            source = unpacker_filter(source);
            return js_beautify(source, options);
        }
        //    the.beautify_in_progress = false;
    }
    //
    // Unpacker for Dean Edward's p.a.c.k.e.r, a part of javascript beautifier
    // written by Einar Lielmanis <einar@jsbeautifier.org>
    //
    // Coincidentally, it can defeat a couple of other eval-based compressors.
    //
    // usage:
    //
    // if (P_A_C_K_E_R.detect(some_string)) {
    //     var unpacked = P_A_C_K_E_R.unpack(some_string);
    // }
    // 
    //
    var P_A_C_K_E_R =
    {
        detect: function (str)
        {
            return false;//    P_A_C_K_E_R._starts_with(str.toLowerCase().replace(/ +/g, ''), 'eval(function(') || P_A_C_K_E_R._starts_with(str.toLowerCase().replace(/ +/g, ''), 'eval((function(');
        },
        unpack: function (str)
        {
            var unpacked_source = '';
            if (P_A_C_K_E_R.detect(str))
            {
                try
                {
                    eval('unpacked_source = ' + str.substring(4) + ';')
                    if (typeof unpacked_source == 'string' && unpacked_source)
                    {
                        str = unpacked_source;
                    }
                }
                catch (error)
                {
                    // well, it failed. we'll just return the original, instead of crashing on user.
                }
            }
            return str;
        },
        _starts_with: function (str, what)
        {
            return str.substr(0, what.length) === what;
        },
        run_tests: function (sanity_test)
        {
            var t = sanity_test || new SanityTest();
            t.test_function(P_A_C_K_E_R.detect, "P_A_C_K_E_R.detect");
            t.expect('', false);
            t.expect('var a = b', false);
            t.expect('eval(function(p,a,c,k,e,r', true);
            t.expect('eval ( function(p, a, c, k, e, r', true);
            t.test_function(P_A_C_K_E_R.unpack, 'P_A_C_K_E_R.unpack');
            t.expect("eval(function(p,a,c,k,e,r){e=String;if(!''.replace(/^/,String)){while(c--)r[c]=k[c]||c;k=[function(e){return r[e]}];e=function(){return'\\\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\\\b'+e(c)+'\\\\b','g'),k[c]);return p}('0 2=1',3,3,'var||a'.split('|'),0,{}))", 'var a=1');
            var starts_with_a = function (what)
                {
                    return P_A_C_K_E_R._starts_with(what, 'a');
                }
            t.test_function(starts_with_a, "P_A_C_K_E_R._starts_with(?, a)");
            t.expect('abc', true);
            t.expect('bcd', false);
            t.expect('a', true);
            t.expect('', false);
            return t;
        }
    }
    //
    // trivial bookmarklet/escaped script detector for the javascript beautifier
    // written by Einar Lielmanis <einar@jsbeautifier.org>
    //
    // usage:
    //
    // if (Urlencoded.detect(some_string)) {
    //     var unpacked = Urlencoded.unpack(some_string);
    // }
    // 
    //
    var Urlencoded =
    {
        detect: function (str)
        {
            // the fact that script doesn't contain any space, but has %20 instead
            // should be sufficient check for now.
    //        if (str.indexOf(' ') == -1)
    //        {
    //            if (str.indexOf('%20') != -1) return true;
    //            if (str.replace(/[^%]+/g, '').length > 3) return true;
    //        }
            return false;
        },
        unpack: function (str)
        {
            if (Urlencoded.detect(str))
            {
                return unescape(str.replace(/\+/g, '%20'));
            }
            return str;
        },
        run_tests: function (sanity_test)
        {
            var t = sanity_test || new SanityTest();
            t.test_function(Urlencoded.detect, "Urlencoded.detect");
            t.expect('', false);
            t.expect('var a = b', false);
            t.expect('var%20a+=+b', true);
            t.expect('var%20a=b', true);
            t.expect('var%20%21%22', true);
            t.test_function(Urlencoded.unpack, 'Urlencoded.unpack');
            t.expect('', '');
            t.expect('abcd', 'abcd');
            t.expect('var a = b', 'var a = b');
            t.expect('var%20a=b', 'var a=b');
            t.expect('var%20a+=+b', 'var a = b');
            return t;
        }
    }
    //
    // simple unpacker/deobfuscator for scripts messed up with javascriptobfuscator.com
    // written by Einar Lielmanis <einar@jsbeautifier.org>
    //
    // usage:
    //
    // if (JavascriptObfuscator.detect(some_string)) {
    //     var unpacked = JavascriptObfuscator.unpack(some_string);
    // }
    // 
    //
    var JavascriptObfuscator =
    {
        detect: function (str)
        {
            return /^var _0x[a-f0-9]+ ?\= ?\[/.test(str);
        },
        unpack: function (str)
        {
            if (JavascriptObfuscator.detect(str))
            {
                var matches = /var (_0x[a-f\d]+) ?\= ?\[(.*?)\];/.exec(str);
                if (matches)
                {
                    var var_name = matches[1];
                    var strings = JavascriptObfuscator._smart_split(matches[2]);
                    var str = str.substring(matches[0].length);
                    for (var k in strings)
                    {
                        str = str.replace(new RegExp(var_name + '\\[' + k + '\\]', 'g'), JavascriptObfuscator._fix_quotes(JavascriptObfuscator._unescape(strings[k])));
                    }
                }
            }
            return str;
        },
        _fix_quotes: function (str)
        {
            var matches = /^"(.*)"$/.exec(str);
            if (matches)
            {
                str = matches[1];
                str = "'" + str.replace(/'/g, "\\'") + "'";
            }
            return str;
        },
        _smart_split: function (str)
        {
            var strings = [];
            var pos = 0;
            while (pos < str.length)
            {
                if (str.charAt(pos) == '"')
                {
                    // new word
                    var word = '';
                    pos += 1;
                    while (pos < str.length)
                    {
                        if (str.charAt(pos) == '"')
                        {
                            break;
                        }
                        if (str.charAt(pos) == '\\')
                        {
                            word += '\\';
                            pos++;
                        }
                        word += str.charAt(pos);
                        pos++;
                    }
                    strings.push('"' + word + '"');
                }
                pos += 1;
            }
            return strings;
        },
        _unescape: function (str)
        {
            // inefficient if used repeatedly or on small strings, but wonderful on single large chunk of text
            for (var i = 32; i < 128; i++)
            {
                str = str.replace(new RegExp('\\\\x' + i.toString(16), 'ig'), String.fromCharCode(i));
            }
            return str;
        },
        run_tests: function (sanity_test)
        {
            var t = sanity_test || new SanityTest();
            t.test_function(JavascriptObfuscator._smart_split, "JavascriptObfuscator._smart_split");
            t.expect('', []);
            t.expect('"a", "b"', ['"a"', '"b"']);
            t.expect('"aaa","bbbb"', ['"aaa"', '"bbbb"']);
            t.expect('"a", "b\\\""', ['"a"', '"b\\\""']);
            t.test_function(JavascriptObfuscator._unescape, 'JavascriptObfuscator._unescape');
            t.expect('\\x40', '@');
            t.expect('\\x10', '\\x10');
            t.expect('\\x1', '\\x1');
            t.expect("\\x61\\x62\\x22\\x63\\x64", 'ab"cd');
            t.test_function(JavascriptObfuscator.detect, 'JavascriptObfuscator.detect');
            t.expect('', false);
            t.expect('abcd', false);
            t.expect('var _0xaaaa', false);
            t.expect('var _0xaaaa = ["a", "b"]', true);
            t.expect('var _0xaaaa=["a", "b"]', true);
            t.expect('var _0x1234=["a","b"]', true);
            return t;
        }
    }
    //
    // simple unpacker/deobfuscator for scripts messed up with myobfuscate.com
    // You really don't want to obfuscate your scripts there: they're tracking
    // your unpackings, your script gets turned into something like this,
    // as of 2011-04-25:
    /*
        var _escape = 'your_script_escaped';
        var _111 = document.createElement('script');
        _111.src = 'http://api.www.myobfuscate.com/?getsrc=ok' +
            '&ref=' + encodeURIComponent(document.referrer) +
            '&url=' + encodeURIComponent(document.URL);
        var 000 = document.getElementsByTagName('head')[0];
        000.appendChild(_111);
        document.write(unescape(_escape));
    */
    //
    // written by Einar Lielmanis <einar@jsbeautifier.org>
    //
    // usage:
    //
    // if (MyObfuscate.detect(some_string)) {
    //     var unpacked = MyObfuscate.unpack(some_string);
    // }
    //
    //
    var MyObfuscate =
    {
        detect: function (str)
        {
            return /^var _?[0O1lI]{3}\=('|\[).*\)\)\);/.test(str);
        },
        unpack: function (str)
        {
            if (MyObfuscate.detect(str))
            {
                var modified_source = str.replace(';eval(', ';unpacked_source = (');
                var unpacked_source = '';
                eval(modified_source);
                if (unpacked_source)
                {
                    if (MyObfuscate.starts_with(unpacked_source, 'var _escape'))
                    {
                        // fetch the urlencoded stuff from the script,
                        var matches = /'([^']*)'/.exec(unpacked_source);
                        var unescaped = unescape(matches[1]);
                        if (MyObfuscate.starts_with(unescaped, '<script>'))
                        {
                            unescaped = unescaped.substr(8, unescaped.length - 8);
                        }
                        if (MyObfuscate.ends_with(unescaped, '</script>'))
                        {
                            unescaped = unescaped.substr(0, unescaped.length - 9);
                        }
                        unpacked_source = unescaped;
                    }
                }
                return unpacked_source ? "// Unpacker warning: be careful when using myobfuscate.com for your projects:\n" + "// scripts obfuscated by the free online version call back home.\n" + "\n//\n" + unpacked_source : str;
            }
            return str;
        },
        starts_with: function (str, what)
        {
            return str.substr(0, what.length) === what;
        },
        ends_with: function (str, what)
        {
            return str.substr(str.length - what.length, what.length) === what;
        },
        run_tests: function (sanity_test)
        {
            var t = sanity_test || new SanityTest();
            return t;
        }
    }
    //
    // simple testing interface
    // written by Einar Lielmanis, einar@jsbeautifier.org
    //
    // usage:
    //
    // var t = new SanityTest(function (x) { return x; }, 'my function');
    // t.expect('input', 'output');
    // t.expect('a', 'a');
    // output_somewhere(t.results()); // good for <pre>, html safe-ish
    // alert(t.results_raw());        // html unescaped
    function SanityTest(func, test_name)
    {
        var test_func = func ||
        function (x)
        {
            return x;
        }
        var test_name = test_name || '';
        var n_failed = 0;
        var n_succeeded = 0;
        var failures = [];
        this.test_function = function (func, name)
        {
            test_func = func;
            test_name = name || '';
        }
        this.expect = function (parameters, expected_value)
        {
            // multi-parameter calls not supported (I don't need them now).
            var result = test_func(parameters);
            // proper array checking is a pain. i'll maybe do it later, compare strings representations instead
            if ((result === expected_value) || (expected_value instanceof Array && result.join(', ') == expected_value.join(', ')))
            {
                n_succeeded += 1;
            }
            else
            {
                n_failed += 1;
                failures.push([test_name, parameters, expected_value, result]);
            }
        }
        this.results_raw = function ()
        {
            var results = '';
            if (n_failed === 0)
            {
                if (n_succeeded === 0)
                {
                    results = 'No tests run.';
                }
                else
                {
                    results = 'All ' + n_succeeded + ' tests passed.';
                }
            }
            else
            {
                for (var i = 0; i < failures.length; i++)
                {
                    var f = failures[i];
                    if (f[0])
                    {
                        f[0] = f[0] + ' ';
                    }
                    results += '---- ' + f[0] + 'input -------\n' + this.prettyprint(f[1]) + '\n';
                    results += '---- ' + f[0] + 'expected ----\n' + this.prettyprint(f[2]) + '\n';
                    results += '---- ' + f[0] + 'output ------\n' + this.prettyprint(f[3]) + '\n\n';
                }
                results += n_failed + ' tests failed.\n';
            }
            return results;
        }
        this.results = function ()
        {
            return this.lazy_escape(this.results_raw());
        }
        this.prettyprint = function (something, quote_strings)
        {
            var type = typeof something;
            switch (type.toLowerCase())
            {
            case 'string':
                if (quote_strings)
                {
                    return "'" + something.replace("'", "\\'") + "'";
                }
                else
                {
                    return something;
                }
            case 'number':
                return '' + something;
            case 'boolean':
                return something ? 'true' : 'false';
            case 'undefined':
                return 'undefined';
            case 'object':
                if (something instanceof Array)
                {
                    var x = [];
                    var expected_index = 0;
                    // modified by Microshaoft
                    for (k in something)
                    //for (var k in something)
                    {
                        if (k == expected_index)
                        {
                            x.push(this.prettyprint(something[k], true));
                            expected_index += 1;
                        }
                        else
                        {
                            x.push('\n' + k + ': ' + this.prettyprint(something[k], true));
                        }
                    }
                    return '[' + x.join(', ') + ']';
                }
                else
                {
                    return 'object: ' + something;
                }
            default:
                return type + ': ' + something;
            }
        }
        this.lazy_escape = function (str)
        {
            return str.replace(/</g, '&lt;').replace(/\>/g, '&gt;').replace(/\n/g, '<br />');
        }
        this.log = function ()
        {
            // comments by Microshaoft begin ======================================================
            //        if (window.console) {
            //            if (console.firebug) {
            //                console.log.apply(console, Array.prototype.slice.call(arguments));
            //            } else {
            //                console.log.call(console, Array.prototype.slice.call(arguments));
            //            }
            //        }
            // comments by Microshaoft end ======================================================
        };
    }
    // add by Microshaoft begin ===========================================================
    WScript.Echo("/*");
    WScript.Echo(" * Beautifyed by using \"Microshaoft.beautify.CScript.js\"");
    WScript.Echo(" * \"Microshaoft.beautify.exe\" is invented for EditPlus user tool by using WScript");
    WScript.Echo(" * Thanks for \"http://jsbeautifier.org/\" supply \"https://github.com/einars/js-beautify\"");
    WScript.Echo(" */");
    var opts =
                {
                    indent_size: 1,
                    indent_char: '\t',
                    preserve_newlines: true,
                    brace_style: "expand-strict",
                    keep_array_indentation: true,
                    space_after_anon_function: true,
                    space_before_conditional: true,
                    indent_scripts: true
                };
    s = beautify(s, opts);
    WScript.Echo(s);
    // add by Microshaoft end ===========================================================
    
    
  • 相关阅读:
    JS面向对象的理解
    引用类型值的相等判断
    数组的常用方法
    得到一定范围内的随机数
    数组随机排序
    【目标检测大集合】R-FCN、SSD、YOLO2、faster-rcnn和labelImg实验笔记
    卷积层和池化层学习
    R-FCN:基于区域的全卷积网络来检测物体
    【目标检测】Faster RCNN算法详解
    Selective Search for Object Recognition
  • 原文地址:https://www.cnblogs.com/Microshaoft/p/2485221.html
Copyright © 2011-2022 走看看