├── .gitignore ├── Support ├── lib │ ├── jsbeautifier │ │ ├── core │ │ │ ├── __init__.py │ │ │ ├── token.py │ │ │ ├── directives.py │ │ │ ├── tokenstream.py │ │ │ ├── whitespacepattern.py │ │ │ ├── pattern.py │ │ │ ├── tokenizer.py │ │ │ ├── inputscanner.py │ │ │ ├── templatablepattern.py │ │ │ ├── options.py │ │ │ └── output.py │ │ ├── tests │ │ │ ├── __init__.py │ │ │ ├── core │ │ │ │ ├── __init__.py │ │ │ │ ├── test_options.py │ │ │ │ └── test_inputscanner.py │ │ │ ├── testindentation.py │ │ │ └── shell-test.sh │ │ ├── __version__.py │ │ ├── javascript │ │ │ ├── __init__.py │ │ │ ├── options.py │ │ │ └── acorn.py │ │ ├── unpackers │ │ │ ├── tests │ │ │ │ ├── __init__.py │ │ │ │ ├── testurlencode.py │ │ │ │ ├── testmyobfuscate.py │ │ │ │ ├── testjavascriptobfuscator.py │ │ │ │ ├── test-myobfuscate-output.js │ │ │ │ ├── test-packer-62-input.js │ │ │ │ ├── testpacker.py │ │ │ │ ├── test-packer-non62-input.js │ │ │ │ └── test-myobfuscate-input.js │ │ │ ├── README.specs.mkd │ │ │ ├── urlencode.py │ │ │ ├── evalbased.py │ │ │ ├── javascriptobfuscator.py │ │ │ ├── __init__.py │ │ │ ├── myobfuscate.py │ │ │ └── packer.py │ │ ├── cli │ │ │ └── __init__.py │ │ └── __init__.py │ └── jsbeautifier-license.txt └── jsmate.rb ├── Snippets ├── log.tmSnippet ├── warn.tmSnippet ├── case.tmSnippet ├── else.tmSnippet ├── error.tmSnippet ├── if.tmSnippet ├── throw.tmSnippet ├── do.tmSnippet ├── getElementById.tmSnippet ├── function (fun).plist ├── while.tmSnippet ├── for … of.tmSnippet ├── getElementsByName.tmSnippet ├── function.tmSnippet ├── Object Method.tmSnippet ├── getElementsByTagName.tmSnippet ├── Arrow Function.tmSnippet ├── Class.tmSnippet ├── getElementsByClassName.tmSnippet ├── try.tmSnippet ├── if ... else.tmSnippet ├── Prototype (proto).plist ├── setTimeout function.tmSnippet ├── setInterval function.tmSnippet ├── Immediately-Invoked Function Expression.tmSnippet ├── for (…) {…}.tmSnippet ├── switch.tmSnippet ├── Object key — key: "value".tmSnippet ├── for … in.tmSnippet ├── Insert ${} - Template Strings.tmSnippet └── for (…) {…} (faster).tmSnippet ├── Preferences ├── Symbol List.tmPreferences ├── Folding.tmPreferences ├── Comments.tmPreferences └── JavaScript Indent.tmPreferences ├── Macros └── Overwrite } in #{ .. }.tmMacro ├── Commands ├── New Method.tmCommand ├── Documentation for Word.plist ├── New Function.tmCommand ├── Reformat Document : Selection.tmCommand ├── Toggle Quote Style.tmCommand └── Copy as Bookmarklet to Clipboard.tmCommand ├── README.mdown ├── info.plist └── Syntaxes └── Regular Expressions (JavaScript).tmLanguage /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | -------------------------------------------------------------------------------- /Support/lib/jsbeautifier/core/__init__.py: -------------------------------------------------------------------------------- 1 | # Empty file :) 2 | -------------------------------------------------------------------------------- /Support/lib/jsbeautifier/tests/__init__.py: -------------------------------------------------------------------------------- 1 | # Empty file :) 2 | -------------------------------------------------------------------------------- /Support/lib/jsbeautifier/__version__.py: -------------------------------------------------------------------------------- 1 | __version__ = "1.14.3" 2 | -------------------------------------------------------------------------------- /Support/lib/jsbeautifier/javascript/__init__.py: -------------------------------------------------------------------------------- 1 | # Empty file :) 2 | -------------------------------------------------------------------------------- /Support/lib/jsbeautifier/tests/core/__init__.py: -------------------------------------------------------------------------------- 1 | # Empty file :) 2 | -------------------------------------------------------------------------------- /Support/lib/jsbeautifier/unpackers/tests/__init__.py: -------------------------------------------------------------------------------- 1 | # Empty file :) 2 | # pylint: disable=C0111 3 | -------------------------------------------------------------------------------- /Snippets/log.tmSnippet: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | content 6 | console.log(${1:$TM_SELECTED_TEXT}); 7 | name 8 | log 9 | scope 10 | source.js 11 | tabTrigger 12 | log 13 | uuid 14 | 3E69BFC9-8C2B-4BB3-875C-8673C1740FD4 15 | 16 | 17 | -------------------------------------------------------------------------------- /Snippets/warn.tmSnippet: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | content 6 | console.warn(${1:$TM_SELECTED_TEXT}); 7 | name 8 | warn 9 | scope 10 | source.js 11 | tabTrigger 12 | warn 13 | uuid 14 | 9B27DBEA-56C1-4484-ACC7-0A5A05CFF9A8 15 | 16 | 17 | -------------------------------------------------------------------------------- /Snippets/case.tmSnippet: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | content 6 | case ${1:expression}: 7 | $2 8 | break; 9 | name 10 | case 11 | scope 12 | source.js 13 | tabTrigger 14 | case 15 | uuid 16 | 7A28A364-65AF-4D8D-A26B-D057D7C2A14E 17 | 18 | 19 | -------------------------------------------------------------------------------- /Snippets/else.tmSnippet: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | content 6 | else { 7 | ${1:$TM_SELECTED_TEXT} 8 | } 9 | name 10 | else 11 | scope 12 | source.js 13 | tabTrigger 14 | else 15 | uuid 16 | 5BA406DB-A4B1-4CED-BA61-33D378FD7F53 17 | 18 | 19 | -------------------------------------------------------------------------------- /Snippets/error.tmSnippet: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | content 6 | console.error(${1:$TM_SELECTED_TEXT}); 7 | name 8 | error 9 | scope 10 | source.js 11 | tabTrigger 12 | error 13 | uuid 14 | D7E2FD2A-5B78-4147-BBF4-BE7FE854A337 15 | 16 | 17 | -------------------------------------------------------------------------------- /Snippets/if.tmSnippet: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | content 6 | if (${1:true}) { 7 | ${2:$TM_SELECTED_TEXT} 8 | } 9 | name 10 | if 11 | scope 12 | source.js 13 | tabTrigger 14 | if 15 | uuid 16 | F19F3732-39A7-48EC-A72B-A8F477A01795 17 | 18 | 19 | -------------------------------------------------------------------------------- /Snippets/throw.tmSnippet: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | content 6 | throw new ${1:Error}(${2:$TM_SELECTED_TEXT}); 7 | name 8 | throw 9 | scope 10 | source.js 11 | tabTrigger 12 | throw 13 | uuid 14 | C1FE098B-501D-4567-B024-5C9C394898E5 15 | 16 | 17 | -------------------------------------------------------------------------------- /Snippets/do.tmSnippet: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | content 6 | do { 7 | ${2:$TM_SELECTED_TEXT} 8 | } while (${1:true}); 9 | name 10 | do 11 | scope 12 | source.js 13 | tabTrigger 14 | do 15 | uuid 16 | 0FF6F54D-AFE0-4FC5-9A15-E837A167689C 17 | 18 | 19 | -------------------------------------------------------------------------------- /Snippets/getElementById.tmSnippet: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | content 6 | getElementById(${1:'${2:id}'}) 7 | name 8 | getElementById 9 | scope 10 | source.js 11 | tabTrigger 12 | get 13 | uuid 14 | B2225C2E-59BD-4AD5-9554-755A9864D7F1 15 | 16 | 17 | -------------------------------------------------------------------------------- /Snippets/function (fun).plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | content 6 | function ${1:functionName}($2) { 7 | $0 8 | } 9 | name 10 | Function 11 | scope 12 | source.js 13 | tabTrigger 14 | fun 15 | uuid 16 | F0E4FB6A-4878-48C6-A777-62438DF1E14F 17 | 18 | 19 | -------------------------------------------------------------------------------- /Snippets/while.tmSnippet: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | content 6 | while (${1:true}) { 7 | ${2:$TM_SELECTED_TEXT} 8 | } 9 | name 10 | while 11 | scope 12 | source.js 13 | tabTrigger 14 | while 15 | uuid 16 | 009514ED-12AE-440F-811E-CD7D41368DBF 17 | 18 | 19 | -------------------------------------------------------------------------------- /Snippets/for … of.tmSnippet: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | content 6 | for (${1:variable} of ${2:iterable}) { 7 | $3 8 | } 9 | name 10 | for … of 11 | scope 12 | source.js 13 | tabTrigger 14 | forof 15 | uuid 16 | 02710093-EED2-4721-8957-8863EB206AB8 17 | 18 | 19 | -------------------------------------------------------------------------------- /Snippets/getElementsByName.tmSnippet: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | content 6 | getElementsByName(${1:'${2:name}'}) 7 | name 8 | getElementsByName 9 | scope 10 | source.js 11 | tabTrigger 12 | get 13 | uuid 14 | 0701FB35-5C3C-453D-9ADE-8A0B7D1E617E 15 | 16 | 17 | -------------------------------------------------------------------------------- /Snippets/function.tmSnippet: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | content 6 | function ($1) { 7 | ${0:$TM_SELECTED_TEXT} 8 | } 9 | name 10 | Anonymous Function 11 | scope 12 | source.js 13 | tabTrigger 14 | f 15 | uuid 16 | 4C6EDB43-3E2E-411B-A016-13C135C59833 17 | 18 | 19 | -------------------------------------------------------------------------------- /Snippets/Object Method.tmSnippet: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | content 6 | ${1:methodName}: function ($3) { 7 | $0 8 | }${10:,} 9 | name 10 | Object Method 11 | scope 12 | source.js 13 | tabTrigger 14 | :f 15 | uuid 16 | 77065D69-742A-4FF0-9A41-AD211DFBE72F 17 | 18 | 19 | -------------------------------------------------------------------------------- /Snippets/getElementsByTagName.tmSnippet: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | content 6 | getElementsByTagName(${1:'${2:tagName}'}) 7 | name 8 | getElementsByTagName 9 | scope 10 | source.js 11 | tabTrigger 12 | get 13 | uuid 14 | C4CA6356-DBC9-4F0D-AA9B-8577692DEBB2 15 | 16 | 17 | -------------------------------------------------------------------------------- /Snippets/Arrow Function.tmSnippet: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | content 6 | ($1) => ${2:{ 7 | ${0:$TM_SELECTED_TEXT} 8 | \}} 9 | name 10 | Arrow Function 11 | scope 12 | source.js 13 | tabTrigger 14 | > 15 | uuid 16 | 400D48C9-CE90-4A0B-AF77-AE9CA6C21A70 17 | 18 | 19 | -------------------------------------------------------------------------------- /Snippets/Class.tmSnippet: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | content 6 | class ${1:ClassName} { 7 | constructor($2) { 8 | $3 9 | } 10 | } 11 | name 12 | Class 13 | scope 14 | source.js 15 | tabTrigger 16 | class 17 | uuid 18 | 66C3F21C-5762-40D7-A383-ABDFFC26EFE5 19 | 20 | 21 | -------------------------------------------------------------------------------- /Snippets/getElementsByClassName.tmSnippet: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | content 6 | getElementsByClassName(${1:'${2:className}'}) 7 | name 8 | getElementsByClassName 9 | scope 10 | source.js 11 | tabTrigger 12 | get 13 | uuid 14 | 923442DA-69C2-4681-B57D-510BB1312E9E 15 | 16 | 17 | -------------------------------------------------------------------------------- /Snippets/try.tmSnippet: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | content 6 | try { 7 | $1 8 | } catch (${2:e) { 9 | $3 10 | }${4: finally { 11 | $5 12 | \}} 13 | name 14 | try 15 | scope 16 | source.js 17 | tabTrigger 18 | try 19 | uuid 20 | 4B1F658D-CB1C-4D10-968D-A443F8597C28 21 | 22 | 23 | -------------------------------------------------------------------------------- /Snippets/if ... else.tmSnippet: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | content 6 | if (${1:true}) { 7 | ${2:$TM_SELECTED_TEXT} 8 | } else { 9 | $3 10 | } 11 | name 12 | if … else 13 | scope 14 | source.js 15 | tabTrigger 16 | ife 17 | uuid 18 | 31964029-9D71-4ADC-8213-DFE5C4E222B3 19 | 20 | 21 | -------------------------------------------------------------------------------- /Snippets/Prototype (proto).plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | content 6 | ${1:ClassName}.prototype.${2:methodName} = function ($3) { 7 | $0 8 | }; 9 | name 10 | Prototype 11 | scope 12 | source.js 13 | tabTrigger 14 | proto 15 | uuid 16 | 2F96136B-0193-42F5-90FC-B6F456A3AD77 17 | 18 | 19 | -------------------------------------------------------------------------------- /Preferences/Symbol List.tmPreferences: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | name 6 | Symbol List 7 | scope 8 | source.js entity.name.function.js, source.js meta.function.js meta.function.variable.js 9 | settings 10 | 11 | showInSymbolList 12 | 1 13 | 14 | uuid 15 | 6FF7E4FD-64C1-4162-85ED-CE40511A2414 16 | 17 | 18 | -------------------------------------------------------------------------------- /Snippets/setTimeout function.tmSnippet: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | content 6 | setTimeout(${2:function () { 7 | ${3:$TM_SELECTED_TEXT} 8 | \}}, ${1:10}); 9 | name 10 | setTimeout function 11 | scope 12 | source.js 13 | tabTrigger 14 | timeout 15 | uuid 16 | 009A3E6C-FE3F-4A18-8759-2DC31F17BBE2 17 | 18 | 19 | -------------------------------------------------------------------------------- /Snippets/setInterval function.tmSnippet: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | content 6 | setInterval(${2:function () { 7 | ${3:$TM_SELECTED_TEXT} 8 | \}}, ${1:10}); 9 | name 10 | setInterval function 11 | scope 12 | source.js 13 | tabTrigger 14 | interval 15 | uuid 16 | 3A00B409-6E94-4E27-8050-45F04EB9765A 17 | 18 | 19 | -------------------------------------------------------------------------------- /Snippets/Immediately-Invoked Function Expression.tmSnippet: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | content 6 | (function() { 7 | ${1:$TM_SELECTED_TEXT} 8 | }()); 9 | name 10 | Immediately-Invoked Function Expression 11 | scope 12 | source.js 13 | tabTrigger 14 | iife 15 | uuid 16 | 20E20EB2-E795-4097-86CF-D40E44DC4E70 17 | 18 | 19 | -------------------------------------------------------------------------------- /Snippets/for (…) {…}.tmSnippet: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | content 6 | for (${2:var }${20:i} = 0; ${20:i} < ${1:Things}.length; ${20:i}++) { 7 | ${100:${1:Things}[${20:i}]} 8 | } 9 | name 10 | for (…) {…} 11 | scope 12 | source.js 13 | tabTrigger 14 | for 15 | uuid 16 | 011C4681-FBEC-4891-9326-3DECFCDED6D6 17 | 18 | 19 | -------------------------------------------------------------------------------- /Snippets/switch.tmSnippet: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | content 6 | switch (${1:expression}) { 7 | case ${2:expression}: 8 | $4 9 | break;$5 10 | default: 11 | ${3:$TM_SELECTED_TEXT} 12 | } 13 | name 14 | switch 15 | scope 16 | source.js 17 | tabTrigger 18 | switch 19 | uuid 20 | 13386ECB-2A5C-4881-9D54-035BC8B0A4A1 21 | 22 | 23 | -------------------------------------------------------------------------------- /Snippets/Object key — key: "value".tmSnippet: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | content 6 | ${1:key}: ${2:"${3:value}"}${4:, } 7 | keyEquivalent 8 | ~: 9 | name 10 | Object key — key: "value" 11 | scope 12 | source.js 13 | tabTrigger 14 | : 15 | uuid 16 | DC8B46FB-8ADA-45EA-8F36-94C807A0D302 17 | 18 | 19 | -------------------------------------------------------------------------------- /Preferences/Folding.tmPreferences: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | name 6 | Folding 7 | scope 8 | source.js 9 | settings 10 | 11 | foldingStartMarker 12 | \{\s*(//.*)?$|\[\s*(//.*)?$|\(\s*(//.*)?$ 13 | foldingStopMarker 14 | ^\s*\}|^\s*\]|^\s*\) 15 | 16 | uuid 17 | 1E044101-68F8-410B-8FF5-E9553AD14B7C 18 | 19 | 20 | -------------------------------------------------------------------------------- /Snippets/for … in.tmSnippet: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | content 6 | for (${1:variable} in ${2:object}) { 7 | ${3:if (${2:object}.hasOwnProperty(${1:variable})) { 8 | ${4:$TM_SELECTED_TEXT} 9 | \}} 10 | } 11 | name 12 | for … in 13 | scope 14 | source.js 15 | tabTrigger 16 | forin 17 | uuid 18 | 3AFF0ECE-A475-4CFB-832B-EE551D90B8E5 19 | 20 | 21 | -------------------------------------------------------------------------------- /Snippets/Insert ${} - Template Strings.tmSnippet: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | content 6 | \${${1:$TM_SELECTED_TEXT}} 7 | hideFromUser 8 | 9 | keyEquivalent 10 | $ 11 | name 12 | Insert ${} - Template Strings 13 | scope 14 | B:string.quoted.other.template.js - string source 15 | uuid 16 | 0DA0E112-971D-4D7F-B2C9-BCACE0CA61B3 17 | 18 | 19 | -------------------------------------------------------------------------------- /Snippets/for (…) {…} (faster).tmSnippet: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | content 6 | for (${2:var }${20:i} = ${1:Things}.length - 1; ${20:i} >= 0; ${20:i}--) { 7 | ${100:${1:Things}[${20:i}]} 8 | } 9 | name 10 | for (…) {…} (Improved Native For-Loop) 11 | scope 12 | source.js 13 | tabTrigger 14 | for 15 | uuid 16 | C207B7C3-5597-4873-8AAD-C46FB8842AF2 17 | 18 | 19 | -------------------------------------------------------------------------------- /Macros/Overwrite } in #{ .. }.tmMacro: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | commands 6 | 7 | 8 | command 9 | moveRight: 10 | 11 | 12 | hideFromUser 13 | 14 | keyEquivalent 15 | } 16 | name 17 | Overwrite '}' in ${ .. } 18 | scope 19 | source.js string meta.embedded.line.js punctuation.section.embedded.end.js 20 | uuid 21 | 9A836C03-5693-49FA-B587-6EAF76EE743A 22 | 23 | 24 | -------------------------------------------------------------------------------- /Preferences/Comments.tmPreferences: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | name 6 | Comments 7 | scope 8 | source.js 9 | settings 10 | 11 | shellVariables 12 | 13 | 14 | name 15 | TM_COMMENT_START 16 | value 17 | // 18 | 19 | 20 | name 21 | TM_COMMENT_START_2 22 | value 23 | /* 24 | 25 | 26 | name 27 | TM_COMMENT_END_2 28 | value 29 | */ 30 | 31 | 32 | 33 | uuid 34 | A67A8BD9-A951-406F-9175-018DD4B52FD1 35 | 36 | 37 | -------------------------------------------------------------------------------- /Commands/New Method.tmCommand: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | beforeRunningCommand 6 | nop 7 | command 8 | #!/usr/bin/env bash 9 | 10 | cat <<SNIPPET 11 | ${TM_SELECTED_TEXT:-$TM_CURRENT_WORD}: function (\$1) { 12 | \$0 13 | }\${2:,} 14 | SNIPPET 15 | fallbackInput 16 | word 17 | input 18 | selection 19 | inputFormat 20 | text 21 | keyEquivalent 22 | ~$ 23 | name 24 | New Method 25 | outputCaret 26 | afterOutput 27 | outputFormat 28 | snippet 29 | outputLocation 30 | replaceInput 31 | scope 32 | source.js 33 | uuid 34 | 1717B5AE-209B-4548-9155-9E88A7230C1C 35 | version 36 | 2 37 | 38 | 39 | -------------------------------------------------------------------------------- /Support/lib/jsbeautifier/unpackers/README.specs.mkd: -------------------------------------------------------------------------------- 1 | # UNPACKERS SPECIFICATIONS 2 | 3 | Nothing very difficult: an unpacker is a submodule placed in the directory 4 | where this file was found. Each unpacker must define three symbols: 5 | 6 | * `PRIORITY` : integer number expressing the priority in applying this 7 | unpacker. Lower number means higher priority. 8 | Makes sense only if a source file has been packed with 9 | more than one packer. 10 | * `detect(source)` : returns `True` if source is packed, otherwise, `False`. 11 | * `unpack(source)` : takes a `source` string and unpacks it. Must always return 12 | valid JavaScript. That is to say, your code should look 13 | like: 14 | 15 | ``` 16 | if detect(source): 17 | return do_your_fancy_things_with(source) 18 | else: 19 | return source 20 | ``` 21 | 22 | *You can safely define any other symbol in your module, as it will be ignored.* 23 | 24 | `__init__` code will automatically load new unpackers, without any further step 25 | to be accomplished. Simply drop it in this directory. 26 | -------------------------------------------------------------------------------- /Support/lib/jsbeautifier-license.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2007-2018 Einar Lielmanis, Liam Newman, and contributors. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /Support/lib/jsbeautifier/unpackers/urlencode.py: -------------------------------------------------------------------------------- 1 | # 2 | # Trivial bookmarklet/escaped script detector for the javascript beautifier 3 | # written by Einar Lielmanis 4 | # rewritten in Python by Stefano Sanfilippo 5 | # 6 | # Will always return valid javascript: if `detect()` is false, `code` is 7 | # returned, unmodified. 8 | # 9 | # usage: 10 | # 11 | # some_string = urlencode.unpack(some_string) 12 | # 13 | 14 | """Bookmarklet/escaped script unpacker.""" 15 | 16 | # Python 2 retrocompatibility 17 | # pylint: disable=F0401 18 | # pylint: disable=E0611 19 | try: 20 | from urllib import unquote_plus 21 | except ImportError: 22 | from urllib.parse import unquote_plus 23 | 24 | PRIORITY = 0 25 | 26 | 27 | def detect(code): 28 | """Detects if a scriptlet is urlencoded.""" 29 | # the fact that script doesn't contain any space, but has %20 instead 30 | # should be sufficient check for now. 31 | return " " not in code and ("%20" in code or code.count("%") > 3) 32 | 33 | 34 | def unpack(code): 35 | """URL decode `code` source string.""" 36 | return unquote_plus(code) if detect(code) else code 37 | -------------------------------------------------------------------------------- /README.mdown: -------------------------------------------------------------------------------- 1 | # Installation 2 | 3 | You can install this bundle in TextMate by opening the preferences and going to the bundles tab. After installation it will be automatically updated for you. 4 | 5 | # General 6 | 7 | * [Bundle Styleguide](http://kb.textmate.org/bundle_styleguide) — _before you make changes_ 8 | * [Commit Styleguide](http://kb.textmate.org/commit_styleguide) — _before you send a pull request_ 9 | * [Writing Bug Reports](http://kb.textmate.org/writing_bug_reports) — _before you report an issue_ 10 | 11 | # License 12 | 13 | If not otherwise specified (see below), files in this repository fall under the following license: 14 | 15 | Permission to copy, use, modify, sell and distribute this 16 | software is granted. This software is provided "as is" without 17 | express or implied warranty, and with no claim as to its 18 | suitability for any purpose. 19 | 20 | An exception is made for files in readable text which contain their own license information, or files where an accompanying file exists (in the same directory) with a “-license” suffix added to the base-name name of the original file, and an extension of txt, html, or similar. For example “tidy” is accompanied by “tidy-license.txt”. -------------------------------------------------------------------------------- /Commands/Documentation for Word.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | beforeRunningCommand 6 | nop 7 | command 8 | #!/usr/bin/env ruby18 9 | 10 | require "#{ENV['TM_BUNDLE_SUPPORT']}/jsmate" 11 | 12 | JavaScript::documentationForWord 13 | 14 | fallbackInput 15 | word 16 | input 17 | selection 18 | inputFormat 19 | text 20 | keyEquivalent 21 | ^h 22 | name 23 | Documentation for Word / Selection 24 | outputCaret 25 | afterOutput 26 | outputFormat 27 | text 28 | outputLocation 29 | toolTip 30 | scope 31 | source.js 32 | semanticClass 33 | lookup.define.js 34 | uuid 35 | B4874A14-2491-465A-A349-61E4EBCF4700 36 | version 37 | 2 38 | 39 | 40 | -------------------------------------------------------------------------------- /Commands/New Function.tmCommand: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | beforeRunningCommand 6 | nop 7 | command 8 | #!/bin/bash 9 | [[ -f "${TM_SUPPORT_PATH}/lib/bash_init.sh" ]] && . "${TM_SUPPORT_PATH}/lib/bash_init.sh" 10 | 11 | cat <<SNIPPET 12 | function ${TM_SELECTED_TEXT:-$TM_CURRENT_WORD}(\$1) { 13 | \$0 14 | } 15 | SNIPPET 16 | fallbackInput 17 | word 18 | input 19 | selection 20 | inputFormat 21 | text 22 | keyEquivalent 23 | $ 24 | name 25 | New Function 26 | outputCaret 27 | afterOutput 28 | outputFormat 29 | snippet 30 | outputLocation 31 | replaceInput 32 | scope 33 | source.js 34 | uuid 35 | 73951799-AC15-40A6-81DB-EC051AB4A033 36 | version 37 | 2 38 | 39 | 40 | -------------------------------------------------------------------------------- /Support/lib/jsbeautifier/unpackers/tests/testurlencode.py: -------------------------------------------------------------------------------- 1 | # 2 | # written by Stefano Sanfilippo 3 | # 4 | 5 | """Tests for urlencoded unpacker.""" 6 | 7 | import unittest 8 | 9 | from jsbeautifier.unpackers.urlencode import detect, unpack 10 | 11 | # pylint: disable=R0904 12 | 13 | 14 | class TestUrlencode(unittest.TestCase): 15 | """urlencode test case.""" 16 | 17 | def test_detect(self): 18 | """Test detect() function.""" 19 | 20 | def encoded(source): 21 | return self.assertTrue(detect(source)) 22 | 23 | def unencoded(source): 24 | return self.assertFalse(detect(source)) 25 | 26 | unencoded("") 27 | unencoded("var a = b") 28 | encoded("var%20a+=+b") 29 | encoded("var%20a=b") 30 | encoded("var%20%21%22") 31 | 32 | def test_unpack(self): 33 | """Test unpack function.""" 34 | 35 | def equals(source, result): 36 | return self.assertEqual(unpack(source), result) 37 | 38 | equals("", "") 39 | equals("abcd", "abcd") 40 | equals("var a = b", "var a = b") 41 | equals("var%20a=b", "var a=b") 42 | equals("var%20a+=+b", "var a = b") 43 | 44 | 45 | if __name__ == "__main__": 46 | unittest.main() 47 | -------------------------------------------------------------------------------- /Support/lib/jsbeautifier/unpackers/evalbased.py: -------------------------------------------------------------------------------- 1 | # 2 | # Unpacker for eval() based packers, a part of javascript beautifier 3 | # by Einar Lielmanis 4 | # 5 | # written by Stefano Sanfilippo 6 | # 7 | # usage: 8 | # 9 | # if detect(some_string): 10 | # unpacked = unpack(some_string) 11 | # 12 | 13 | """Unpacker for eval() based packers: runs JS code and returns result. 14 | Works only if a JS interpreter (e.g. Mozilla's Rhino) is installed and 15 | properly set up on host.""" 16 | 17 | from subprocess import PIPE, Popen 18 | 19 | PRIORITY = 3 20 | 21 | 22 | def detect(source): 23 | """Detects if source is likely to be eval() packed.""" 24 | return source.strip().lower().startswith("eval(function(") 25 | 26 | 27 | def unpack(source): 28 | """Runs source and return resulting code.""" 29 | return jseval("print %s;" % source[4:]) if detect(source) else source 30 | 31 | 32 | # In case of failure, we'll just return the original, without crashing on user. 33 | 34 | 35 | def jseval(script): 36 | """Run code in the JS interpreter and return output.""" 37 | try: 38 | interpreter = Popen(["js"], stdin=PIPE, stdout=PIPE) 39 | except OSError: 40 | return script 41 | result, errors = interpreter.communicate(script) 42 | if interpreter.poll() or errors: 43 | return script 44 | return result 45 | -------------------------------------------------------------------------------- /Commands/Reformat Document : Selection.tmCommand: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | beforeRunningCommand 6 | nop 7 | command 8 | #!/usr/bin/env python3 9 | 10 | import os 11 | import sys 12 | 13 | sys.path.append(os.path.join(os.environ["TM_BUNDLE_SUPPORT"], "lib")) 14 | 15 | import jsbeautifier 16 | 17 | opts = jsbeautifier.default_options() 18 | 19 | if os.environ["TM_SOFT_TABS"] == 'NO': 20 | opts.indent_size = 1 21 | opts.indent_char = '\t' 22 | else: 23 | opts.indent_size = int(os.environ["TM_TAB_SIZE"]) 24 | 25 | print(jsbeautifier.beautify_file('-', opts)) 26 | 27 | input 28 | selection 29 | inputFormat 30 | text 31 | keyEquivalent 32 | ^H 33 | name 34 | Reformat Document / Selection 35 | outputCaret 36 | heuristic 37 | outputFormat 38 | text 39 | outputLocation 40 | replaceInput 41 | scope 42 | source.js 43 | uuid 44 | 36EC03E9-EFF4-479A-AB90-8DFA16800642 45 | version 46 | 2 47 | 48 | 49 | -------------------------------------------------------------------------------- /Support/lib/jsbeautifier/unpackers/tests/testmyobfuscate.py: -------------------------------------------------------------------------------- 1 | # 2 | # written by Stefano Sanfilippo 3 | # 4 | 5 | """Tests for MyObfuscate unpacker.""" 6 | 7 | import unittest 8 | import os 9 | from jsbeautifier.unpackers.myobfuscate import detect, unpack 10 | from jsbeautifier.unpackers.tests import __path__ as path 11 | 12 | INPUT = os.path.join(path[0], "test-myobfuscate-input.js") 13 | OUTPUT = os.path.join(path[0], "test-myobfuscate-output.js") 14 | 15 | # pylint: disable=R0904 16 | 17 | 18 | class TestMyObfuscate(unittest.TestCase): 19 | # pylint: disable=C0103 20 | """MyObfuscate obfuscator testcase.""" 21 | 22 | @classmethod 23 | def setUpClass(cls): 24 | """Load source files (encoded and decoded version) for tests.""" 25 | with open(INPUT, "r") as data: 26 | cls.input = data.read() 27 | with open(OUTPUT, "r") as data: 28 | cls.output = data.read() 29 | 30 | def test_detect(self): 31 | """Test detect() function.""" 32 | 33 | def detected(source): 34 | return self.assertTrue(detect(source)) 35 | 36 | detected(self.input) 37 | 38 | def test_unpack(self): 39 | """Test unpack() function.""" 40 | 41 | def check(inp, out): 42 | return self.assertEqual(unpack(inp), out) 43 | 44 | check(self.input, self.output) 45 | 46 | 47 | if __name__ == "__main__": 48 | unittest.main() 49 | -------------------------------------------------------------------------------- /Commands/Toggle Quote Style.tmCommand: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | beforeRunningCommand 6 | nop 7 | command 8 | #!/usr/bin/env ruby18 9 | 10 | class String 11 | def escape(char) 12 | gsub(/\\.|#{Regexp.quote(char)}/) { |match| match == char ? "\\#{char}" : match } 13 | end 14 | 15 | def unescape(char) 16 | gsub(/\\./) { |match| match == "\\#{char}" ? char : match } 17 | end 18 | end 19 | 20 | print case str = STDIN.read 21 | when /\A"(.*)"\z/m; "'" + $1.unescape('"').escape("'") + "'" 22 | when /\A'(.*)'\z/m; '`' + $1.unescape("'").escape('`') + '`' 23 | when /\A`(.*)`\z/m; '"' + $1.unescape("`").escape('"') + '"' 24 | else str 25 | end 26 | 27 | hideFromUser 28 | 29 | input 30 | scope 31 | inputFormat 32 | text 33 | keyEquivalent 34 | ^" 35 | name 36 | Toggle Quote Style 37 | outputCaret 38 | interpolateByChar 39 | outputFormat 40 | text 41 | outputLocation 42 | replaceInput 43 | scope 44 | source.js string.quoted.double, source.js string.quoted.single, source.js string.quoted.other.template 45 | uuid 46 | 3CB25F61-ABB1-45FD-B7ED-2D65FF2CB84F 47 | version 48 | 2 49 | 50 | 51 | -------------------------------------------------------------------------------- /Support/lib/jsbeautifier/tests/testindentation.py: -------------------------------------------------------------------------------- 1 | import re 2 | import unittest 3 | import jsbeautifier 4 | 5 | 6 | class TestJSBeautifierIndentation(unittest.TestCase): 7 | def test_tabs(self): 8 | test_fragment = self.decodesto 9 | 10 | self.options.indent_with_tabs = 1 11 | test_fragment("{tabs()}", "{\n\ttabs()\n}") 12 | 13 | def test_function_indent(self): 14 | test_fragment = self.decodesto 15 | 16 | self.options.indent_with_tabs = 1 17 | self.options.keep_function_indentation = 1 18 | test_fragment( 19 | "var foo = function(){ bar() }();", "var foo = function() {\n\tbar()\n}();" 20 | ) 21 | 22 | self.options.tabs = 1 23 | self.options.keep_function_indentation = 0 24 | test_fragment( 25 | "var foo = function(){ baz() }();", "var foo = function() {\n\tbaz()\n}();" 26 | ) 27 | 28 | def decodesto(self, input, expectation=None): 29 | self.assertEqual( 30 | jsbeautifier.beautify(input, self.options), expectation or input 31 | ) 32 | 33 | @classmethod 34 | def setUpClass(cls): 35 | options = jsbeautifier.default_options() 36 | options.indent_size = 4 37 | options.indent_char = " " 38 | options.preserve_newlines = True 39 | options.jslint_happy = False 40 | options.keep_array_indentation = False 41 | options.brace_style = "collapse" 42 | options.indent_level = 0 43 | 44 | cls.options = options 45 | cls.wrapregex = re.compile("^(.+)$", re.MULTILINE) 46 | 47 | 48 | if __name__ == "__main__": 49 | unittest.main() 50 | -------------------------------------------------------------------------------- /Support/lib/jsbeautifier/core/token.py: -------------------------------------------------------------------------------- 1 | # The MIT License (MIT) 2 | # 3 | # Copyright (c) 2007-2018 Einar Lielmanis, Liam Newman, and contributors. 4 | # 5 | # Permission is hereby granted, free of charge, to any person 6 | # obtaining a copy of this software and associated documentation files 7 | # (the "Software"), to deal in the Software without restriction, 8 | # including without limitation the rights to use, copy, modify, merge, 9 | # publish, distribute, sublicense, and/or sell copies of the Software, 10 | # and to permit persons to whom the Software is furnished to do so, 11 | # subject to the following conditions: 12 | # 13 | # The above copyright notice and this permission notice shall be 14 | # included in all copies or substantial portions of the Software. 15 | # 16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 20 | # BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 21 | # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22 | # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | # SOFTWARE. 24 | 25 | 26 | class Token: 27 | def __init__(self, type, text, newlines=0, whitespace_before=""): 28 | self.type = type 29 | self.text = text 30 | self.comments_before = None 31 | self.newlines = newlines 32 | self.whitespace_before = whitespace_before 33 | self.parent = None 34 | self.next = None 35 | self.previous = None 36 | self.opened = None 37 | self.closed = None 38 | self.directives = None 39 | -------------------------------------------------------------------------------- /Support/lib/jsbeautifier/unpackers/tests/testjavascriptobfuscator.py: -------------------------------------------------------------------------------- 1 | # 2 | # written by Stefano Sanfilippo 3 | # 4 | 5 | """Tests for JavaScriptObfuscator unpacker.""" 6 | 7 | import unittest 8 | from jsbeautifier.unpackers.javascriptobfuscator import unpack, detect, smartsplit 9 | 10 | # pylint: disable=R0904 11 | 12 | 13 | class TestJavascriptObfuscator(unittest.TestCase): 14 | """JavascriptObfuscator.com test case.""" 15 | 16 | def test_smartsplit(self): 17 | """Test smartsplit() function.""" 18 | split = smartsplit 19 | 20 | def equals(data, result): 21 | return self.assertEqual(split(data), result) 22 | 23 | equals("", []) 24 | equals('"a", "b"', ['"a"', '"b"']) 25 | equals('"aaa","bbbb"', ['"aaa"', '"bbbb"']) 26 | equals('"a", "b\\""', ['"a"', '"b\\""']) 27 | 28 | def test_detect(self): 29 | """Test detect() function.""" 30 | 31 | def positive(source): 32 | return self.assertTrue(detect(source)) 33 | 34 | def negative(source): 35 | return self.assertFalse(detect(source)) 36 | 37 | negative("") 38 | negative("abcd") 39 | negative("var _0xaaaa") 40 | positive('var _0xaaaa = ["a", "b"]') 41 | positive('var _0xaaaa=["a", "b"]') 42 | positive('var _0x1234=["a","b"]') 43 | 44 | def test_unpack(self): 45 | """Test unpack() function.""" 46 | 47 | def decodeto(ob, original): 48 | return self.assertEqual(unpack(ob), original) 49 | 50 | decodeto("var _0x8df3=[];var a=10;", "var a=10;") 51 | decodeto( 52 | 'var _0xb2a7=["\x74\x27\x65\x73\x74"];var i;for(i=0;i<10;++i)' 53 | "{alert(_0xb2a7[0]);} ;", 54 | "var i;for(i=0;i<10;++i){alert" '("t\'est");} ;', 55 | ) 56 | 57 | 58 | if __name__ == "__main__": 59 | unittest.main() 60 | -------------------------------------------------------------------------------- /Support/lib/jsbeautifier/unpackers/javascriptobfuscator.py: -------------------------------------------------------------------------------- 1 | # 2 | # simple unpacker/deobfuscator for scripts messed up with 3 | # javascriptobfuscator.com 4 | # 5 | # written by Einar Lielmanis 6 | # rewritten in Python by Stefano Sanfilippo 7 | # 8 | # Will always return valid javascript: if `detect()` is false, `code` is 9 | # returned, unmodified. 10 | # 11 | # usage: 12 | # 13 | # if javascriptobfuscator.detect(some_string): 14 | # some_string = javascriptobfuscator.unpack(some_string) 15 | # 16 | 17 | """deobfuscator for scripts messed up with JavascriptObfuscator.com""" 18 | 19 | import re 20 | 21 | PRIORITY = 1 22 | 23 | 24 | def smartsplit(code): 25 | """Split `code` at " symbol, only if it is not escaped.""" 26 | strings = [] 27 | pos = 0 28 | while pos < len(code): 29 | if code[pos] == '"': 30 | word = "" # new word 31 | pos += 1 32 | while pos < len(code): 33 | if code[pos] == '"': 34 | break 35 | if code[pos] == "\\": 36 | word += "\\" 37 | pos += 1 38 | word += code[pos] 39 | pos += 1 40 | strings.append('"%s"' % word) 41 | pos += 1 42 | return strings 43 | 44 | 45 | def detect(code): 46 | """Detects if `code` is JavascriptObfuscator.com packed.""" 47 | # prefer `is not` idiom, so that a true boolean is returned 48 | return re.search(r"^var _0x[a-f0-9]+ ?\= ?\[", code) is not None 49 | 50 | 51 | def unpack(code): 52 | """Unpacks JavascriptObfuscator.com packed code.""" 53 | if detect(code): 54 | matches = re.search(r"var (_0x[a-f\d]+) ?\= ?\[(.*?)\];", code) 55 | if matches: 56 | variable = matches.group(1) 57 | dictionary = smartsplit(matches.group(2)) 58 | code = code[len(matches.group(0)) :] 59 | for key, value in enumerate(dictionary): 60 | code = code.replace(r"%s[%s]" % (variable, key), value) 61 | return code 62 | -------------------------------------------------------------------------------- /Commands/Copy as Bookmarklet to Clipboard.tmCommand: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | beforeRunningCommand 6 | nop 7 | command 8 | #!/usr/bin/env perl 9 | # 10 | # Written by John Gruber, taken with permission from: 11 | # http://daringfireball.net/2007/03/javascript_bookmarklet_builder 12 | 13 | use strict; 14 | use warnings; 15 | use URI::Escape qw(uri_escape_utf8); 16 | use open IO => ":utf8", # UTF8 by default 17 | ":std"; # Apply to STDIN/STDOUT/STDERR 18 | 19 | my $src = do { local $/; <> }; 20 | 21 | # Zap the first line if there's already a bookmarklet comment: 22 | $src =~ s{^// ?javascript:.+\n}{}; 23 | my $bookmarklet = $src; 24 | 25 | $bookmarklet =~ s{^\s*//.+\n}{}gm; # Kill comments. 26 | $bookmarklet =~ s{\t}{ }gm; # Tabs to spaces 27 | $bookmarklet =~ s{ +}{ }gm; # Space runs to one space 28 | $bookmarklet =~ s{^\s+}{}gm; # Kill line-leading whitespace 29 | $bookmarklet =~ s{\s+$}{}gm; # Kill line-ending whitespace 30 | $bookmarklet =~ s{\n}{}gm; # Kill newlines 31 | 32 | # Escape single- and double-quotes, spaces, control chars, unicode: 33 | $bookmarklet = "javascript:" . 34 | uri_escape_utf8($bookmarklet, qq('" \x00-\x1f\x7f-\xff)); 35 | 36 | print "// $bookmarklet\n" . $src; 37 | 38 | # Put bookmarklet on clipboard: 39 | `/bin/echo -n '$bookmarklet' | /usr/bin/pbcopy`; 40 | 41 | input 42 | selection 43 | inputFormat 44 | text 45 | name 46 | Copy as Bookmarklet to Clipboard 47 | outputCaret 48 | heuristic 49 | outputFormat 50 | text 51 | outputLocation 52 | replaceInput 53 | scope 54 | source.js 55 | uuid 56 | 20E61C43-B81F-4FB9-9362-BFFE668EB9C9 57 | version 58 | 2 59 | 60 | 61 | -------------------------------------------------------------------------------- /Preferences/JavaScript Indent.tmPreferences: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | name 6 | Indentation 7 | scope 8 | source.js 9 | settings 10 | 11 | decreaseIndentPattern 12 | (?x) 13 | ^ \s* ( (?! \S.* /[*] ) .* [*]/ \s* )? [})\]] 14 | | ^ \s* (case\b.*|default): \s* ( // .* | /[*] .* [*]/ \s* )? $ 15 | 16 | increaseIndentPattern 17 | (?x) 18 | ( \{ [^}"']* 19 | | \( [^)"']* 20 | | \[ [^\]"']* 21 | | ^ \s* ( \{ \} | \( \) | \[ \] 22 | | (case\b.*|default): 23 | ) 24 | ) 25 | \s* ( // .* | /[*] .* [*]/ \s* )? $ 26 | 27 | indentNextLinePattern 28 | (?x) 29 | ^ \s* (for|while|if|else)\b 30 | # Disregard if line ends with semi-colon or braces 31 | (?! .* [;{}] \s* ( // .* | /[*] .* [*]/ \s* )? $ ) 32 | 33 | unIndentedLinePattern 34 | (?x)^ 35 | # Ignore lines that do not end with (semi-)colon or braces 36 | (?! .* ([;{}] | \S:) \s* ( // .* | /[*] .* [*]/ \s* )? $ ) 37 | 38 | # Unless the line is matched by any of the rules above 39 | (?! .* 40 | # increaseIndentPattern 41 | ( \{ [^}"']* 42 | | \( [^)"']* 43 | | \[ [^\]"']* 44 | | ^ \s* ( \{ \} | \( \) | \[ \] 45 | | (case\b.*|default): 46 | ) 47 | ) 48 | \s* ( // .* | /[*] .* [*]/ \s* )? $ 49 | ) 50 | 51 | (?! 52 | # decreaseIndentPattern 53 | ^ \s* ( (?! \S.* /[*] ) .* [*]/ \s* )? [})\]] 54 | | ^ \s* (case\b.*|default): \s* ( // .* | /[*] .* [*]/ \s* )? $ 55 | ) 56 | 57 | (?! 58 | # indentNextLinePattern 59 | ^ \s* (for|while|if|else)\b 60 | (?! .* [;{}] \s* ( // .* | /[*] .* [*]/ \s* )? $ ) 61 | ) 62 | 63 | 64 | uuid 65 | BC062860-3346-4D3B-8421-C5543F83D11F 66 | 67 | 68 | -------------------------------------------------------------------------------- /Support/lib/jsbeautifier/core/directives.py: -------------------------------------------------------------------------------- 1 | # The MIT License (MIT) 2 | # 3 | # Copyright (c) 2007-2018 Einar Lielmanis, Liam Newman, and contributors. 4 | # 5 | # Permission is hereby granted, free of charge, to any person 6 | # obtaining a copy of this software and associated documentation files 7 | # (the "Software"), to deal in the Software without restriction, 8 | # including without limitation the rights to use, copy, modify, merge, 9 | # publish, distribute, sublicense, and/or sell copies of the Software, 10 | # and to permit persons to whom the Software is furnished to do so, 11 | # subject to the following conditions: 12 | # 13 | # The above copyright notice and this permission notice shall be 14 | # included in all copies or substantial portions of the Software. 15 | # 16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 20 | # BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 21 | # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22 | # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | # SOFTWARE. 24 | 25 | import re 26 | 27 | 28 | class Directives: 29 | def __init__(self, start_block_pattern, end_block_pattern): 30 | 31 | self.__directives_block_pattern = re.compile( 32 | start_block_pattern + r" beautify( \w+[:]\w+)+ " + end_block_pattern 33 | ) 34 | self.__directive_pattern = re.compile(r" (\w+)[:](\w+)") 35 | 36 | self.__directives_end_ignore_pattern = re.compile( 37 | start_block_pattern + r"\sbeautify\signore:end\s" + end_block_pattern 38 | ) 39 | 40 | def get_directives(self, text): 41 | if not self.__directives_block_pattern.match(text): 42 | return None 43 | 44 | directives = {} 45 | directive_match = self.__directive_pattern.search(text) 46 | 47 | while directive_match: 48 | directives[directive_match.group(1)] = directive_match.group(2) 49 | directive_match = self.__directive_pattern.search( 50 | text, directive_match.end() 51 | ) 52 | 53 | return directives 54 | 55 | def readIgnored(self, input): 56 | return input.readUntilAfter(self.__directives_end_ignore_pattern) 57 | -------------------------------------------------------------------------------- /Support/lib/jsbeautifier/unpackers/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # General code for JSBeautifier unpackers infrastructure. See README.specs 3 | # written by Stefano Sanfilippo 4 | # 5 | 6 | """General code for JSBeautifier unpackers infrastructure.""" 7 | 8 | import pkgutil 9 | import re 10 | from jsbeautifier.unpackers import evalbased 11 | 12 | # NOTE: AT THE MOMENT, IT IS DEACTIVATED FOR YOUR SECURITY: it runs js! 13 | BLACKLIST = ["jsbeautifier.unpackers.evalbased"] 14 | 15 | 16 | class UnpackingError(Exception): 17 | """Badly packed source or general error. Argument is a 18 | meaningful description.""" 19 | 20 | pass 21 | 22 | 23 | def getunpackers(): 24 | """Scans the unpackers dir, finds unpackers and add them to UNPACKERS list. 25 | An unpacker will be loaded only if it is a valid python module (name must 26 | adhere to naming conventions) and it is not blacklisted (i.e. inserted 27 | into BLACKLIST.""" 28 | path = __path__ 29 | prefix = __name__ + "." 30 | unpackers = [] 31 | interface = ["unpack", "detect", "PRIORITY"] 32 | for _importer, modname, _ispkg in pkgutil.iter_modules(path, prefix): 33 | if "tests" not in modname and modname not in BLACKLIST: 34 | try: 35 | module = __import__(modname, fromlist=interface) 36 | except ImportError: 37 | raise UnpackingError("Bad unpacker: %s" % modname) 38 | else: 39 | unpackers.append(module) 40 | 41 | return sorted(unpackers, key=lambda mod: mod.PRIORITY) 42 | 43 | 44 | UNPACKERS = getunpackers() 45 | 46 | 47 | def run(source, evalcode=False): 48 | """Runs the applicable unpackers and return unpacked source as a string.""" 49 | for unpacker in [mod for mod in UNPACKERS if mod.detect(source)]: 50 | source = unpacker.unpack(source) 51 | if evalcode and evalbased.detect(source): 52 | source = evalbased.unpack(source) 53 | return source 54 | 55 | 56 | def filtercomments(source): 57 | """NOT USED: strips trailing comments and put them at the top.""" 58 | trailing_comments = [] 59 | comment = True 60 | 61 | while comment: 62 | if re.search(r"^\s*\/\*", source): 63 | comment = source[0, source.index("*/") + 2] 64 | elif re.search(r"^\s*\/\/", source): 65 | comment = re.search(r"^\s*\/\/", source).group(0) 66 | else: 67 | comment = None 68 | 69 | if comment: 70 | source = re.sub(r"^\s+", "", source[len(comment) :]) 71 | trailing_comments.append(comment) 72 | 73 | return "\n".join(trailing_comments) + source 74 | -------------------------------------------------------------------------------- /Support/lib/jsbeautifier/core/tokenstream.py: -------------------------------------------------------------------------------- 1 | # The MIT License (MIT) 2 | # 3 | # Copyright (c) 2007-2018 Einar Lielmanis, Liam Newman, and contributors. 4 | # 5 | # Permission is hereby granted, free of charge, to any person 6 | # obtaining a copy of this software and associated documentation files 7 | # (the "Software"), to deal in the Software without restriction, 8 | # including without limitation the rights to use, copy, modify, merge, 9 | # publish, distribute, sublicense, and/or sell copies of the Software, 10 | # and to permit persons to whom the Software is furnished to do so, 11 | # subject to the following conditions: 12 | # 13 | # The above copyright notice and this permission notice shall be 14 | # included in all copies or substantial portions of the Software. 15 | # 16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 20 | # BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 21 | # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22 | # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | # SOFTWARE. 24 | 25 | import re 26 | from ..core.inputscanner import InputScanner 27 | from ..core.token import Token 28 | 29 | 30 | class TokenStream: 31 | def __init__(self, parent_token=None): 32 | self.__tokens = [] 33 | self.__tokens_length = len(self.__tokens) 34 | self.__position = 0 35 | self.__parent_token = parent_token 36 | 37 | def restart(self): 38 | self.__position = 0 39 | 40 | def isEmpty(self): 41 | return self.__tokens_length == 0 42 | 43 | def hasNext(self): 44 | return self.__position < self.__tokens_length 45 | 46 | def next(self): 47 | if self.hasNext(): 48 | val = self.__tokens[self.__position] 49 | self.__position += 1 50 | return val 51 | else: 52 | raise StopIteration 53 | 54 | def peek(self, index=0): 55 | val = None 56 | index += self.__position 57 | if index >= 0 and index < self.__tokens_length: 58 | val = self.__tokens[index] 59 | 60 | return val 61 | 62 | def add(self, token): 63 | if self.__parent_token: 64 | token.parent = self.__parent_token 65 | 66 | self.__tokens.append(token) 67 | self.__tokens_length += 1 68 | 69 | def __iter__(self): 70 | self.restart() 71 | return self 72 | 73 | def __next__(self): 74 | return self.next() 75 | -------------------------------------------------------------------------------- /Support/lib/jsbeautifier/unpackers/tests/test-myobfuscate-output.js: -------------------------------------------------------------------------------- 1 | // 2 | // Unpacker warning: be careful when using myobfuscate.com for your projects: 3 | // scripts obfuscated by the free online version call back home. 4 | // 5 | 6 | // 7 | // Unpacker for Dean Edward's p.a.c.k.e.r, a part of javascript beautifier 8 | // written by Einar Lielmanis 9 | // 10 | // Coincidentally, it can defeat a couple of other eval-based compressors. 11 | // 12 | // usage: 13 | // 14 | // if (P_A_C_K_E_R.detect(some_string)) { 15 | // var unpacked = P_A_C_K_E_R.unpack(some_string); 16 | // } 17 | // 18 | // 19 | 20 | var P_A_C_K_E_R = { 21 | detect: function (str) { 22 | return P_A_C_K_E_R._starts_with(str.toLowerCase().replace(/ +/g, ''), 'eval(function(') || 23 | P_A_C_K_E_R._starts_with(str.toLowerCase().replace(/ +/g, ''), 'eval((function(') ; 24 | }, 25 | 26 | unpack: function (str) { 27 | var unpacked_source = ''; 28 | if (P_A_C_K_E_R.detect(str)) { 29 | try { 30 | eval('unpacked_source = ' + str.substring(4) + ';') 31 | if (typeof unpacked_source == 'string' && unpacked_source) { 32 | str = unpacked_source; 33 | } 34 | } catch (error) { 35 | // well, it failed. we'll just return the original, instead of crashing on user. 36 | } 37 | } 38 | return str; 39 | }, 40 | 41 | _starts_with: function (str, what) { 42 | return str.substr(0, what.length) === what; 43 | }, 44 | 45 | run_tests: function (sanity_test) { 46 | var t = sanity_test || new SanityTest(); 47 | t.test_function(P_A_C_K_E_R.detect, "P_A_C_K_E_R.detect"); 48 | t.expect('', false); 49 | t.expect('var a = b', false); 50 | t.expect('eval(function(p,a,c,k,e,r', true); 51 | t.expect('eval ( function(p, a, c, k, e, r', true); 52 | 53 | t.test_function(P_A_C_K_E_R.unpack, 'P_A_C_K_E_R.unpack'); 54 | 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,{}))", 55 | 'var a=1'); 56 | 57 | var starts_with_a = function(what) { return P_A_C_K_E_R._starts_with(what, 'a'); } 58 | t.test_function(starts_with_a, "P_A_C_K_E_R._starts_with(?, a)"); 59 | t.expect('abc', true); 60 | t.expect('bcd', false); 61 | t.expect('a', true); 62 | t.expect('', false); 63 | return t; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /Support/lib/jsbeautifier/core/whitespacepattern.py: -------------------------------------------------------------------------------- 1 | # The MIT License (MIT) 2 | # 3 | # Copyright (c) 2007-2018 Einar Lielmanis, Liam Newman, and contributors. 4 | # 5 | # Permission is hereby granted, free of charge, to any person 6 | # obtaining a copy of this software and associated documentation files 7 | # (the "Software"), to deal in the Software without restriction, 8 | # including without limitation the rights to use, copy, modify, merge, 9 | # publish, distribute, sublicense, and/or sell copies of the Software, 10 | # and to permit persons to whom the Software is furnished to do so, 11 | # subject to the following conditions: 12 | # 13 | # The above copyright notice and this permission notice shall be 14 | # included in all copies or substantial portions of the Software. 15 | # 16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 20 | # BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 21 | # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22 | # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | # SOFTWARE. 24 | 25 | import re 26 | from ..core.pattern import Pattern 27 | 28 | __all__ = ["WhitespacePattern"] 29 | 30 | 31 | class WhitespacePattern(Pattern): 32 | def __init__(self, input_scanner, parent=None): 33 | Pattern.__init__(self, input_scanner, parent) 34 | 35 | if parent is not None: 36 | self._newline_regexp = self._input.get_regexp(parent._newline_regexp) 37 | else: 38 | self.__set_whitespace_patterns("", "") 39 | 40 | self.newline_count = 0 41 | self.whitespace_before_token = "" 42 | 43 | def __set_whitespace_patterns(self, whitespace_chars, newline_chars): 44 | whitespace_chars += "\\t " 45 | newline_chars += "\\n\\r" 46 | 47 | self._match_pattern = self._input.get_regexp( 48 | "[" + whitespace_chars + newline_chars + "]+" 49 | ) 50 | self._newline_regexp = self._input.get_regexp("\\r\\n|[" + newline_chars + "]") 51 | 52 | def read(self): 53 | self.newline_count = 0 54 | self.whitespace_before_token = "" 55 | 56 | resulting_string = self._input.read(self._match_pattern) 57 | if resulting_string == " ": 58 | self.whitespace_before_token = " " 59 | elif bool(resulting_string): 60 | lines = self._newline_regexp.split(resulting_string) 61 | self.newline_count = len(lines) - 1 62 | self.whitespace_before_token = lines[-1] 63 | 64 | return resulting_string 65 | 66 | def matching(self, whitespace_chars, newline_chars): 67 | result = self._create() 68 | result.__set_whitespace_patterns(whitespace_chars, newline_chars) 69 | result._update() 70 | return result 71 | 72 | def _create(self): 73 | return WhitespacePattern(self._input, self) 74 | -------------------------------------------------------------------------------- /Support/lib/jsbeautifier/unpackers/myobfuscate.py: -------------------------------------------------------------------------------- 1 | # 2 | # deobfuscator for scripts messed up with myobfuscate.com 3 | # by Einar Lielmanis 4 | # 5 | # written by Stefano Sanfilippo 6 | # 7 | # usage: 8 | # 9 | # if detect(some_string): 10 | # unpacked = unpack(some_string) 11 | # 12 | 13 | # CAVEAT by Einar Lielmanis 14 | 15 | # 16 | # You really don't want to obfuscate your scripts there: they're tracking 17 | # your unpackings, your script gets turned into something like this, 18 | # as of 2011-08-26: 19 | # 20 | # var _escape = 'your_script_escaped'; 21 | # var _111 = document.createElement('script'); 22 | # _111.src = 'http://api.www.myobfuscate.com/?getsrc=ok' + 23 | # '&ref=' + encodeURIComponent(document.referrer) + 24 | # '&url=' + encodeURIComponent(document.URL); 25 | # var 000 = document.getElementsByTagName('head')[0]; 26 | # 000.appendChild(_111); 27 | # document.write(unescape(_escape)); 28 | # 29 | 30 | """Deobfuscator for scripts messed up with MyObfuscate.com""" 31 | 32 | import re 33 | import base64 34 | 35 | # Python 2 retrocompatibility 36 | # pylint: disable=F0401 37 | # pylint: disable=E0611 38 | try: 39 | from urllib import unquote 40 | except ImportError: 41 | from urllib.parse import unquote 42 | 43 | from jsbeautifier.unpackers import UnpackingError 44 | 45 | PRIORITY = 1 46 | 47 | CAVEAT = """// 48 | // Unpacker warning: be careful when using myobfuscate.com for your projects: 49 | // scripts obfuscated by the free online version call back home. 50 | // 51 | 52 | """ 53 | 54 | SIGNATURE = ( 55 | r'["\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4A\x4B\x4C\x4D\x4E\x4F' 56 | r"\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5A\x61\x62\x63\x64\x65" 57 | r"\x66\x67\x68\x69\x6A\x6B\x6C\x6D\x6E\x6F\x70\x71\x72\x73\x74\x75" 58 | r"\x76\x77\x78\x79\x7A\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x2B" 59 | r'\x2F\x3D","","\x63\x68\x61\x72\x41\x74","\x69\x6E\x64\x65\x78' 60 | r'\x4F\x66","\x66\x72\x6F\x6D\x43\x68\x61\x72\x43\x6F\x64\x65","' 61 | r'\x6C\x65\x6E\x67\x74\x68"]' 62 | ) 63 | 64 | 65 | def detect(source): 66 | """Detects MyObfuscate.com packer.""" 67 | return SIGNATURE in source 68 | 69 | 70 | def unpack(source): 71 | """Unpacks js code packed with MyObfuscate.com""" 72 | if not detect(source): 73 | return source 74 | payload = unquote(_filter(source)) 75 | match = re.search(r"^var _escape\='