├── .github ├── FUNDING.yml └── workflows │ └── build.yml ├── .gitignore ├── README.md ├── index.html ├── package-lock.json ├── package.json └── src ├── index.js └── tools.js /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: willnode 2 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: Build CI 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | 7 | jobs: 8 | build: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@v2 12 | - name: Install dependencies 13 | run: npm install 14 | - name: Build web 15 | run: npm run build 16 | - name: Deploy to gh-pages 17 | uses: JamesIves/github-pages-deploy-action@4.1.4 18 | with: 19 | branch: gh-pages 20 | folder: ./dist 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | dist 2 | node_modules -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Javascript Deobfuscator 2 | 3 | Need to edit an obfuscated Javascript? This repo is the way to de-obfuscate any kind of obfuscated Javascript, especially if it comes from automatic tools like https://obfuscator.io/. 4 | 5 | Because obfuscation varies wildly in the internet, the process is not automatic. It won't give you one-click-and-it-done but instead it gives you a script editor with tools necessary to deobfucate any kind of javascript (provided you also familiar with how JS works of course). 6 | 7 | Your work is automatically saved to SessionStorage so don't worry about accidental refresh or page navigation. 8 | 9 | ## The Editor 10 | 11 | This tool uses Monaco. The editor that powers VSCode. It itself can do Find + Replace, Undo + Redo, Syntax + Error highlighting, unused variables detection, and other neat stuff. 12 | 13 | ## Formatting Tools 14 | 15 | All formatting tools affects selected text, or all text in editor if none selected. 16 | 17 | #### Format Document 18 | 19 | Beautify javascript for all text in editor. 20 | 21 | You should format your document first before doing other tasks so it reduces chance of your code become corrupt. 22 | 23 | #### Simplify String `simplifyString()` 24 | 25 | This reformats string `''` and `""`. Example `"\x75\x73\x65\x20\x73\x74\x72\x69\x63\x74"` becomes `"use strict"`. 26 | 27 | Currently doesn't work with literal string. Also, it uses regex, so beware with complex string (e.g. `'\''`). 28 | 29 | #### Simplify Number `simplifyNumber()` 30 | 31 | This reformats hex number. Example `0xff` becomes `255`. 32 | 33 | #### Simplify Object Access `simplifyAccess()` 34 | 35 | This reformats object access. Example `document["body"]["style"]["color"]="black";` becomes `document.body.style.color="black";` 36 | 37 | #### Simplify Hex Name `simplifyHex()` 38 | 39 | This renames all variables `_0x[Hex code]` to it's shorter name (`a`, `b`, `c`, etc.). 40 | 41 | Beware that this method isn't 100% safe. It can't detect any variable name collision yet. 42 | 43 | ## Evaluation Tools 44 | 45 | This is a powerful tool to let you evaluate javascript code and reveal it's hidden content. 46 | 47 | It's advised for you to open Browser Console (Ctrl+Shift+I, tab Console) for helpful information. 48 | 49 | #### Push `evalPush()` and Pop `evalPop()` 50 | 51 | Push selected text to "code stack", or pop it. 52 | 53 | It means to be used with eval buttons (explained below). These buttons does nothing on it's own. 54 | 55 | Pushing to code stack means if there's line `A` then you push `B`, then the current stack will be `A\nB` (A followed by B in next line). 56 | 57 | #### Eval Selected `evalStr()` 58 | 59 | Evaluate selected code along with current variables stack on. If it returns any valid JSON value (includes array and object) it will replaces the selected code. 60 | 61 | A practical example is like this: 62 | 63 | ```js 64 | var foo = {'baz' => 'bar'}; 65 | var result = foo['baz']; 66 | ``` 67 | 68 | If you push the first line to stack and then `evalStr` the text `foo['baz']`, it will replaced as `"bar"`. 69 | 70 | #### Eval Auto `evalAuto()` 71 | 72 | Harnessing the power of regex, this "intelligently" replaces any "captured" variable in the selected code, like if you do `evalStr` on each one of them. If it used correctly it will definitely saves you a lot of time. 73 | 74 | The captured variables are based on the current stack. It will detect all `var`/`const`/`let`. If the evaluation returns string or number, it will be replaced. 75 | 76 | 77 | #### Sync Vars `syncVar()` 78 | 79 | Select a word variable and any derived variable names will be magically recusively replaced. Example select `foo` and then `let bar = foo; let baz = bar; console.log(baz)` will simply become `console.log(foo)`. Combined with `evalAuto` both are destructive yet very time saving operation. 80 | 81 | ## Hidden Evaluation Tools 82 | 83 | These tools are experimental. Although it's useful in certain cases. To access it you need to call the function in browser console. 84 | 85 | #### `evalBareStr` 86 | 87 | Similar like `evalStr`, but without `JSON.stringify`. This is useful for extracting code out of eval string, for example. 88 | 89 | #### `simplifyStringExp` 90 | 91 | Similar like `simplifyString`, but also merges string concatenation (e.g. `"foo" + "bar"`). Because it's flexibility, it only detects double quote `""` right now. Proceed with caution. 92 | 93 | #### `simplifyNumberExp` 94 | 95 | Similar like `simplifyNumber`, but also merges number operations (e.g. `-1 + 2`). Because it's flexibility, it only detect regular number. Proceed with caution. 96 | 97 | #### `splitVar` 98 | 99 | Split two or more concatenated `const`/`let`/`var` definitions in a selected single expression. It does not simply naively replace `,`, it's aware about array/object presence. Because of that you can't just select multiple functions and expect it gots the effect too. Still kinda useful for readability. 100 | 101 | 102 | Feel free to requests other operation ideas in Issue Tracker. 103 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Javascript Deobfuscator 8 | 9 | 10 | 40 | 41 | 42 | 43 | 54 | 64 |
65 | 66 | 67 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "deobfuscator", 3 | "lockfileVersion": 2, 4 | "requires": true, 5 | "packages": { 6 | "": { 7 | "name": "deobfuscator", 8 | "license": "MIT", 9 | "dependencies": { 10 | "js-beautify": "^1.14.8", 11 | "monaco-editor": "^0.39.0" 12 | }, 13 | "devDependencies": { 14 | "@types/js-beautify": "^1.13.3", 15 | "vite": "^4.3.9" 16 | } 17 | }, 18 | "node_modules/@esbuild/darwin-arm64": { 19 | "version": "0.17.19", 20 | "cpu": [ 21 | "arm64" 22 | ], 23 | "dev": true, 24 | "license": "MIT", 25 | "optional": true, 26 | "os": [ 27 | "darwin" 28 | ], 29 | "engines": { 30 | "node": ">=12" 31 | } 32 | }, 33 | "node_modules/@types/js-beautify": { 34 | "version": "1.13.3", 35 | "resolved": "https://registry.npmjs.org/@types/js-beautify/-/js-beautify-1.13.3.tgz", 36 | "integrity": "sha512-ucIPw5gmNyvRKi6mpeojlqp+T+6ZBJeU+kqMDnIEDlijEU4QhLTon90sZ3cz9HZr+QTwXILjNsMZImzA7+zuJA==", 37 | "dev": true 38 | }, 39 | "node_modules/abbrev": { 40 | "version": "1.1.1", 41 | "license": "ISC" 42 | }, 43 | "node_modules/balanced-match": { 44 | "version": "1.0.2", 45 | "license": "MIT" 46 | }, 47 | "node_modules/brace-expansion": { 48 | "version": "2.0.1", 49 | "license": "MIT", 50 | "dependencies": { 51 | "balanced-match": "^1.0.0" 52 | } 53 | }, 54 | "node_modules/commander": { 55 | "version": "2.20.3", 56 | "license": "MIT" 57 | }, 58 | "node_modules/config-chain": { 59 | "version": "1.1.13", 60 | "license": "MIT", 61 | "dependencies": { 62 | "ini": "^1.3.4", 63 | "proto-list": "~1.2.1" 64 | } 65 | }, 66 | "node_modules/editorconfig": { 67 | "version": "0.15.3", 68 | "license": "MIT", 69 | "dependencies": { 70 | "commander": "^2.19.0", 71 | "lru-cache": "^4.1.5", 72 | "semver": "^5.6.0", 73 | "sigmund": "^1.0.1" 74 | }, 75 | "bin": { 76 | "editorconfig": "bin/editorconfig" 77 | } 78 | }, 79 | "node_modules/esbuild": { 80 | "version": "0.17.19", 81 | "dev": true, 82 | "hasInstallScript": true, 83 | "license": "MIT", 84 | "bin": { 85 | "esbuild": "bin/esbuild" 86 | }, 87 | "engines": { 88 | "node": ">=12" 89 | }, 90 | "optionalDependencies": { 91 | "@esbuild/android-arm": "0.17.19", 92 | "@esbuild/android-arm64": "0.17.19", 93 | "@esbuild/android-x64": "0.17.19", 94 | "@esbuild/darwin-arm64": "0.17.19", 95 | "@esbuild/darwin-x64": "0.17.19", 96 | "@esbuild/freebsd-arm64": "0.17.19", 97 | "@esbuild/freebsd-x64": "0.17.19", 98 | "@esbuild/linux-arm": "0.17.19", 99 | "@esbuild/linux-arm64": "0.17.19", 100 | "@esbuild/linux-ia32": "0.17.19", 101 | "@esbuild/linux-loong64": "0.17.19", 102 | "@esbuild/linux-mips64el": "0.17.19", 103 | "@esbuild/linux-ppc64": "0.17.19", 104 | "@esbuild/linux-riscv64": "0.17.19", 105 | "@esbuild/linux-s390x": "0.17.19", 106 | "@esbuild/linux-x64": "0.17.19", 107 | "@esbuild/netbsd-x64": "0.17.19", 108 | "@esbuild/openbsd-x64": "0.17.19", 109 | "@esbuild/sunos-x64": "0.17.19", 110 | "@esbuild/win32-arm64": "0.17.19", 111 | "@esbuild/win32-ia32": "0.17.19", 112 | "@esbuild/win32-x64": "0.17.19" 113 | } 114 | }, 115 | "node_modules/esbuild/node_modules/@esbuild/android-arm": { 116 | "version": "0.17.19", 117 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.19.tgz", 118 | "integrity": "sha512-rIKddzqhmav7MSmoFCmDIb6e2W57geRsM94gV2l38fzhXMwq7hZoClug9USI2pFRGL06f4IOPHHpFNOkWieR8A==", 119 | "cpu": [ 120 | "arm" 121 | ], 122 | "dev": true, 123 | "optional": true, 124 | "os": [ 125 | "android" 126 | ], 127 | "engines": { 128 | "node": ">=12" 129 | } 130 | }, 131 | "node_modules/esbuild/node_modules/@esbuild/android-arm64": { 132 | "version": "0.17.19", 133 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.17.19.tgz", 134 | "integrity": "sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA==", 135 | "cpu": [ 136 | "arm64" 137 | ], 138 | "dev": true, 139 | "optional": true, 140 | "os": [ 141 | "android" 142 | ], 143 | "engines": { 144 | "node": ">=12" 145 | } 146 | }, 147 | "node_modules/esbuild/node_modules/@esbuild/android-x64": { 148 | "version": "0.17.19", 149 | "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.17.19.tgz", 150 | "integrity": "sha512-uUTTc4xGNDT7YSArp/zbtmbhO0uEEK9/ETW29Wk1thYUJBz3IVnvgEiEwEa9IeLyvnpKrWK64Utw2bgUmDveww==", 151 | "cpu": [ 152 | "x64" 153 | ], 154 | "dev": true, 155 | "optional": true, 156 | "os": [ 157 | "android" 158 | ], 159 | "engines": { 160 | "node": ">=12" 161 | } 162 | }, 163 | "node_modules/esbuild/node_modules/@esbuild/darwin-x64": { 164 | "version": "0.17.19", 165 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.19.tgz", 166 | "integrity": "sha512-IJM4JJsLhRYr9xdtLytPLSH9k/oxR3boaUIYiHkAawtwNOXKE8KoU8tMvryogdcT8AU+Bflmh81Xn6Q0vTZbQw==", 167 | "cpu": [ 168 | "x64" 169 | ], 170 | "dev": true, 171 | "optional": true, 172 | "os": [ 173 | "darwin" 174 | ], 175 | "engines": { 176 | "node": ">=12" 177 | } 178 | }, 179 | "node_modules/esbuild/node_modules/@esbuild/freebsd-arm64": { 180 | "version": "0.17.19", 181 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.19.tgz", 182 | "integrity": "sha512-pBwbc7DufluUeGdjSU5Si+P3SoMF5DQ/F/UmTSb8HXO80ZEAJmrykPyzo1IfNbAoaqw48YRpv8shwd1NoI0jcQ==", 183 | "cpu": [ 184 | "arm64" 185 | ], 186 | "dev": true, 187 | "optional": true, 188 | "os": [ 189 | "freebsd" 190 | ], 191 | "engines": { 192 | "node": ">=12" 193 | } 194 | }, 195 | "node_modules/esbuild/node_modules/@esbuild/freebsd-x64": { 196 | "version": "0.17.19", 197 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.17.19.tgz", 198 | "integrity": "sha512-4lu+n8Wk0XlajEhbEffdy2xy53dpR06SlzvhGByyg36qJw6Kpfk7cp45DR/62aPH9mtJRmIyrXAS5UWBrJT6TQ==", 199 | "cpu": [ 200 | "x64" 201 | ], 202 | "dev": true, 203 | "optional": true, 204 | "os": [ 205 | "freebsd" 206 | ], 207 | "engines": { 208 | "node": ">=12" 209 | } 210 | }, 211 | "node_modules/esbuild/node_modules/@esbuild/linux-arm": { 212 | "version": "0.17.19", 213 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.17.19.tgz", 214 | "integrity": "sha512-cdmT3KxjlOQ/gZ2cjfrQOtmhG4HJs6hhvm3mWSRDPtZ/lP5oe8FWceS10JaSJC13GBd4eH/haHnqf7hhGNLerA==", 215 | "cpu": [ 216 | "arm" 217 | ], 218 | "dev": true, 219 | "optional": true, 220 | "os": [ 221 | "linux" 222 | ], 223 | "engines": { 224 | "node": ">=12" 225 | } 226 | }, 227 | "node_modules/esbuild/node_modules/@esbuild/linux-arm64": { 228 | "version": "0.17.19", 229 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.17.19.tgz", 230 | "integrity": "sha512-ct1Tg3WGwd3P+oZYqic+YZF4snNl2bsnMKRkb3ozHmnM0dGWuxcPTTntAF6bOP0Sp4x0PjSF+4uHQ1xvxfRKqg==", 231 | "cpu": [ 232 | "arm64" 233 | ], 234 | "dev": true, 235 | "optional": true, 236 | "os": [ 237 | "linux" 238 | ], 239 | "engines": { 240 | "node": ">=12" 241 | } 242 | }, 243 | "node_modules/esbuild/node_modules/@esbuild/linux-ia32": { 244 | "version": "0.17.19", 245 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.17.19.tgz", 246 | "integrity": "sha512-w4IRhSy1VbsNxHRQpeGCHEmibqdTUx61Vc38APcsRbuVgK0OPEnQ0YD39Brymn96mOx48Y2laBQGqgZ0j9w6SQ==", 247 | "cpu": [ 248 | "ia32" 249 | ], 250 | "dev": true, 251 | "optional": true, 252 | "os": [ 253 | "linux" 254 | ], 255 | "engines": { 256 | "node": ">=12" 257 | } 258 | }, 259 | "node_modules/esbuild/node_modules/@esbuild/linux-loong64": { 260 | "version": "0.17.19", 261 | "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.17.19.tgz", 262 | "integrity": "sha512-2iAngUbBPMq439a+z//gE+9WBldoMp1s5GWsUSgqHLzLJ9WoZLZhpwWuym0u0u/4XmZ3gpHmzV84PonE+9IIdQ==", 263 | "cpu": [ 264 | "loong64" 265 | ], 266 | "dev": true, 267 | "optional": true, 268 | "os": [ 269 | "linux" 270 | ], 271 | "engines": { 272 | "node": ">=12" 273 | } 274 | }, 275 | "node_modules/esbuild/node_modules/@esbuild/linux-mips64el": { 276 | "version": "0.17.19", 277 | "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.17.19.tgz", 278 | "integrity": "sha512-LKJltc4LVdMKHsrFe4MGNPp0hqDFA1Wpt3jE1gEyM3nKUvOiO//9PheZZHfYRfYl6AwdTH4aTcXSqBerX0ml4A==", 279 | "cpu": [ 280 | "mips64el" 281 | ], 282 | "dev": true, 283 | "optional": true, 284 | "os": [ 285 | "linux" 286 | ], 287 | "engines": { 288 | "node": ">=12" 289 | } 290 | }, 291 | "node_modules/esbuild/node_modules/@esbuild/linux-ppc64": { 292 | "version": "0.17.19", 293 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.17.19.tgz", 294 | "integrity": "sha512-/c/DGybs95WXNS8y3Ti/ytqETiW7EU44MEKuCAcpPto3YjQbyK3IQVKfF6nbghD7EcLUGl0NbiL5Rt5DMhn5tg==", 295 | "cpu": [ 296 | "ppc64" 297 | ], 298 | "dev": true, 299 | "optional": true, 300 | "os": [ 301 | "linux" 302 | ], 303 | "engines": { 304 | "node": ">=12" 305 | } 306 | }, 307 | "node_modules/esbuild/node_modules/@esbuild/linux-riscv64": { 308 | "version": "0.17.19", 309 | "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.17.19.tgz", 310 | "integrity": "sha512-FC3nUAWhvFoutlhAkgHf8f5HwFWUL6bYdvLc/TTuxKlvLi3+pPzdZiFKSWz/PF30TB1K19SuCxDTI5KcqASJqA==", 311 | "cpu": [ 312 | "riscv64" 313 | ], 314 | "dev": true, 315 | "optional": true, 316 | "os": [ 317 | "linux" 318 | ], 319 | "engines": { 320 | "node": ">=12" 321 | } 322 | }, 323 | "node_modules/esbuild/node_modules/@esbuild/linux-s390x": { 324 | "version": "0.17.19", 325 | "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.17.19.tgz", 326 | "integrity": "sha512-IbFsFbxMWLuKEbH+7sTkKzL6NJmG2vRyy6K7JJo55w+8xDk7RElYn6xvXtDW8HCfoKBFK69f3pgBJSUSQPr+4Q==", 327 | "cpu": [ 328 | "s390x" 329 | ], 330 | "dev": true, 331 | "optional": true, 332 | "os": [ 333 | "linux" 334 | ], 335 | "engines": { 336 | "node": ">=12" 337 | } 338 | }, 339 | "node_modules/esbuild/node_modules/@esbuild/linux-x64": { 340 | "version": "0.17.19", 341 | "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.17.19.tgz", 342 | "integrity": "sha512-68ngA9lg2H6zkZcyp22tsVt38mlhWde8l3eJLWkyLrp4HwMUr3c1s/M2t7+kHIhvMjglIBrFpncX1SzMckomGw==", 343 | "cpu": [ 344 | "x64" 345 | ], 346 | "dev": true, 347 | "optional": true, 348 | "os": [ 349 | "linux" 350 | ], 351 | "engines": { 352 | "node": ">=12" 353 | } 354 | }, 355 | "node_modules/esbuild/node_modules/@esbuild/netbsd-x64": { 356 | "version": "0.17.19", 357 | "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.17.19.tgz", 358 | "integrity": "sha512-CwFq42rXCR8TYIjIfpXCbRX0rp1jo6cPIUPSaWwzbVI4aOfX96OXY8M6KNmtPcg7QjYeDmN+DD0Wp3LaBOLf4Q==", 359 | "cpu": [ 360 | "x64" 361 | ], 362 | "dev": true, 363 | "optional": true, 364 | "os": [ 365 | "netbsd" 366 | ], 367 | "engines": { 368 | "node": ">=12" 369 | } 370 | }, 371 | "node_modules/esbuild/node_modules/@esbuild/openbsd-x64": { 372 | "version": "0.17.19", 373 | "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.17.19.tgz", 374 | "integrity": "sha512-cnq5brJYrSZ2CF6c35eCmviIN3k3RczmHz8eYaVlNasVqsNY+JKohZU5MKmaOI+KkllCdzOKKdPs762VCPC20g==", 375 | "cpu": [ 376 | "x64" 377 | ], 378 | "dev": true, 379 | "optional": true, 380 | "os": [ 381 | "openbsd" 382 | ], 383 | "engines": { 384 | "node": ">=12" 385 | } 386 | }, 387 | "node_modules/esbuild/node_modules/@esbuild/sunos-x64": { 388 | "version": "0.17.19", 389 | "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.17.19.tgz", 390 | "integrity": "sha512-vCRT7yP3zX+bKWFeP/zdS6SqdWB8OIpaRq/mbXQxTGHnIxspRtigpkUcDMlSCOejlHowLqII7K2JKevwyRP2rg==", 391 | "cpu": [ 392 | "x64" 393 | ], 394 | "dev": true, 395 | "optional": true, 396 | "os": [ 397 | "sunos" 398 | ], 399 | "engines": { 400 | "node": ">=12" 401 | } 402 | }, 403 | "node_modules/esbuild/node_modules/@esbuild/win32-arm64": { 404 | "version": "0.17.19", 405 | "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.17.19.tgz", 406 | "integrity": "sha512-yYx+8jwowUstVdorcMdNlzklLYhPxjniHWFKgRqH7IFlUEa0Umu3KuYplf1HUZZ422e3NU9F4LGb+4O0Kdcaag==", 407 | "cpu": [ 408 | "arm64" 409 | ], 410 | "dev": true, 411 | "optional": true, 412 | "os": [ 413 | "win32" 414 | ], 415 | "engines": { 416 | "node": ">=12" 417 | } 418 | }, 419 | "node_modules/esbuild/node_modules/@esbuild/win32-ia32": { 420 | "version": "0.17.19", 421 | "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.17.19.tgz", 422 | "integrity": "sha512-eggDKanJszUtCdlVs0RB+h35wNlb5v4TWEkq4vZcmVt5u/HiDZrTXe2bWFQUez3RgNHwx/x4sk5++4NSSicKkw==", 423 | "cpu": [ 424 | "ia32" 425 | ], 426 | "dev": true, 427 | "optional": true, 428 | "os": [ 429 | "win32" 430 | ], 431 | "engines": { 432 | "node": ">=12" 433 | } 434 | }, 435 | "node_modules/esbuild/node_modules/@esbuild/win32-x64": { 436 | "version": "0.17.19", 437 | "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.19.tgz", 438 | "integrity": "sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA==", 439 | "cpu": [ 440 | "x64" 441 | ], 442 | "dev": true, 443 | "optional": true, 444 | "os": [ 445 | "win32" 446 | ], 447 | "engines": { 448 | "node": ">=12" 449 | } 450 | }, 451 | "node_modules/fs.realpath": { 452 | "version": "1.0.0", 453 | "license": "ISC" 454 | }, 455 | "node_modules/fsevents": { 456 | "version": "2.3.2", 457 | "dev": true, 458 | "license": "MIT", 459 | "optional": true, 460 | "os": [ 461 | "darwin" 462 | ], 463 | "engines": { 464 | "node": "^8.16.0 || ^10.6.0 || >=11.0.0" 465 | } 466 | }, 467 | "node_modules/glob": { 468 | "version": "8.1.0", 469 | "license": "ISC", 470 | "dependencies": { 471 | "fs.realpath": "^1.0.0", 472 | "inflight": "^1.0.4", 473 | "inherits": "2", 474 | "minimatch": "^5.0.1", 475 | "once": "^1.3.0" 476 | }, 477 | "engines": { 478 | "node": ">=12" 479 | }, 480 | "funding": { 481 | "url": "https://github.com/sponsors/isaacs" 482 | } 483 | }, 484 | "node_modules/inflight": { 485 | "version": "1.0.6", 486 | "license": "ISC", 487 | "dependencies": { 488 | "once": "^1.3.0", 489 | "wrappy": "1" 490 | } 491 | }, 492 | "node_modules/inherits": { 493 | "version": "2.0.4", 494 | "license": "ISC" 495 | }, 496 | "node_modules/ini": { 497 | "version": "1.3.8", 498 | "license": "ISC" 499 | }, 500 | "node_modules/js-beautify": { 501 | "version": "1.14.8", 502 | "license": "MIT", 503 | "dependencies": { 504 | "config-chain": "^1.1.13", 505 | "editorconfig": "^0.15.3", 506 | "glob": "^8.1.0", 507 | "nopt": "^6.0.0" 508 | }, 509 | "bin": { 510 | "css-beautify": "js/bin/css-beautify.js", 511 | "html-beautify": "js/bin/html-beautify.js", 512 | "js-beautify": "js/bin/js-beautify.js" 513 | }, 514 | "engines": { 515 | "node": ">=12" 516 | } 517 | }, 518 | "node_modules/lru-cache": { 519 | "version": "4.1.5", 520 | "license": "ISC", 521 | "dependencies": { 522 | "pseudomap": "^1.0.2", 523 | "yallist": "^2.1.2" 524 | } 525 | }, 526 | "node_modules/minimatch": { 527 | "version": "5.1.6", 528 | "license": "ISC", 529 | "dependencies": { 530 | "brace-expansion": "^2.0.1" 531 | }, 532 | "engines": { 533 | "node": ">=10" 534 | } 535 | }, 536 | "node_modules/monaco-editor": { 537 | "version": "0.39.0", 538 | "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.39.0.tgz", 539 | "integrity": "sha512-zhbZ2Nx93tLR8aJmL2zI1mhJpsl87HMebNBM6R8z4pLfs8pj604pIVIVwyF1TivcfNtIPpMXL+nb3DsBmE/x6Q==" 540 | }, 541 | "node_modules/nanoid": { 542 | "version": "3.3.6", 543 | "dev": true, 544 | "funding": [ 545 | { 546 | "type": "github", 547 | "url": "https://github.com/sponsors/ai" 548 | } 549 | ], 550 | "license": "MIT", 551 | "bin": { 552 | "nanoid": "bin/nanoid.cjs" 553 | }, 554 | "engines": { 555 | "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" 556 | } 557 | }, 558 | "node_modules/nopt": { 559 | "version": "6.0.0", 560 | "license": "ISC", 561 | "dependencies": { 562 | "abbrev": "^1.0.0" 563 | }, 564 | "bin": { 565 | "nopt": "bin/nopt.js" 566 | }, 567 | "engines": { 568 | "node": "^12.13.0 || ^14.15.0 || >=16.0.0" 569 | } 570 | }, 571 | "node_modules/once": { 572 | "version": "1.4.0", 573 | "license": "ISC", 574 | "dependencies": { 575 | "wrappy": "1" 576 | } 577 | }, 578 | "node_modules/picocolors": { 579 | "version": "1.0.0", 580 | "dev": true, 581 | "license": "ISC" 582 | }, 583 | "node_modules/postcss": { 584 | "version": "8.4.24", 585 | "dev": true, 586 | "funding": [ 587 | { 588 | "type": "opencollective", 589 | "url": "https://opencollective.com/postcss/" 590 | }, 591 | { 592 | "type": "tidelift", 593 | "url": "https://tidelift.com/funding/github/npm/postcss" 594 | }, 595 | { 596 | "type": "github", 597 | "url": "https://github.com/sponsors/ai" 598 | } 599 | ], 600 | "license": "MIT", 601 | "dependencies": { 602 | "nanoid": "^3.3.6", 603 | "picocolors": "^1.0.0", 604 | "source-map-js": "^1.0.2" 605 | }, 606 | "engines": { 607 | "node": "^10 || ^12 || >=14" 608 | } 609 | }, 610 | "node_modules/proto-list": { 611 | "version": "1.2.4", 612 | "license": "ISC" 613 | }, 614 | "node_modules/pseudomap": { 615 | "version": "1.0.2", 616 | "license": "ISC" 617 | }, 618 | "node_modules/rollup": { 619 | "version": "3.25.3", 620 | "dev": true, 621 | "license": "MIT", 622 | "bin": { 623 | "rollup": "dist/bin/rollup" 624 | }, 625 | "engines": { 626 | "node": ">=14.18.0", 627 | "npm": ">=8.0.0" 628 | }, 629 | "optionalDependencies": { 630 | "fsevents": "~2.3.2" 631 | } 632 | }, 633 | "node_modules/semver": { 634 | "version": "5.7.1", 635 | "license": "ISC", 636 | "bin": { 637 | "semver": "bin/semver" 638 | } 639 | }, 640 | "node_modules/sigmund": { 641 | "version": "1.0.1", 642 | "license": "ISC" 643 | }, 644 | "node_modules/source-map-js": { 645 | "version": "1.0.2", 646 | "dev": true, 647 | "license": "BSD-3-Clause", 648 | "engines": { 649 | "node": ">=0.10.0" 650 | } 651 | }, 652 | "node_modules/vite": { 653 | "version": "4.3.9", 654 | "dev": true, 655 | "license": "MIT", 656 | "dependencies": { 657 | "esbuild": "^0.17.5", 658 | "postcss": "^8.4.23", 659 | "rollup": "^3.21.0" 660 | }, 661 | "bin": { 662 | "vite": "bin/vite.js" 663 | }, 664 | "engines": { 665 | "node": "^14.18.0 || >=16.0.0" 666 | }, 667 | "optionalDependencies": { 668 | "fsevents": "~2.3.2" 669 | }, 670 | "peerDependencies": { 671 | "@types/node": ">= 14", 672 | "less": "*", 673 | "sass": "*", 674 | "stylus": "*", 675 | "sugarss": "*", 676 | "terser": "^5.4.0" 677 | }, 678 | "peerDependenciesMeta": { 679 | "@types/node": { 680 | "optional": true 681 | }, 682 | "less": { 683 | "optional": true 684 | }, 685 | "sass": { 686 | "optional": true 687 | }, 688 | "stylus": { 689 | "optional": true 690 | }, 691 | "sugarss": { 692 | "optional": true 693 | }, 694 | "terser": { 695 | "optional": true 696 | } 697 | } 698 | }, 699 | "node_modules/wrappy": { 700 | "version": "1.0.2", 701 | "license": "ISC" 702 | }, 703 | "node_modules/yallist": { 704 | "version": "2.1.2", 705 | "license": "ISC" 706 | } 707 | }, 708 | "dependencies": { 709 | "@esbuild/darwin-arm64": { 710 | "version": "0.17.19", 711 | "dev": true, 712 | "optional": true 713 | }, 714 | "@types/js-beautify": { 715 | "version": "1.13.3", 716 | "resolved": "https://registry.npmjs.org/@types/js-beautify/-/js-beautify-1.13.3.tgz", 717 | "integrity": "sha512-ucIPw5gmNyvRKi6mpeojlqp+T+6ZBJeU+kqMDnIEDlijEU4QhLTon90sZ3cz9HZr+QTwXILjNsMZImzA7+zuJA==", 718 | "dev": true 719 | }, 720 | "abbrev": { 721 | "version": "1.1.1" 722 | }, 723 | "balanced-match": { 724 | "version": "1.0.2" 725 | }, 726 | "brace-expansion": { 727 | "version": "2.0.1", 728 | "requires": { 729 | "balanced-match": "^1.0.0" 730 | } 731 | }, 732 | "commander": { 733 | "version": "2.20.3" 734 | }, 735 | "config-chain": { 736 | "version": "1.1.13", 737 | "requires": { 738 | "ini": "^1.3.4", 739 | "proto-list": "~1.2.1" 740 | } 741 | }, 742 | "editorconfig": { 743 | "version": "0.15.3", 744 | "requires": { 745 | "commander": "^2.19.0", 746 | "lru-cache": "^4.1.5", 747 | "semver": "^5.6.0", 748 | "sigmund": "^1.0.1" 749 | } 750 | }, 751 | "esbuild": { 752 | "version": "0.17.19", 753 | "dev": true, 754 | "requires": { 755 | "@esbuild/android-arm": "0.17.19", 756 | "@esbuild/android-arm64": "0.17.19", 757 | "@esbuild/android-x64": "0.17.19", 758 | "@esbuild/darwin-arm64": "0.17.19", 759 | "@esbuild/darwin-x64": "0.17.19", 760 | "@esbuild/freebsd-arm64": "0.17.19", 761 | "@esbuild/freebsd-x64": "0.17.19", 762 | "@esbuild/linux-arm": "0.17.19", 763 | "@esbuild/linux-arm64": "0.17.19", 764 | "@esbuild/linux-ia32": "0.17.19", 765 | "@esbuild/linux-loong64": "0.17.19", 766 | "@esbuild/linux-mips64el": "0.17.19", 767 | "@esbuild/linux-ppc64": "0.17.19", 768 | "@esbuild/linux-riscv64": "0.17.19", 769 | "@esbuild/linux-s390x": "0.17.19", 770 | "@esbuild/linux-x64": "0.17.19", 771 | "@esbuild/netbsd-x64": "0.17.19", 772 | "@esbuild/openbsd-x64": "0.17.19", 773 | "@esbuild/sunos-x64": "0.17.19", 774 | "@esbuild/win32-arm64": "0.17.19", 775 | "@esbuild/win32-ia32": "0.17.19", 776 | "@esbuild/win32-x64": "0.17.19" 777 | }, 778 | "dependencies": { 779 | "@esbuild/android-arm": { 780 | "version": "0.17.19", 781 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.19.tgz", 782 | "integrity": "sha512-rIKddzqhmav7MSmoFCmDIb6e2W57geRsM94gV2l38fzhXMwq7hZoClug9USI2pFRGL06f4IOPHHpFNOkWieR8A==", 783 | "dev": true, 784 | "optional": true 785 | }, 786 | "@esbuild/android-arm64": { 787 | "version": "0.17.19", 788 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.17.19.tgz", 789 | "integrity": "sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA==", 790 | "dev": true, 791 | "optional": true 792 | }, 793 | "@esbuild/android-x64": { 794 | "version": "0.17.19", 795 | "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.17.19.tgz", 796 | "integrity": "sha512-uUTTc4xGNDT7YSArp/zbtmbhO0uEEK9/ETW29Wk1thYUJBz3IVnvgEiEwEa9IeLyvnpKrWK64Utw2bgUmDveww==", 797 | "dev": true, 798 | "optional": true 799 | }, 800 | "@esbuild/darwin-x64": { 801 | "version": "0.17.19", 802 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.19.tgz", 803 | "integrity": "sha512-IJM4JJsLhRYr9xdtLytPLSH9k/oxR3boaUIYiHkAawtwNOXKE8KoU8tMvryogdcT8AU+Bflmh81Xn6Q0vTZbQw==", 804 | "dev": true, 805 | "optional": true 806 | }, 807 | "@esbuild/freebsd-arm64": { 808 | "version": "0.17.19", 809 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.19.tgz", 810 | "integrity": "sha512-pBwbc7DufluUeGdjSU5Si+P3SoMF5DQ/F/UmTSb8HXO80ZEAJmrykPyzo1IfNbAoaqw48YRpv8shwd1NoI0jcQ==", 811 | "dev": true, 812 | "optional": true 813 | }, 814 | "@esbuild/freebsd-x64": { 815 | "version": "0.17.19", 816 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.17.19.tgz", 817 | "integrity": "sha512-4lu+n8Wk0XlajEhbEffdy2xy53dpR06SlzvhGByyg36qJw6Kpfk7cp45DR/62aPH9mtJRmIyrXAS5UWBrJT6TQ==", 818 | "dev": true, 819 | "optional": true 820 | }, 821 | "@esbuild/linux-arm": { 822 | "version": "0.17.19", 823 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.17.19.tgz", 824 | "integrity": "sha512-cdmT3KxjlOQ/gZ2cjfrQOtmhG4HJs6hhvm3mWSRDPtZ/lP5oe8FWceS10JaSJC13GBd4eH/haHnqf7hhGNLerA==", 825 | "dev": true, 826 | "optional": true 827 | }, 828 | "@esbuild/linux-arm64": { 829 | "version": "0.17.19", 830 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.17.19.tgz", 831 | "integrity": "sha512-ct1Tg3WGwd3P+oZYqic+YZF4snNl2bsnMKRkb3ozHmnM0dGWuxcPTTntAF6bOP0Sp4x0PjSF+4uHQ1xvxfRKqg==", 832 | "dev": true, 833 | "optional": true 834 | }, 835 | "@esbuild/linux-ia32": { 836 | "version": "0.17.19", 837 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.17.19.tgz", 838 | "integrity": "sha512-w4IRhSy1VbsNxHRQpeGCHEmibqdTUx61Vc38APcsRbuVgK0OPEnQ0YD39Brymn96mOx48Y2laBQGqgZ0j9w6SQ==", 839 | "dev": true, 840 | "optional": true 841 | }, 842 | "@esbuild/linux-loong64": { 843 | "version": "0.17.19", 844 | "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.17.19.tgz", 845 | "integrity": "sha512-2iAngUbBPMq439a+z//gE+9WBldoMp1s5GWsUSgqHLzLJ9WoZLZhpwWuym0u0u/4XmZ3gpHmzV84PonE+9IIdQ==", 846 | "dev": true, 847 | "optional": true 848 | }, 849 | "@esbuild/linux-mips64el": { 850 | "version": "0.17.19", 851 | "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.17.19.tgz", 852 | "integrity": "sha512-LKJltc4LVdMKHsrFe4MGNPp0hqDFA1Wpt3jE1gEyM3nKUvOiO//9PheZZHfYRfYl6AwdTH4aTcXSqBerX0ml4A==", 853 | "dev": true, 854 | "optional": true 855 | }, 856 | "@esbuild/linux-ppc64": { 857 | "version": "0.17.19", 858 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.17.19.tgz", 859 | "integrity": "sha512-/c/DGybs95WXNS8y3Ti/ytqETiW7EU44MEKuCAcpPto3YjQbyK3IQVKfF6nbghD7EcLUGl0NbiL5Rt5DMhn5tg==", 860 | "dev": true, 861 | "optional": true 862 | }, 863 | "@esbuild/linux-riscv64": { 864 | "version": "0.17.19", 865 | "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.17.19.tgz", 866 | "integrity": "sha512-FC3nUAWhvFoutlhAkgHf8f5HwFWUL6bYdvLc/TTuxKlvLi3+pPzdZiFKSWz/PF30TB1K19SuCxDTI5KcqASJqA==", 867 | "dev": true, 868 | "optional": true 869 | }, 870 | "@esbuild/linux-s390x": { 871 | "version": "0.17.19", 872 | "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.17.19.tgz", 873 | "integrity": "sha512-IbFsFbxMWLuKEbH+7sTkKzL6NJmG2vRyy6K7JJo55w+8xDk7RElYn6xvXtDW8HCfoKBFK69f3pgBJSUSQPr+4Q==", 874 | "dev": true, 875 | "optional": true 876 | }, 877 | "@esbuild/linux-x64": { 878 | "version": "0.17.19", 879 | "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.17.19.tgz", 880 | "integrity": "sha512-68ngA9lg2H6zkZcyp22tsVt38mlhWde8l3eJLWkyLrp4HwMUr3c1s/M2t7+kHIhvMjglIBrFpncX1SzMckomGw==", 881 | "dev": true, 882 | "optional": true 883 | }, 884 | "@esbuild/netbsd-x64": { 885 | "version": "0.17.19", 886 | "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.17.19.tgz", 887 | "integrity": "sha512-CwFq42rXCR8TYIjIfpXCbRX0rp1jo6cPIUPSaWwzbVI4aOfX96OXY8M6KNmtPcg7QjYeDmN+DD0Wp3LaBOLf4Q==", 888 | "dev": true, 889 | "optional": true 890 | }, 891 | "@esbuild/openbsd-x64": { 892 | "version": "0.17.19", 893 | "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.17.19.tgz", 894 | "integrity": "sha512-cnq5brJYrSZ2CF6c35eCmviIN3k3RczmHz8eYaVlNasVqsNY+JKohZU5MKmaOI+KkllCdzOKKdPs762VCPC20g==", 895 | "dev": true, 896 | "optional": true 897 | }, 898 | "@esbuild/sunos-x64": { 899 | "version": "0.17.19", 900 | "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.17.19.tgz", 901 | "integrity": "sha512-vCRT7yP3zX+bKWFeP/zdS6SqdWB8OIpaRq/mbXQxTGHnIxspRtigpkUcDMlSCOejlHowLqII7K2JKevwyRP2rg==", 902 | "dev": true, 903 | "optional": true 904 | }, 905 | "@esbuild/win32-arm64": { 906 | "version": "0.17.19", 907 | "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.17.19.tgz", 908 | "integrity": "sha512-yYx+8jwowUstVdorcMdNlzklLYhPxjniHWFKgRqH7IFlUEa0Umu3KuYplf1HUZZ422e3NU9F4LGb+4O0Kdcaag==", 909 | "dev": true, 910 | "optional": true 911 | }, 912 | "@esbuild/win32-ia32": { 913 | "version": "0.17.19", 914 | "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.17.19.tgz", 915 | "integrity": "sha512-eggDKanJszUtCdlVs0RB+h35wNlb5v4TWEkq4vZcmVt5u/HiDZrTXe2bWFQUez3RgNHwx/x4sk5++4NSSicKkw==", 916 | "dev": true, 917 | "optional": true 918 | }, 919 | "@esbuild/win32-x64": { 920 | "version": "0.17.19", 921 | "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.19.tgz", 922 | "integrity": "sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA==", 923 | "dev": true, 924 | "optional": true 925 | } 926 | } 927 | }, 928 | "fs.realpath": { 929 | "version": "1.0.0" 930 | }, 931 | "fsevents": { 932 | "version": "2.3.2", 933 | "dev": true, 934 | "optional": true 935 | }, 936 | "glob": { 937 | "version": "8.1.0", 938 | "requires": { 939 | "fs.realpath": "^1.0.0", 940 | "inflight": "^1.0.4", 941 | "inherits": "2", 942 | "minimatch": "^5.0.1", 943 | "once": "^1.3.0" 944 | } 945 | }, 946 | "inflight": { 947 | "version": "1.0.6", 948 | "requires": { 949 | "once": "^1.3.0", 950 | "wrappy": "1" 951 | } 952 | }, 953 | "inherits": { 954 | "version": "2.0.4" 955 | }, 956 | "ini": { 957 | "version": "1.3.8" 958 | }, 959 | "js-beautify": { 960 | "version": "1.14.8", 961 | "requires": { 962 | "config-chain": "^1.1.13", 963 | "editorconfig": "^0.15.3", 964 | "glob": "^8.1.0", 965 | "nopt": "^6.0.0" 966 | } 967 | }, 968 | "lru-cache": { 969 | "version": "4.1.5", 970 | "requires": { 971 | "pseudomap": "^1.0.2", 972 | "yallist": "^2.1.2" 973 | } 974 | }, 975 | "minimatch": { 976 | "version": "5.1.6", 977 | "requires": { 978 | "brace-expansion": "^2.0.1" 979 | } 980 | }, 981 | "monaco-editor": { 982 | "version": "0.39.0", 983 | "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.39.0.tgz", 984 | "integrity": "sha512-zhbZ2Nx93tLR8aJmL2zI1mhJpsl87HMebNBM6R8z4pLfs8pj604pIVIVwyF1TivcfNtIPpMXL+nb3DsBmE/x6Q==" 985 | }, 986 | "nanoid": { 987 | "version": "3.3.6", 988 | "dev": true 989 | }, 990 | "nopt": { 991 | "version": "6.0.0", 992 | "requires": { 993 | "abbrev": "^1.0.0" 994 | } 995 | }, 996 | "once": { 997 | "version": "1.4.0", 998 | "requires": { 999 | "wrappy": "1" 1000 | } 1001 | }, 1002 | "picocolors": { 1003 | "version": "1.0.0", 1004 | "dev": true 1005 | }, 1006 | "postcss": { 1007 | "version": "8.4.24", 1008 | "dev": true, 1009 | "requires": { 1010 | "nanoid": "^3.3.6", 1011 | "picocolors": "^1.0.0", 1012 | "source-map-js": "^1.0.2" 1013 | } 1014 | }, 1015 | "proto-list": { 1016 | "version": "1.2.4" 1017 | }, 1018 | "pseudomap": { 1019 | "version": "1.0.2" 1020 | }, 1021 | "rollup": { 1022 | "version": "3.25.3", 1023 | "dev": true, 1024 | "requires": { 1025 | "fsevents": "~2.3.2" 1026 | } 1027 | }, 1028 | "semver": { 1029 | "version": "5.7.1" 1030 | }, 1031 | "sigmund": { 1032 | "version": "1.0.1" 1033 | }, 1034 | "source-map-js": { 1035 | "version": "1.0.2", 1036 | "dev": true 1037 | }, 1038 | "vite": { 1039 | "version": "4.3.9", 1040 | "dev": true, 1041 | "requires": { 1042 | "esbuild": "^0.17.5", 1043 | "fsevents": "~2.3.2", 1044 | "postcss": "^8.4.23", 1045 | "rollup": "^3.21.0" 1046 | } 1047 | }, 1048 | "wrappy": { 1049 | "version": "1.0.2" 1050 | }, 1051 | "yallist": { 1052 | "version": "2.1.2" 1053 | } 1054 | } 1055 | } 1056 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "deobfuscator", 3 | "scripts": { 4 | "start": "vite serve", 5 | "build": "vite build --base=./", 6 | "preview": "vite preview" 7 | }, 8 | "dependencies": { 9 | "js-beautify": "^1.14.8", 10 | "monaco-editor": "^0.39.0" 11 | }, 12 | "devDependencies": { 13 | "@types/js-beautify": "^1.13.3", 14 | "vite": "^4.3.9" 15 | }, 16 | "license": "MIT" 17 | } 18 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import * as monaco from "monaco-editor"; 2 | import {KeyCode, KeyMod } from "monaco-editor"; 3 | import tsWorker from "monaco-editor/esm/vs/language/typescript/ts.worker?worker"; 4 | import "./tools.js"; 5 | 6 | /* Editor Initialization */ 7 | 8 | self.MonacoEnvironment = { 9 | getWorker: function () { 10 | return new tsWorker(); 11 | }, 12 | }; 13 | 14 | const editor = monaco.editor.create(document.getElementById("container"), { 15 | value: 16 | sessionStorage["decoder-text"] || 17 | [`function x() {`, `\tconsole['log']("Hello world!");`, `}`].join("\n"), 18 | language: "javascript", 19 | wordWrap: "on", 20 | automaticLayout: true, 21 | }); 22 | 23 | window.editor = editor; 24 | 25 | editor.getModel().onDidChangeContent(() => { 26 | sessionStorage["decoder-text"] = utils.text; 27 | }); 28 | 29 | editor.addAction({ 30 | id: "evaluate-selected", 31 | label: "Evaluate Selected", 32 | keybindings: [KeyCode.F10], 33 | run: function () { 34 | window.evalStr(); 35 | }, 36 | }); 37 | 38 | editor.addAction({ 39 | id: "evaluate-auto", 40 | label: "Auto Eval", 41 | keybindings: [KeyMod.CtrlCmd | KeyCode.F10], 42 | run: function () { 43 | window.evalAuto(); 44 | }, 45 | }); 46 | 47 | editor.addAction({ 48 | id: "object-access", 49 | label: "Object Access", 50 | keybindings: [KeyMod.CtrlCmd | KeyCode.F9], 51 | run: function () { 52 | window.simplifyAccess(); 53 | }, 54 | }); 55 | 56 | editor.addAction({ 57 | id: "split-var", 58 | label: "Split Var", 59 | keybindings: [KeyMod.CtrlCmd | KeyCode.F8], 60 | run: function () { 61 | window.splitVar(); 62 | }, 63 | }); 64 | editor.addAction({ 65 | id: "eval-push", 66 | label: "Eval Push", 67 | keybindings: [KeyCode.F9], 68 | run: function () { 69 | window.evalPush(); 70 | }, 71 | }); 72 | 73 | editor.addAction({ 74 | id: "eval-pop", 75 | label: "Eval Pop", 76 | keybindings: [KeyCode.F8], 77 | run: function () { 78 | window.evalPop(); 79 | }, 80 | }); 81 | 82 | const utils = { 83 | transformSelection(f) { 84 | var selectionList = editor.getSelections(); 85 | var model = editor.getModel(); 86 | var ops = selectionList.map((selection, i) => { 87 | var text = model.getValueInRange(selection); 88 | var range = new monaco.Range( 89 | selection.startLineNumber, 90 | selection.startColumn, 91 | selection.endLineNumber, 92 | selection.endColumn 93 | ); 94 | var identifier = { major: 1, minor: i + 1 }; 95 | var op = { 96 | range, 97 | identifier, 98 | text: f(text), 99 | forceMoveMarkers: true, 100 | }; 101 | return op; 102 | }); 103 | editor.executeEdits("my-source", ops); 104 | }, 105 | get selectedText() { 106 | return editor.getModel().getValueInRange(editor.getSelection()); 107 | }, 108 | set selectedText(text) { 109 | var selection = editor.getSelection(); 110 | var range = new monaco.Range( 111 | selection.startLineNumber, 112 | selection.startColumn, 113 | selection.endLineNumber, 114 | selection.endColumn 115 | ); 116 | var id = { major: 1, minor: 1 }; 117 | var op = { 118 | identifier: id, 119 | range: range, 120 | text: text, 121 | forceMoveMarkers: true, 122 | }; 123 | editor.executeEdits("my-source", [op]); 124 | }, 125 | get startSelection() { 126 | var selection = editor.getSelection(); 127 | return editor.getModel().getOffsetAt(selection.getStartPosition()); 128 | }, 129 | get endSelection() { 130 | var selection = editor.getSelection(); 131 | return editor.getModel().getOffsetAt(selection.getEndPosition()); 132 | }, 133 | get text() { 134 | return editor.getValue(); 135 | }, 136 | set text(v) { 137 | // Select all text 138 | const fullRange = editor.getModel().getFullModelRange(); 139 | 140 | // Apply the text over the range 141 | editor.executeEdits(null, [{ 142 | text: v, 143 | range: fullRange 144 | }]); 145 | }, 146 | selectAllIfNone() { 147 | if (this.startSelection == this.endSelection) { 148 | editor.setSelection(editor.getModel().getFullModelRange()); 149 | } 150 | }, 151 | rangeFromOffset(start, end) { 152 | var model = editor.getModel(); 153 | var start = model.getPositionAt(start); 154 | var end = model.getPositionAt(end); 155 | return new monaco.Selection( 156 | start.lineNumber, 157 | start.column, 158 | end.lineNumber, 159 | end.column 160 | ); 161 | }, 162 | /** 163 | * 164 | * @param {Selection[]} rangeList 165 | */ 166 | selectRangeList(rangeList) { 167 | editor.setSelections(rangeList); 168 | } 169 | }; 170 | 171 | window.utils = utils; 172 | -------------------------------------------------------------------------------- /src/tools.js: -------------------------------------------------------------------------------- 1 | import beautify from "js-beautify"; 2 | import { Range } from "monaco-editor"; 3 | 4 | window.stackEval = []; 5 | 6 | 7 | function colName(n) { 8 | var ordA = "a".charCodeAt(0); 9 | var ordZ = "z".charCodeAt(0); 10 | var len = ordZ - ordA + 1; 11 | 12 | var s = ""; 13 | while (n >= 0) { 14 | s = String.fromCharCode((n % len) + ordA) + s; 15 | n = Math.floor(n / len) - 1; 16 | } 17 | return s; 18 | } 19 | 20 | function isBracketEven(str) { 21 | var count = 0; 22 | for (var i = 0; i < str.length; i++) { 23 | if (str[i] === "(") count++; 24 | else if (str[i] === ")") count--; 25 | else if (str[i] === "[") count++; 26 | else if (str[i] === "]") count--; 27 | else if (str[i] === "{") count++; 28 | else if (str[i] === "}") count--; 29 | } 30 | return count === 0; 31 | } 32 | 33 | window.expandBracket = function () { 34 | editor.getAction("editor.action.selectToBracket").run(); 35 | }; 36 | 37 | 38 | 39 | window.selectAllVarDeclaration = function () { 40 | var text = utils.text; 41 | var r = /^\s*(var|let|const) [\w\W]+?(;\n|function|=>)/gm; 42 | var ranges = []; 43 | 44 | var m; 45 | while ((m = r.exec(text)) !== null) { 46 | var start = m.index; 47 | var end = start + m[0].length; 48 | if (isBracketEven(m[0]) && m[0].endsWith(";\n")) { 49 | ranges.push(utils.rangeFromOffset(start, end)); 50 | } 51 | } 52 | utils.selectRangeList(ranges); 53 | }; 54 | 55 | window.subtituteAllVarAssigment = function () { 56 | var fulltext = utils.text; 57 | utils.transformSelection(function (text) { 58 | // must be single var 59 | var r = /^(\s*var |\s*let |\s*const )(\w+)(;\s*)/gm; 60 | var m = r.exec(text); 61 | if (m) { 62 | var varname = m[2]; 63 | var r2 = new RegExp(`(,|^)\\s*${varname}( = .+?)(,|;)`, "gm"); 64 | var m2 = r2.exec(fulltext); 65 | if (m2) { 66 | return m[1] + m[2] + m2[2] + m[3]; 67 | } 68 | } 69 | else { 70 | return text; 71 | } 72 | }); 73 | } 74 | 75 | window.syncVar = function () { 76 | var thevar = utils.selectedText; 77 | var text = utils.text; 78 | if (thevar.indexOf(" ") !== -1) { 79 | alert('Not a valid var!'); 80 | return; 81 | } 82 | var text2 = text; 83 | while (true) { 84 | text2 = syncVarNested(thevar, text); 85 | if (text !== text2) 86 | text = text2; 87 | else 88 | break; 89 | } 90 | utils.text = text2; 91 | }; 92 | 93 | 94 | window.syncVarNested = function (thevar, text) { 95 | var r = new RegExp(`^ *(var|let|const)? +(\\w+) += +${thevar}(;|,\\n)`, "gm"); 96 | var alternates = []; 97 | var t = text.replace(r, function (_, p1, p2, sep) { 98 | alternates.push(p2); 99 | return ``; 100 | }); 101 | alternates = alternates.filter((v, i, a) => a.indexOf(v) === i) 102 | console.log(alternates); 103 | alternates.forEach(w => { 104 | t = t.replace(new RegExp(`\\b${w}\\b`, "g"), thevar); 105 | t = window.syncVarNested(w, t); 106 | }); 107 | return t; 108 | }; 109 | 110 | function stringify(obj) { 111 | if (typeof obj == "function") return obj.toString(); 112 | else if (obj === undefined) throw new Error("returned undefined"); 113 | else return JSON.stringify(obj); 114 | } 115 | 116 | window.evalStr = function () { 117 | utils.transformSelection(function (text) { 118 | try { 119 | if (window.stackEval.length > 0) { 120 | return stringify(eval(` 121 | (function(){ 122 | ${stackEval.slice(-1)[0]} 123 | return ${text}; 124 | })(); 125 | `)); 126 | } else { 127 | return stringify(eval("(" + text + ")")); 128 | } 129 | } catch (error) { 130 | console.error(error); 131 | return text; 132 | } 133 | }); 134 | }; 135 | 136 | window.evalBareStr = function () { 137 | utils.transformSelection(function (text) { 138 | try { 139 | if (window.stackEval.length > 0) { 140 | return String(eval(` 141 | (function(){ 142 | ${stackEval.slice(-1)[0]} 143 | return ${text}; 144 | })(); 145 | `)); 146 | } else { 147 | return String(eval("(" + text + ")")); 148 | } 149 | } catch (error) { 150 | console.error(error); 151 | return text; 152 | } 153 | }); 154 | }; 155 | 156 | window.evalPush = function () { 157 | if (utils.startSelection != utils.endSelection) { 158 | window.stackEval.push( 159 | (window.stackEval.slice(-1)[0] || "") + utils.selectedText + "\n" 160 | ); 161 | console.log("stackEval pushed, current evaluation:"); 162 | console.log(window.stackEval.slice(-1)[0]); 163 | } else { 164 | console.log("Nothing selected"); 165 | } 166 | }; 167 | 168 | window.evalPop = function () { 169 | window.stackEval.pop(); 170 | console.log("stackEval popped, current evaluation:"); 171 | console.log(stackEval.slice(-1)[0]); 172 | }; 173 | 174 | window.evalAuto = function () { 175 | utils.selectAllIfNone(); 176 | var r = /(?:^|;)\s*(?:var|const|let)\s+(\w+)/gm, 177 | w, 178 | v = [], 179 | text = utils.selectedText; 180 | while ((w = r.exec(window.stackEval.slice(-1)[0])) !== null) v.push(w[1]); 181 | console.log("Captured variables:"); 182 | console.log(v); 183 | v.forEach((t) => { 184 | text = text.replace( 185 | new RegExp("\b" + t + "(\\.\\w+)?(\\[.+?\\]|\\(.+?\\)|\\b)", "g"), 186 | function (token) { 187 | try { 188 | var result = eval(` 189 | (function(){ 190 | ${stackEval.slice(-1)[0]} 191 | return ${token}; 192 | })(); 193 | `); 194 | if (typeof result == "string" || typeof result == "number" || typeof result == "boolean" || result === null) { 195 | return JSON.stringify(result); 196 | } else { 197 | return token; 198 | } 199 | } catch (error) { 200 | return token; 201 | } 202 | } 203 | ); 204 | }); 205 | utils.selectedText = text; 206 | }; 207 | 208 | window.evalAutoRegex = function (regex, outf) { 209 | utils.selectAllIfNone(); 210 | var replaced = utils.selectedText.replace(r, function (o) { 211 | try { 212 | var result = outf.apply(null, arguments); 213 | if (typeof result == "string" || typeof result == "number") return result; 214 | else return o; 215 | } catch (e) { 216 | return o; 217 | } 218 | }); 219 | utils.selectedText = replaced; 220 | }; 221 | 222 | function splitNested(str) { 223 | let result = [], item = '', depth = 0; 224 | 225 | function push() { if (item) result.push(item); item = ''; } 226 | 227 | for (let i = 0, c; c = str[i], i < str.length; i++) { 228 | if (!depth && c === ',') push(); 229 | else { 230 | item += c; 231 | if (c === '[') depth++; 232 | if (c === ']') depth--; 233 | if (c === '{') depth++; 234 | if (c === '}') depth--; 235 | if (c === '(') depth++; 236 | if (c === ')') depth--; 237 | } 238 | } 239 | 240 | push(); 241 | return result; 242 | } 243 | 244 | window.splitVar = function () { 245 | utils.transformSelection(function (text) { 246 | return text.replace(/^(\s*)(var|let|const)\s+(.+?);/gsm, function (all, space, met, exp) { 247 | // assume nice formatted 248 | var vars = splitNested(exp); 249 | return vars.map(x => `${space}${met} ${x.trim()};\n`).join(""); 250 | }); 251 | }); 252 | }; 253 | 254 | /* Formatting Tools */ 255 | 256 | window.beautify = function () { 257 | utils.text = beautify(utils.text, { indent_size: 2 }); 258 | }; 259 | 260 | window.simplifyString = function () { 261 | utils.selectAllIfNone(); 262 | var replaced = utils.selectedText 263 | .replace(/"(\\"|[^"])*?"/g, function (m) { 264 | return JSON.stringify(eval(m)); 265 | }) 266 | .replace(/'(\\"|[^'])*?'/g, function (m) { 267 | return JSON.stringify(eval(m)); 268 | }); 269 | utils.selectedText = replaced; 270 | }; 271 | 272 | window.simplifyNumber = function () { 273 | utils.selectAllIfNone(); 274 | var replaced = utils.selectedText.replace( 275 | /\b0x[a-fA-F0-9]+\b/g, 276 | function (m) { 277 | return JSON.stringify(eval(m)); 278 | } 279 | ); 280 | utils.selectedText = replaced; 281 | }; 282 | 283 | window.simplifyNumberExp = function () { 284 | utils.selectAllIfNone(); 285 | var replaced = utils.selectedText.replace( 286 | /(\b|-)(-?[\d\.]+ ?[-*+/%^] ?)+(-?[\d\.]+)\b/g, 287 | function (m) { 288 | try { 289 | var r = eval(m); 290 | return typeof r == "number" ? JSON.stringify(r) : m; 291 | } catch (error) { 292 | return m; 293 | } 294 | } 295 | ); 296 | utils.selectedText = replaced; 297 | }; 298 | 299 | window.simplifyStringExp = function () { 300 | utils.selectAllIfNone(); 301 | var replaced = utils.selectedText.replace(/"[\w" \+]+"/g, function (m) { 302 | try { 303 | var r = eval(m); 304 | return typeof r == "string" ? JSON.stringify(r) : m; 305 | } catch (error) { 306 | return m; 307 | } 308 | }); 309 | utils.selectedText = replaced; 310 | }; 311 | 312 | window.simplifyAccess = function () { 313 | utils.selectAllIfNone(); 314 | utils.selectedText = utils.selectedText 315 | .replace(/\["([\w][\w\d_]*?)"\]/g, ".$1") 316 | .replace(/\['([\w][\w\d_]*?)'\]/g, ".$1"); 317 | }; 318 | 319 | window.simplifyVar = function () { 320 | utils.selectAllIfNone(); 321 | // This function dissasemble var chain. Can't figure save way to do it yet. 322 | console.log("Coming Soon!"); 323 | }; 324 | 325 | window.simplifyHex = function () { 326 | utils.selectAllIfNone(); 327 | var letters = {}; 328 | var letc = 0; 329 | var s = utils.selectedText; 330 | var replaced = s.replace(/\b_0x[a-fA-F0-9]+\b/g, function (m) { 331 | if (letters[m]) return letters[m]; 332 | else { 333 | var x; 334 | while ((x = colName(letc++))) 335 | if (!s.match(new RegExp("\\b" + x + "\\b", "i"))) 336 | if ( 337 | !["do", "if", "in", "for", "let", "new", "var", "try"].includes(x) 338 | ) 339 | break; 340 | 341 | letters[m] = x; 342 | return x; 343 | } 344 | }); 345 | utils.selectedText = replaced; 346 | }; 347 | 348 | window.gotoRepo = function () { 349 | window.open("https://github.com/willnode/deobfuscator", "_blank"); 350 | }; 351 | --------------------------------------------------------------------------------