{"id":13457769,"url":"https://github.com/javascript-obfuscator/javascript-obfuscator","last_synced_at":"2026-02-04T18:03:09.118Z","repository":{"id":37405529,"uuid":"58360147","full_name":"javascript-obfuscator/javascript-obfuscator","owner":"javascript-obfuscator","description":"A powerful obfuscator for JavaScript and Node.js","archived":false,"fork":false,"pushed_at":"2026-01-27T21:04:40.000Z","size":34015,"stargazers_count":15826,"open_issues_count":94,"forks_count":1714,"subscribers_count":189,"default_branch":"master","last_synced_at":"2026-01-27T22:36:24.681Z","etag":null,"topics":["browser","control-flow","cryptography","encoding","flattening","flow","javascript","javascript-obfuscator","js-obfuscator","literal","mangle","nodejs","obfuscate","obfuscation","obfuscator","protection","security","string","typescript","uglify"],"latest_commit_sha":null,"homepage":"https://obfuscator.io","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-2-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/javascript-obfuscator.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE.BSD","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":"sanex3339","open_collective":"javascript-obfuscator","custom":["https://github.com/javascript-obfuscator/javascript-obfuscator#you-can-support-this-project-by-donating"]}},"created_at":"2016-05-09T08:16:53.000Z","updated_at":"2026-01-27T21:04:46.000Z","dependencies_parsed_at":"2023-12-15T10:09:16.937Z","dependency_job_id":"7fc1450f-e5f1-4356-990b-de4f5788b782","html_url":"https://github.com/javascript-obfuscator/javascript-obfuscator","commit_stats":{"total_commits":1956,"total_committers":46,"mean_commits":42.52173913043478,"dds":0.25,"last_synced_commit":"1000402f10f61bd367cd971d55f0f832d940d60e"},"previous_names":["sanex3339/javascript-obfuscator"],"tags_count":223,"template":false,"template_full_name":null,"purl":"pkg:github/javascript-obfuscator/javascript-obfuscator","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/javascript-obfuscator%2Fjavascript-obfuscator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/javascript-obfuscator%2Fjavascript-obfuscator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/javascript-obfuscator%2Fjavascript-obfuscator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/javascript-obfuscator%2Fjavascript-obfuscator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/javascript-obfuscator","download_url":"https://codeload.github.com/javascript-obfuscator/javascript-obfuscator/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/javascript-obfuscator%2Fjavascript-obfuscator/sbom","scorecard":{"id":508181,"data":{"date":"2025-08-11","repo":{"name":"github.com/javascript-obfuscator/javascript-obfuscator","commit":"828a190cf80a86227ef77be38e99aad9838aed70"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3,"checks":[{"name":"Code-Review","score":2,"reason":"Found 6/27 approved changesets -- score normalized to 2","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/ci.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE.BSD:0","Info: FSF or OSI recognized license: BSD 2-Clause \"Simplified\" License: LICENSE.BSD:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:33: update your workflow using https://app.stepsecurity.io/secureworkflow/javascript-obfuscator/javascript-obfuscator/ci.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/ci.yml:34: update your workflow using https://app.stepsecurity.io/secureworkflow/javascript-obfuscator/javascript-obfuscator/ci.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:38: update your workflow using https://app.stepsecurity.io/secureworkflow/javascript-obfuscator/javascript-obfuscator/ci.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:41: update your workflow using https://app.stepsecurity.io/secureworkflow/javascript-obfuscator/javascript-obfuscator/ci.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/ci.yml:49: update your workflow using https://app.stepsecurity.io/secureworkflow/javascript-obfuscator/javascript-obfuscator/ci.yml/master?enable=pin","Info:   0 out of   3 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   2 third-party GitHubAction dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 14 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":0,"reason":"18 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-968p-4wvh-cqc8","Warn: Project is vulnerable to: GHSA-67hx-6x53-jw92","Warn: Project is vulnerable to: GHSA-v6h2-p8h4-qcjw","Warn: Project is vulnerable to: GHSA-grv7-fg5c-xmjg","Warn: Project is vulnerable to: GHSA-3xgq-45jj-v275","Warn: Project is vulnerable to: GHSA-gxpj-cx7g-858c","Warn: Project is vulnerable to: GHSA-4q6p-r6v2-jvc5","Warn: Project is vulnerable to: GHSA-43f8-2h32-f4cj","Warn: Project is vulnerable to: GHSA-9c47-m6qq-7p4h","Warn: Project is vulnerable to: GHSA-952p-6rrq-rcjv","Warn: Project is vulnerable to: GHSA-f8q6-p94x-37v3","Warn: Project is vulnerable to: GHSA-9wv6-86v2-598j","Warn: Project is vulnerable to: GHSA-c2qf-rxjj-qqgw","Warn: Project is vulnerable to: GHSA-76p7-773f-r4q5","Warn: Project is vulnerable to: GHSA-4wf5-vphf-c2xc","Warn: Project is vulnerable to: GHSA-hc6q-2mpp-qw7j","Warn: Project is vulnerable to: GHSA-4vvj-4cpr-p986","Warn: Project is vulnerable to: GHSA-j8xg-fqg3-53r7"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-19T23:46:40.055Z","repository_id":37405529,"created_at":"2025-08-19T23:46:40.055Z","updated_at":"2025-08-19T23:46:40.055Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29092733,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-04T03:31:03.593Z","status":"ssl_error","status_checked_at":"2026-02-04T03:29:50.742Z","response_time":62,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["browser","control-flow","cryptography","encoding","flattening","flow","javascript","javascript-obfuscator","js-obfuscator","literal","mangle","nodejs","obfuscate","obfuscation","obfuscator","protection","security","string","typescript","uglify"],"created_at":"2024-07-31T09:00:36.271Z","updated_at":"2026-02-04T18:03:09.107Z","avatar_url":"https://github.com/javascript-obfuscator.png","language":"TypeScript","readme":"\u003c!--\n  Title: JavaScript Obfuscator\n  Description: A powerful obfuscator for JavaScript and Node.js.\n  Author: Timofei Kachalov\n  --\u003e\n\n#### You can support this project by donating:\n* (Github) https://github.com/sponsors/sanex3339\n\nHuge thanks to all supporters!\n\n# JavaScript obfuscator\n\n![logo](https://raw.githubusercontent.com/javascript-obfuscator/javascript-obfuscator/master/images/logo.png)\n\n---\n\n### :rocket: Obfuscator.io with VM Obfuscation is out!\n\n**Obfuscator.io** features **VM-based bytecode obfuscation** — the most advanced code protection available. Your JavaScript functions are transformed into custom bytecode running on an embedded virtual machine, making reverse engineering extremely difficult.\n\n[Try it at obfuscator.io](https://obfuscator.io)\n\nThis package provides access to Obfuscator.io Pro API via CLI and Node.js API.\n\n---\n\nJavaScript Obfuscator is a powerful free obfuscator for JavaScript, containing a variety of features which provide protection for your source code.\n\n**Key features:**\n- VM bytecode obfuscation (via [Obfuscator.io](https://obfuscator.io/))\n- variables renaming\n- strings extraction and encryption\n- dead code injection\n- control flow flattening\n- various code transformations\n- and [more](#javascript-obfuscator-options)...\n\nThe example of obfuscated code: [github.com](https://github.com/javascript-obfuscator/javascript-obfuscator/blob/master/examples/javascript-obfuscator.js)\n\n#### Online version:\n[obfuscator.io](https://obfuscator.io)\n\n#### Plugins:\n* Webpack plugin: [webpack-obfuscator](https://github.com/javascript-obfuscator/webpack-obfuscator)\n* Webpack loader: [obfuscator-loader](https://github.com/javascript-obfuscator/obfuscator-loader)\n* Gulp: [gulp-javascript-obfuscator](https://github.com/javascript-obfuscator/gulp-javascript-obfuscator)\n* Grunt: [grunt-contrib-obfuscator](https://github.com/javascript-obfuscator/grunt-contrib-obfuscator)\n* Rollup: [rollup-plugin-javascript-obfuscator](https://github.com/javascript-obfuscator/rollup-plugin-javascript-obfuscator)\n* Weex: [weex-devtool](https://www.npmjs.com/package/weex-devtool)\n* Malta: [malta-js-obfuscator](https://github.com/fedeghe/malta-js-obfuscator)\n* Netlify plugin: [netlify-plugin-js-obfuscator](https://www.npmjs.com/package/netlify-plugin-js-obfuscator)\n* Snowpack plugin: [snowpack-javascript-obfuscator](https://www.npmjs.com/package/snowpack-javascript-obfuscator)\n\n[![npm version](https://badge.fury.io/js/javascript-obfuscator.svg)](https://badge.fury.io/js/javascript-obfuscator)\n[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fjavascript-obfuscator%2Fjavascript-obfuscator.svg?type=shield)](https://app.fossa.io/projects/git%2Bgithub.com%2Fjavascript-obfuscator%2Fjavascript-obfuscator?ref=badge_shield)\n![Build Status](https://github.com/javascript-obfuscator/javascript-obfuscator/workflows/JavaScript%20Obfuscator%20CI/badge.svg)\n[![Coverage Status](https://coveralls.io/repos/github/javascript-obfuscator/javascript-obfuscator/badge.svg)](https://coveralls.io/github/javascript-obfuscator/javascript-obfuscator)\n[![Backers on Open Collective](https://opencollective.com/javascript-obfuscator/backers/badge.svg)](#backers) \n[![Sponsors on Open Collective](https://opencollective.com/javascript-obfuscator/sponsors/badge.svg)](#sponsors)\n[![xscode](https://img.shields.io/badge/Available%20on-xs%3Acode-blue?style=?style=plastic\u0026logo=appveyor\u0026logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAMAAACdt4HsAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAAZQTFRF////////VXz1bAAAAAJ0Uk5T/wDltzBKAAAAlUlEQVR42uzXSwqAMAwE0Mn9L+3Ggtgkk35QwcnSJo9S+yGwM9DCooCbgn4YrJ4CIPUcQF7/XSBbx2TEz4sAZ2q1RAECBAiYBlCtvwN+KiYAlG7UDGj59MViT9hOwEqAhYCtAsUZvL6I6W8c2wcbd+LIWSCHSTeSAAECngN4xxIDSK9f4B9t377Wd7H5Nt7/Xz8eAgwAvesLRjYYPuUAAAAASUVORK5CYII=)](https://xscode.com/sanex3339/javascript-obfuscator)\n\n#### *NOTE! the README on the master branch might not match that of the latest stable release!*\n\n#### If you have a question, check this section first: [FAQ](#frequently-asked-questions)\n\n## :warning: Important\n##### Only obfuscate the code that belongs to you. \n\nIt is not recommended to obfuscate vendor scripts and polyfills, since the obfuscated code is 15-80% slower (depends on options) and the files are significantly larger.\n\n## Installation\n\n#### Using Yarn or NPM\n\nInstall the package with Yarn or NPM and add it to your `dependencies` or `devDependencies`:\n\n```sh\n$ yarn add --dev javascript-obfuscator\n```\nor\n```sh\n$ npm install --save-dev javascript-obfuscator\n```\n\n#### In a Browser\n\nFrom CDN:\n\n```html\n\u003cscript src=\"https://cdn.jsdelivr.net/npm/javascript-obfuscator/dist/index.browser.js\"\u003e\u003c/script\u003e\n```\n\nFrom `node_modules`:\n\n```html\n\u003cscript src=\"./node_modules/javascript-obfuscator/dist/index.browser.js\"\u003e\u003c/script\u003e\n```\n\n## Usage\n\n```javascript\nvar JavaScriptObfuscator = require('javascript-obfuscator');\n\nvar obfuscationResult = JavaScriptObfuscator.obfuscate(\n    `\n        (function(){\n            var variable1 = '5' - 3;\n            var variable2 = '5' + 3;\n            var variable3 = '5' + - '2';\n            var variable4 = ['10','10','10','10','10'].map(parseInt);\n            var variable5 = 'foo ' + 1 + 1;\n            console.log(variable1);\n            console.log(variable2);\n            console.log(variable3);\n            console.log(variable4);\n            console.log(variable5);\n        })();\n    `,\n    {\n        compact: false,\n        controlFlowFlattening: true,\n        controlFlowFlatteningThreshold: 1,\n        numbersToExpressions: true,\n        simplify: true,\n        stringArrayShuffle: true,\n        splitStrings: true,\n        stringArrayThreshold: 1\n    }\n);\n\nconsole.log(obfuscationResult.getObfuscatedCode());\n/*\nvar _0x9947 = [\n    'map',\n    'log',\n    'foo\\x20',\n    'bvmqO',\n    '133039ViRMWR',\n    'xPfLC',\n    'ytpdx',\n    '1243717qSZCyh',\n    '2|7|4|6|9|',\n    '1ErtbCr',\n    '1608314VKvthn',\n    '1ZRaFKN',\n    'XBoAA',\n    '423266kQOYHV',\n    '3|0|5|8|1',\n    '235064xPNdKe',\n    '13RUDZfG',\n    '157gNPQGm',\n    '1639212MvnHZL',\n    'rDjOa',\n    'iBHph',\n    '9926iRHoRl',\n    'split'\n];\nfunction _0x33e4(_0x1809b5, _0x37ef6e) {\n    return _0x33e4 = function (_0x338a69, _0x39ad79) {\n        _0x338a69 = _0x338a69 - (0x1939 + -0xf * 0x1f3 + 0x1 * 0x469);\n        var _0x2b223a = _0x9947[_0x338a69];\n        return _0x2b223a;\n    }, _0x33e4(_0x1809b5, _0x37ef6e);\n}\n(function (_0x431d87, _0x156c7f) {\n    var _0x10cf6e = _0x33e4;\n    while (!![]) {\n        try {\n            var _0x330ad1 = -parseInt(_0x10cf6e(0x6c)) * -parseInt(_0x10cf6e(0x6d)) + -parseInt(_0x10cf6e(0x74)) * -parseInt(_0x10cf6e(0x78)) + parseInt(_0x10cf6e(0x6a)) + -parseInt(_0x10cf6e(0x70)) + parseInt(_0x10cf6e(0x6e)) * -parseInt(_0x10cf6e(0x75)) + parseInt(_0x10cf6e(0x72)) + -parseInt(_0x10cf6e(0x67)) * parseInt(_0x10cf6e(0x73));\n            if (_0x330ad1 === _0x156c7f)\n                break;\n            else\n                _0x431d87['push'](_0x431d87['shift']());\n        } catch (_0x9f878) {\n            _0x431d87['push'](_0x431d87['shift']());\n        }\n    }\n}(_0x9947, -0xb6270 + 0x4dfd2 * 0x2 + 0x75460 * 0x2), function () {\n    var _0x1f346d = _0x33e4, _0x860db8 = {\n            'ytpdx': _0x1f346d(0x6b) + _0x1f346d(0x71),\n            'bvmqO': function (_0x560787, _0x519b9e) {\n                return _0x560787 - _0x519b9e;\n            },\n            'rDjOa': function (_0x4501fe, _0x2b07a3) {\n                return _0x4501fe + _0x2b07a3;\n            },\n            'xPfLC': function (_0x5f3c9b, _0x434936) {\n                return _0x5f3c9b + _0x434936;\n            },\n            'XBoAA': function (_0x535b8a, _0x42eef4) {\n                return _0x535b8a + _0x42eef4;\n            },\n            'iBHph': _0x1f346d(0x65)\n        }, _0x346c55 = _0x860db8[_0x1f346d(0x69)][_0x1f346d(0x79)]('|'), _0x3bf817 = 0x4bb * 0x1 + 0x801 + -0xcbc;\n    while (!![]) {\n        switch (_0x346c55[_0x3bf817++]) {\n        case '0':\n            console[_0x1f346d(0x7b)](_0x4c96d8);\n            continue;\n        case '1':\n            console[_0x1f346d(0x7b)](_0x101028);\n            continue;\n        case '2':\n            var _0x65977d = _0x860db8[_0x1f346d(0x66)]('5', -0x586 + -0x2195 + -0x6 * -0x685);\n            continue;\n        case '3':\n            console[_0x1f346d(0x7b)](_0x65977d);\n            continue;\n        case '4':\n            var _0x56d39b = _0x860db8[_0x1f346d(0x76)]('5', -'2');\n            continue;\n        case '5':\n            console[_0x1f346d(0x7b)](_0x56d39b);\n            continue;\n        case '6':\n            var _0x544285 = [\n                '10',\n                '10',\n                '10',\n                '10',\n                '10'\n            ][_0x1f346d(0x7a)](parseInt);\n            continue;\n        case '7':\n            var _0x4c96d8 = _0x860db8[_0x1f346d(0x68)]('5', 0x622 * -0x6 + 0x4a * 0x3 + 0x1 * 0x23f1);\n            continue;\n        case '8':\n            console[_0x1f346d(0x7b)](_0x544285);\n            continue;\n        case '9':\n            var _0x101028 = _0x860db8[_0x1f346d(0x6f)](_0x860db8[_0x1f346d(0x6f)](_0x860db8[_0x1f346d(0x77)], 0x6fb * 0x5 + 0x1ebf * 0x1 + -0x41a5), 0x209 * 0xa + 0x1314 + -0x276d);\n            continue;\n        }\n        break;\n    }\n}());\n*/\n```\n\n### `obfuscate(sourceCode, options)`\n\nReturns `ObfuscationResult` object which contains two public methods:\n\n* `getObfuscatedCode()` - returns `string` with obfuscated code;\n* `getSourceMap()` - if [`sourceMap`](#sourcemap) option is enabled - returns `string` with source map or an empty string if [`sourceMapMode`](#sourcemapmode) option is set as `inline`;\n* `getIdentifierNamesCache()` - returns object with identifier names cache if `identifierNamesCache` option is enabled, `null` overwise.\n\nCalling `toString()` for `ObfuscationResult` object will return `string` with obfuscated code.\n\nMethod takes two parameters, `sourceCode` and `options` – the source code and the options respectively:\n\n* `sourceCode` (`string`, default: `null`) – any valid source code, passed as a string;\n* `options` (`Object`, default: `null`) – an object with options.\n\nFor available options, see [options](#options).\n\n### `obfuscateMultiple(sourceCodesObject, options)`\n\nAccepts `sourceCodesObject` that is a map which keys are identifiers of source codes and values are source codes:\n```\n{\n    foo: 'var foo = 1;',\n    bar: 'var bar = 2;'\n}\n```\n\nReturns a map object which keys are identifiers of source codes and values are `ObfuscationResult` objects.\n\n### `getOptionsByPreset(optionsPreset)`\n\nReturns an options object for the passed options preset name.\n\n---\n\n## :shield: Pro API Methods (VM Obfuscation)\n\nThe Pro API methods provide access to **VM-based bytecode obfuscation** through the [obfuscator.io](https://obfuscator.io) cloud service. VM obfuscation is the most advanced and secure form of code protection available, transforming your JavaScript functions into custom bytecode that runs on an embedded virtual machine.\n\n**Why VM Obfuscation?**\n- **Strongest protection**: Code is converted to bytecode that cannot be directly understood\n- **Anti-decompilation**: No standard JavaScript to reverse engineer\n- **Customizable VM**: Each obfuscation generates unique opcodes and VM structure\n- **Layered security**: Combine with other obfuscation options for defense in depth\n\n### Getting an API Token\n\nTo use Pro API methods, you need a valid API token from [obfuscator.io](https://obfuscator.io):\n\n1. Create an account at [obfuscator.io](https://obfuscator.io)\n2. Subscribe to a Pro, Team, or Business plan that includes API access\n3. Generate your API token at [obfuscator.io/dashboard](https://obfuscator.io/dashboard)\n\n### `obfuscatePro(sourceCode, options, proApiConfig, onProgress?)` :new:\n\n**Async method** that obfuscates code using the Pro API with VM-based bytecode obfuscation.\n\n```javascript\nconst JavaScriptObfuscator = require('javascript-obfuscator');\n\nconst result = await JavaScriptObfuscator.obfuscatePro(\n    `function hello() { console.log(\"Hello World\"); }`,\n    {\n        vmObfuscation: true,  // Required!\n        vmObfuscationThreshold: 1,\n        compact: true\n    },\n    {\n        apiToken: 'your_javascript_obfuscator_pro_api_token'\n    }\n);\n\nconsole.log(result.getObfuscatedCode());\n```\n\n**Parameters:**\n\n* `sourceCode` (`string`) – source code to obfuscate\n* `options` (`Object`) – obfuscation options. **Must include at least one Pro feature: `vmObfuscation: true` or `parseHtml: true`**\n* `apiConfig` (`Object`) – Pro API configuration:\n  * `apiToken` (`string`, required) – your API token from obfuscator.io\n  * `timeout` (`number`, optional) – request timeout in ms (default: `300000` - 5 minutes)\n  * `version` (`string`, optional) – Obfuscator.io version to use (e.g., `'5.0.3'`). Defaults to latest version if not specified.\n* `onProgress` (`function`, optional) – callback for progress updates during obfuscation\n\n**Returns:** `Promise\u003cObfuscationResult\u003e`\n\n**Throws:** `ApiError` if:\n- No Pro features (`vmObfuscation` or `parseHtml`) are enabled in options\n- API token is invalid or expired\n- API request fails\n\n### Pro API with Specific Version\n\nYou can specify which obfuscator version to use via the `version` option:\n\n```javascript\nconst result = await JavaScriptObfuscator.obfuscatePro(\n    sourceCode,\n    {\n        vmObfuscation: true,\n        vmObfuscationThreshold: 1\n    },\n    {\n        apiToken: 'your_javascript_obfuscator_pro_api_token',\n        version: '5.0.3'  // Use specific version\n    }\n);\n```\n\n### Pro API with Progress Updates\n\nThe API uses streaming mode to provide real-time progress updates during obfuscation:\n\n```javascript\nconst result = await JavaScriptObfuscator.obfuscatePro(\n    sourceCode,\n    {\n        vmObfuscation: true,\n        vmObfuscationThreshold: 1\n    },\n    {\n        apiToken: 'your_javascript_obfuscator_pro_api_token'\n    },\n    (message) =\u003e {\n        console.log('Progress:', message);\n        // Output: \"Validating request...\", \"Authenticating...\", \"Obfuscating...\", etc.\n    }\n);\n```\n\n### Checking for Pro Features\n\nUse `ProApiClient.hasProFeatures()` to check if options require the Pro API:\n\n```javascript\nconst { ProApiClient } = require('javascript-obfuscator');\n\nconst options = { vmObfuscation: true, compact: true };\n\nif (ProApiClient.hasProFeatures(options)) {\n    // Use obfuscatePro() - requires API token\n    const result = await JavaScriptObfuscator.obfuscatePro(sourceCode, options, { apiToken });\n} else {\n    // Use regular obfuscate() - no API token needed\n    const result = JavaScriptObfuscator.obfuscate(sourceCode, options);\n}\n```\n\nPro features include:\n- `vmObfuscation: true` – VM-based bytecode obfuscation\n- `parseHtml: true` – HTML parsing with inline JavaScript obfuscation\n\n### Error Handling\n\n```javascript\nconst { ApiError } = require('javascript-obfuscator');\n\ntry {\n    const result = await JavaScriptObfuscator.obfuscatePro(sourceCode, options, config);\n} catch (error) {\n    if (error instanceof ApiError) {\n        console.error(`API Error (${error.statusCode}): ${error.message}`);\n    } else {\n        throw error;\n    }\n}\n```\n\n### CLI Usage with Pro API\n\nYou can also use Pro API features directly from the CLI by providing your API token:\n\n```sh\njavascript-obfuscator input.js --pro-api-token YOUR_API_TOKEN --vm-obfuscation true -o output.js\n```\n\nWith a specific obfuscator version:\n\n```sh\njavascript-obfuscator input.js --pro-api-token YOUR_API_TOKEN --pro-api-version 5.0.3 --vm-obfuscation true -o output.js\n```\n\n**CLI Options:**\n- `--pro-api-token \u003cstring\u003e` – Your API token from [obfuscator.io](https://obfuscator.io)\n- `--pro-api-version \u003cstring\u003e` – Obfuscator.io version to use (optional, defaults to latest)\n\nThe CLI automatically detects when Pro features (`vmObfuscation` or `parseHtml`) are enabled and routes the request through the Pro API.\n\n### Large File Uploads\n\nFor files larger than ~4MB, the Pro API uses client-side uploads to Vercel Blob storage. To enable this feature, install the optional `@vercel/blob` package:\n\n```sh\nnpm install @vercel/blob\n```\n\nWithout this package, large file obfuscation will fail with an error message prompting you to install it.\n\n---\n\n## CLI usage\n\nSee [CLI options](#cli-options).\n\n#### Obfuscate single file\n\nUsage:\n```sh\njavascript-obfuscator input_file_name.js [options]\njavascript-obfuscator input_file_name.js --output output_file_name.js [options]\njavascript-obfuscator input_file_name.js --output output_folder_name [options]\njavascript-obfuscator input_folder_name --output output_folder_name [options]\n```\n\nObfuscation of single input file with `.js` extension.\n\nIf the destination path is not specified with the `--output` option, the obfuscated file will be saved into the input file directory, with `INPUT_FILE_NAME-obfuscated.js` name.\n\nSome examples:\n```sh\njavascript-obfuscator samples/sample.js --compact true --self-defending false\n// creates a new file samples/sample-obfuscated.js\n\njavascript-obfuscator samples/sample.js --output output/output.js --compact true --self-defending false\n// creates a new file output/output.js\n```\n\n#### Obfuscate directory recursively\n\nUsage:\n```sh\njavascript-obfuscator ./dist [options]\n// creates a new obfuscated files under `./dist` directory near the input files with `obfuscated` postfix\n\njavascript-obfuscator ./dist --output ./dist/obfuscated [options]\n// creates a folder structure with obfuscated files under `./dist/obfuscated` path\n```\n\nObfuscation of all `.js` files under input directory. If this directory contains already obfuscated files with `-obfuscated` postfix - these files will ignored.\n\nObfuscated files will saved into the input directory under `INPUT_FILE_NAME-obfuscated.js` name.\n\n## Conditional comments\nYou can disable and enable obfuscation for specific parts of the code by adding following comments: \n* disable: `// javascript-obfuscator:disable` or `/* javascript-obfuscator:disable */`;\n* enable: `// javascript-obfuscator:enable` or `/* javascript-obfuscator:enable */`.\n\nExample:\n```javascript\n// input\nvar foo = 1;\n// javascript-obfuscator:disable\nvar bar = 2;\n\n// output\nvar _0xabc123 = 0x1;\nvar bar = 2;\n```\nConditional comments affect only direct transformations of AST-tree nodes. All child transformations still will be applied to the AST-tree nodes. \n\nFor example:\n* Obfuscation of the variable's name at its declaration is called direct transformation;\n* Obfuscation of the variable's name beyond its declaration is called child transformation.\n\n## Kind of variables\n\nKind of variables of inserted nodes will auto-detected, based on most prevailing kind of variables of source code.\n\n## Conflicts of identifier names between different files\n\nDuring obfuscation of the different files, the same names can be generated for the global identifiers between these files.\nTo prevent this set the unique prefix for all global identifiers for each obfuscated file with [`identifiersPrefix`](#identifiersprefix) option. \n\nWhen using CLI this prefix will be added automatically.\n\n## JavaScript Obfuscator Options\n\nFollowing options are available for the JS Obfuscator:\n\n#### options:\n\n```javascript\n{\n    compact: true,\n    controlFlowFlattening: false,\n    controlFlowFlatteningThreshold: 0.75,\n    deadCodeInjection: false,\n    deadCodeInjectionThreshold: 0.4,\n    debugProtection: false,\n    debugProtectionInterval: 0,\n    disableConsoleOutput: false,\n    domainLock: [],\n    domainLockRedirectUrl: 'about:blank',\n    forceTransformStrings: [],\n    identifierNamesCache: null,\n    identifierNamesGenerator: 'hexadecimal',\n    identifiersDictionary: [],\n    identifiersPrefix: '',\n    ignoreImports: false,\n    inputFileName: '',\n    log: false,\n    numbersToExpressions: false,\n    optionsPreset: 'default',\n    renameGlobals: false,\n    renameProperties: false,\n    renamePropertiesMode: 'safe',\n    reservedNames: [],\n    reservedStrings: [],\n    seed: 0,\n    selfDefending: false,\n    simplify: true,\n    sourceMap: false,\n    sourceMapBaseUrl: '',\n    sourceMapFileName: '',\n    sourceMapMode: 'separate',\n    sourceMapSourcesMode: 'sources-content',\n    splitStrings: false,\n    splitStringsChunkLength: 10,\n    stringArray: true,\n    stringArrayCallsTransform: true,\n    stringArrayCallsTransformThreshold: 0.5,\n    stringArrayEncoding: [],\n    stringArrayIndexesType: [\n        'hexadecimal-number'\n    ],\n    stringArrayIndexShift: true,\n    stringArrayRotate: true,\n    stringArrayShuffle: true,\n    stringArrayWrappersCount: 1,\n    stringArrayWrappersChainedCalls: true,\n    stringArrayWrappersParametersMaxCount: 2,\n    stringArrayWrappersType: 'variable',\n    stringArrayThreshold: 0.75,\n    target: 'browser',\n    transformObjectKeys: false,\n    unicodeEscapeSequence: false\n}\n```\n\n#### CLI options:\n```sh\n    -v, --version\n    -h, --help\n\n    -o, --output\n\n    --compact \u003cboolean\u003e\n    --config \u003cstring\u003e\n    --control-flow-flattening \u003cboolean\u003e\n    --control-flow-flattening-threshold \u003cnumber\u003e\n    --dead-code-injection \u003cboolean\u003e\n    --dead-code-injection-threshold \u003cnumber\u003e\n    --debug-protection \u003cboolean\u003e\n    --debug-protection-interval \u003cnumber\u003e\n    --disable-console-output \u003cboolean\u003e\n    --domain-lock '\u003clist\u003e' (comma separated)\n    --domain-lock-redirect-url \u003cstring\u003e\n    --exclude '\u003clist\u003e' (comma separated)\n    --force-transform-strings '\u003clist\u003e' (comma separated)\n    --identifier-names-cache-path \u003cstring\u003e\n    --identifier-names-generator \u003cstring\u003e [dictionary, hexadecimal, mangled, mangled-shuffled]\n    --identifiers-dictionary '\u003clist\u003e' (comma separated)\n    --identifiers-prefix \u003cstring\u003e\n    --ignore-imports \u003cboolean\u003e\n    --log \u003cboolean\u003e\n    --numbers-to-expressions \u003cboolean\u003e\n    --options-preset \u003cstring\u003e [default, low-obfuscation, medium-obfuscation, high-obfuscation]\n    --rename-globals \u003cboolean\u003e\n    --rename-properties \u003cboolean\u003e\n    --rename-properties-mode \u003cstring\u003e [safe, unsafe]\n    --reserved-names '\u003clist\u003e' (comma separated)\n    --reserved-strings '\u003clist\u003e' (comma separated)\n    --seed \u003cstring|number\u003e\n    --self-defending \u003cboolean\u003e\n    --simplify \u003cboolean\u003e\n    --source-map \u003cboolean\u003e\n    --source-map-base-url \u003cstring\u003e\n    --source-map-file-name \u003cstring\u003e\n    --source-map-mode \u003cstring\u003e [inline, separate]\n    --source-map-sources-mode \u003cstring\u003e [sources, sources-content]\n    --split-strings \u003cboolean\u003e\n    --split-strings-chunk-length \u003cnumber\u003e\n    --string-array \u003cboolean\u003e\n    --string-array-calls-transform \u003cboolean\u003e\n    --string-array-calls-transform-threshold \u003cnumber\u003e\n    --string-array-encoding '\u003clist\u003e' (comma separated) [none, base64, rc4]\n    --string-array-indexes-type '\u003clist\u003e' (comma separated) [hexadecimal-number, hexadecimal-numeric-string]\n    --string-array-index-shift \u003cboolean\u003e\n    --string-array-rotate \u003cboolean\u003e\n    --string-array-shuffle \u003cboolean\u003e\n    --string-array-wrappers-count \u003cnumber\u003e\n    --string-array-wrappers-chained-calls \u003cboolean\u003e\n    --string-array-wrappers-parameters-max-count \u003cnumber\u003e\n    --string-array-wrappers-type \u003cstring\u003e [variable, function]\n    --string-array-threshold \u003cnumber\u003e\n    --target \u003cstring\u003e [browser, browser-no-eval, node]\n    --transform-object-keys \u003cboolean\u003e\n    --unicode-escape-sequence \u003cboolean\u003e\n    --pro-api-token \u003cstring\u003e\n    --pro-api-version \u003cstring\u003e\n    --vm-obfuscation \u003cboolean\u003e\n    --vm-obfuscation-threshold \u003cnumber\u003e\n    --vm-preprocess-identifiers \u003cboolean\u003e\n    --vm-dynamic-opcodes \u003cboolean\u003e\n    --vm-target-functions '\u003clist\u003e' (comma separated)\n    --vm-exclude-functions '\u003clist\u003e' (comma separated)\n    --vm-target-functions-mode \u003cstring\u003e [root, comment]\n    --vm-wrap-top-level-initializers \u003cboolean\u003e\n    --vm-opcode-shuffle \u003cboolean\u003e\n    --vm-bytecode-encoding \u003cboolean\u003e\n    --vm-bytecode-array-encoding \u003cboolean\u003e\n    --vm-bytecode-array-encoding-key \u003cstring\u003e\n    --vm-bytecode-array-encoding-key-getter \u003cstring\u003e\n    --vm-instruction-shuffle \u003cboolean\u003e\n    --vm-jumps-encoding \u003cboolean\u003e\n    --vm-decoy-opcodes \u003cboolean\u003e\n    --vm-dead-code-injection \u003cboolean\u003e\n    --vm-split-dispatcher \u003cboolean\u003e\n    --vm-macro-ops \u003cboolean\u003e\n    --vm-debug-protection \u003cboolean\u003e\n    --vm-runtime-opcode-derivation \u003cboolean\u003e\n    --vm-stateful-opcodes \u003cboolean\u003e\n    --vm-stack-encoding \u003cboolean\u003e\n    --vm-randomize-keys \u003cboolean\u003e\n    --vm-indirect-dispatch \u003cboolean\u003e\n    --vm-compact-dispatcher \u003cboolean\u003e\n    --vm-bytecode-format \u003cstring\u003e [binary, json]\n    --parse-html \u003cboolean\u003e\n    --strict-mode \u003cboolean\u003e\n```\n\n\u003c!-- ##options-start## --\u003e\n\n### `compact`\nType: `boolean` Default: `true`\n\nCompact code output on one line.\n\n### `config`\nType: `string` Default: ``\n\nName of JS/JSON config file which contains obfuscator options. These will be overridden by options passed directly to CLI\n\n### `controlFlowFlattening`\nType: `boolean` Default: `false`\n\n##### :warning: This option greatly affects the performance up to 1.5x slower runtime speed. Use [`controlFlowFlatteningThreshold`](#controlflowflatteningthreshold) to set percentage of nodes that will affected by control flow flattening. \n\nEnables code control flow flattening. Control flow flattening is a structure transformation of the source code that hinders program comprehension.\n\nExample:\n```ts\n// input\n(function(){\n    function foo () {\n        return function () {\n            var sum = 1 + 2;\n            console.log(1);\n            console.log(2);\n            console.log(3);\n            console.log(4);\n            console.log(5);\n            console.log(6);\n        }\n    }\n    \n    foo()();\n})();\n\n// output\n(function () {\n    function _0x3bfc5c() {\n        return function () {\n            var _0x3260a5 = {\n                'WtABe': '4|0|6|5|3|2|1',\n                'GokKo': function _0xf87260(_0x427a8e, _0x43354c) {\n                    return _0x427a8e + _0x43354c;\n                }\n            };\n            var _0x1ad4d6 = _0x3260a5['WtABe']['split']('|'), _0x1a7b12 = 0x0;\n            while (!![]) {\n                switch (_0x1ad4d6[_0x1a7b12++]) {\n                case '0':\n                    console['log'](0x1);\n                    continue;\n                case '1':\n                    console['log'](0x6);\n                    continue;\n                case '2':\n                    console['log'](0x5);\n                    continue;\n                case '3':\n                    console['log'](0x4);\n                    continue;\n                case '4':\n                    var _0x1f2f2f = _0x3260a5['GokKo'](0x1, 0x2);\n                    continue;\n                case '5':\n                    console['log'](0x3);\n                    continue;\n                case '6':\n                    console['log'](0x2);\n                    continue;\n                }\n                break;\n            }\n        };\n    }\n\n\t_0x3bfc5c()();\n}());\n```\n\n### `controlFlowFlatteningThreshold`\nType: `number` Default: `0.75` Min: `0` Max: `1`\n\nThe probability that the [`controlFlowFlattening`](#controlflowflattening) transformation will be applied to any given node.\n\nThis setting is especially useful for large code size because large amounts of control flow transformations can slow down your code and increase code size.\n\n`controlFlowFlatteningThreshold: 0` equals to `controlFlowFlattening: false`.\n\n### `deadCodeInjection`\nType: `boolean` Default: `false`\n\n##### :warning: Dramatically increases size of obfuscated code (up to 200%), use only if size of obfuscated code doesn't matter. Use [`deadCodeInjectionThreshold`](#deadcodeinjectionthreshold) to set percentage of nodes that will affected by dead code injection.\n##### :warning: This option forcibly enables `stringArray` option.\n\nWith this option, random blocks of dead code will be added to the obfuscated code. \n\nExample:\n```ts\n// input\n(function(){\n    if (true) {\n        var foo = function () {\n            console.log('abc');\n        };\n        var bar = function () {\n            console.log('def');\n        };\n        var baz = function () {\n            console.log('ghi');\n        };\n        var bark = function () {\n            console.log('jkl');\n        };\n        var hawk = function () {\n            console.log('mno');\n        };\n\n        foo();\n        bar();\n        baz();\n        bark();\n        hawk();\n    }\n})();\n\n// output\nvar _0x37b8 = [\n    'YBCtz',\n    'GlrkA',\n    'urPbb',\n    'abc',\n    'NMIhC',\n    'yZgAj',\n    'zrAId',\n    'EtyJA',\n    'log',\n    'mno',\n    'jkl',\n    'def',\n    'Quzya',\n    'IWbBa',\n    'ghi'\n];\nfunction _0x43a7(_0x12cf56, _0x587376) {\n    _0x43a7 = function (_0x2f87a8, _0x47eac2) {\n        _0x2f87a8 = _0x2f87a8 - (0x16a7 * 0x1 + 0x5 * 0x151 + -0x1c92);\n        var _0x341e03 = _0x37b8[_0x2f87a8];\n        return _0x341e03;\n    };\n    return _0x43a7(_0x12cf56, _0x587376);\n}\n(function () {\n    if (!![]) {\n        var _0xbbe28f = function () {\n            var _0x2fc85f = _0x43a7;\n            if (_0x2fc85f(0xaf) === _0x2fc85f(0xae)) {\n                _0x1dd94f[_0x2fc85f(0xb2)](_0x2fc85f(0xb5));\n            } else {\n                console[_0x2fc85f(0xb2)](_0x2fc85f(0xad));\n            }\n        };\n        var _0x5e46bc = function () {\n            var _0x15b472 = _0x43a7;\n            if (_0x15b472(0xb6) !== _0x15b472(0xaa)) {\n                console[_0x15b472(0xb2)](_0x15b472(0xb5));\n            } else {\n                _0x47eac2[_0x15b472(0xb2)](_0x15b472(0xad));\n            }\n        };\n        var _0x3669e8 = function () {\n            var _0x47a442 = _0x43a7;\n            if (_0x47a442(0xb7) !== _0x47a442(0xb0)) {\n                console[_0x47a442(0xb2)](_0x47a442(0xb8));\n            } else {\n                _0x24e0bf[_0x47a442(0xb2)](_0x47a442(0xb3));\n            }\n        };\n        var _0x28b05a = function () {\n            var _0x497902 = _0x43a7;\n            if (_0x497902(0xb1) === _0x497902(0xb1)) {\n                console[_0x497902(0xb2)](_0x497902(0xb4));\n            } else {\n                _0x59c9c6[_0x497902(0xb2)](_0x497902(0xb4));\n            }\n        };\n        var _0x402a54 = function () {\n            var _0x1906b7 = _0x43a7;\n            if (_0x1906b7(0xab) === _0x1906b7(0xac)) {\n                _0xb89cd0[_0x1906b7(0xb2)](_0x1906b7(0xb8));\n            } else {\n                console[_0x1906b7(0xb2)](_0x1906b7(0xb3));\n            }\n        };\n        _0xbbe28f();\n        _0x5e46bc();\n        _0x3669e8();\n        _0x28b05a();\n        _0x402a54();\n    }\n}());\n```\n\n### `deadCodeInjectionThreshold`\nType: `number` Default: `0.4` Min: `0` Max: `1`\n\nAllows to set percentage of nodes that will affected by `deadCodeInjection`.\n\n### `debugProtection`\nType: `boolean` Default: `false`\n\n##### :warning: Can freeze your browser if you open the Developer Tools.\n\nThis option makes it almost impossible to use the `debugger` function of the Developer Tools (both on WebKit-based and Mozilla Firefox).\n\n### `debugProtectionInterval`\nType: `number` Default: `0`\n\n##### :warning: Can freeze your browser! Use at own risk.\n\nIf set, an interval in milliseconds is used to force the debug mode on the Console tab, making it harder to use other features of the Developer Tools. Works if [`debugProtection`](#debugprotection) is enabled. Recommended value is between `2000` and `4000` milliseconds.\n\n### `disableConsoleOutput`\nType: `boolean` Default: `false`\n\n##### :warning: This option disables `console` calls globally for all scripts\n\nDisables the use of `console.log`, `console.info`, `console.error`, `console.warn`, `console.debug`, `console.exception` and `console.trace` by replacing them with empty functions. This makes the use of the debugger harder.\n\n### `domainLock`\nType: `string[]` Default: `[]`\n\n##### :warning: This option does not work with `target: 'node'`\n\nAllows to run the obfuscated source code only on specific domains and/or sub-domains. This makes really hard for someone to just copy and paste your source code and run it elsewhere.\n\nIf the source code isn't run on the domains specified by this option, the browser will be redirected to a passed to the [`domainLockRedirectUrl`](#domainlockredirecturl) option URL.\n\n##### Multiple domains and sub-domains\nIt's possible to lock your code to more than one domain or sub-domain. For instance, to lock it so the code only runs on **www.example.com** add `www.example.com`. To make it work on the root domain including any sub-domains (`example.com`, `sub.example.com`), use `.example.com`.\n\n### `domainLockRedirectUrl`\nType: `string` Default: `about:blank`\n\n##### :warning: This option does not work with `target: 'node'`\n\nAllows the browser to be redirected to a passed URL if the source code isn't run on the domains specified by [`domainLock`](#domainlock)\n\n### `exclude`\nType: `string[]` Default: `[]`\n\nA file names or globs which indicates files to exclude from obfuscation. \n\n### `forceTransformStrings`\nType: `string[]` Default: `[]`\n\nEnables force transformation of string literals, which being matched by passed RegExp patterns.\n\n##### :warning: This option affects only strings that shouldn't be transformed by [`stringArrayThreshold`](#stringarraythreshold) (or possible other thresholds in the future)\n\nThe option has a priority over `reservedStrings` option but hasn't a priority over `conditional comments`.\n\nExample:\n```ts\n\t{\n\t\tforceTransformStrings: [\n\t\t\t'some-important-value',\n\t\t\t'some-string_\\d'\n\t\t]\n\t}\n```\n\n### `identifierNamesCache`\nType: `Object | null` Default: `null`\n\nThe main goal for this option is the ability to use the same identifier names during obfuscation of multiple sources/files.\n\nCurrently the two types of the identifiers are supported:\n- Global identifiers:\n    * All global identifiers will be written to the cache;\n    * All matched **undeclared** global identifiers will be replaced by the values from the cache.\n- Property identifiers, only when `renameProperties` option is enabled:\n    * All property identifiers will be written to the cache;\n    * All matched property identifiers will be replaced by the values from the cache.\n\n#### Node.js API\nIf a `null` value is passed, completely disables the cache.\n\nIf an empty object (`{}`) is passed, enables the writing identifier names to the cache-object (`TIdentifierNamesCache` type). This cache-object will be accessed through the `getIdentifierNamesCache` method call of `ObfuscationResult` object.\n\nThe resulting cache-object can be next used as `identifierNamesGenerator` option value for using these names during obfuscation of all matched identifier names of next sources.\n\nExample:\n```ts\nconst source1ObfuscationResult = JavaScriptObfuscator.obfuscate(\n    `\n        function foo(arg) {\n           console.log(arg)\n        }\n        \n        function bar() {\n            var bark = 2;\n        }\n    `,\n    {\n        compact: false,\n        identifierNamesCache: {},\n        renameGlobals: true\n    }\n)\n\nconsole.log(source1ObfuscationResult.getIdentifierNamesCache());\n/*\n    { \n        globalIdentifiers: {\n            foo: '_0x5de86d',\n            bar: '_0x2a943b'\n        }\n    }\n*/\n\n\n\nconst source2ObfuscationResult = JavaScriptObfuscator.obfuscate(\n    `\n        // Expecting that these global functions are defined in another obfuscated file\n        foo(1);\n        bar();\n        \n        // Expecting that this global function is defined in third-party package\n        baz();\n    `,\n    {\n        compact: false,\n        identifierNamesCache: source1ObfuscationResult.getIdentifierNamesCache(),\n        renameGlobals: true\n    }\n)\n\nconsole.log(source2ObfuscationResult.getObfuscatedCode());\n/*\n    _0x5de86d(0x1);\n    _0x2a943b();\n    baz();\n */\n```\n\n#### CLI\nCLI has a different option `--identifier-names-cache-path` that allows defining a path to the existing `.json` file that will be used to read and write identifier names cache.\n\nIf a path to the empty file will be passed - identifier names cache will be written to that file.\n\nThis file with existing cache can be used again as `--identifier-names-cache-path` option value for using these names during obfuscation of all matched identifier names of the next files.\n\n### `identifierNamesGenerator`\nType: `string` Default: `hexadecimal`\n\nSets identifier names generator.\n\nAvailable values:\n* `dictionary`: identifier names from [`identifiersDictionary`](#identifiersdictionary) list\n* `hexadecimal`: identifier names like `_0xabc123`\n* `mangled`: short identifier names like `a`, `b`, `c`\n* `mangled-shuffled`: same as `mangled` but with shuffled alphabet\n\n### `identifiersDictionary`\nType: `string[]` Default: `[]`\n\nSets identifiers dictionary for [`identifierNamesGenerator`](#identifiernamesgenerator): `dictionary` option. Each identifier from the dictionary will be used in a few variants with a different casing of each character. Thus, the number of identifiers in the dictionary should depend on the identifiers amount at original source code.\n\n### `identifiersPrefix`\nType: `string` Default: `''`\n\nSets prefix for all global identifiers.\n\nUse this option when you want to obfuscate multiple files. This option helps to avoid conflicts between global identifiers of these files. Prefix should be different for every file.\n\n### `ignoreImports`\nType: `boolean` Default: `false`\n\nPrevents obfuscation of `require` imports. Could be helpful in some cases when for some reason runtime environment requires these imports with static strings only.\n\n### `inputFileName`\nType: `string` Default: `''`\n\nAllows to set name of the input file with source code. This name will be used internally for source map generation.\nRequired when using NodeJS API and `sourceMapSourcesMode` option has `sources` value`.\n\n### `log`\nType: `boolean` Default: `false`\n\nEnables logging of the information to the console.\n\n### `numbersToExpressions`\nType: `boolean` Default: `false`\n\nEnables numbers conversion to expressions\n\nExample: \n```ts\n// input\nconst foo = 1234;\n\n// output\nconst foo=-0xd93+-0x10b4+0x41*0x67+0x84e*0x3+-0xff8;\n```\n\n### `optionsPreset`\nType: `string` Default: `default`\n\nAllows to set [options preset](#preset-options).\n\nAvailable values: \n* `default`;\n* `low-obfuscation`;\n* `medium-obfuscation`;\n* `high-obfuscation`.\n\nAll addition options will be merged with selected options preset.\n\n### `renameGlobals`\nType: `boolean` Default: `false`\n\n##### :warning: this option can break your code. Enable it only if you know what it does!\n\nEnables obfuscation of global variable and function names **with declaration**.\n\n### `renameProperties`\nType: `boolean` Default: `false`\n\n##### :warning: this option **MAY** break your code. Enable it only if you know what it does!\n\nEnables renaming of property names. All built-in DOM properties and properties in core JavaScript classes will be ignored.\n\nTo switch between `safe` and `unsafe` modes of this option use [`renamePropertiesMode`](#renamepropertiesmode) option.\n\nTo set format of renamed property names use [`identifierNamesGenerator`](#identifiernamesgenerator) option.\n\nTo control which properties will be renamed use [`reservedNames`](#reservednames) option.\n\nExample: \n```ts\n// input\n(function () {\n    const foo = {\n        prop1: 1,\n        prop2: 2,\n        calc: function () {\n            return this.prop1 + this.prop2;\n        }\n    };\n    \n    console.log(foo.calc());\n})();\n\n// output\n(function () {\n    const _0x46529b = {\n        '_0x10cec7': 0x1,\n        '_0xc1c0ca': 0x2,\n        '_0x4b961d': function () {\n            return this['_0x10cec7'] + this['_0xc1c0ca'];\n        }\n    };\n    console['log'](_0x46529b['_0x4b961d']());\n}());\n```\n\n### `renamePropertiesMode`\nType: `string` Default: `safe`\n\n##### :warning: Even in `safe` mode, [`renameProperties`](#renameproperties) option **MAY** break your code.\n\nSpecifies `renameProperties` option mode:\n* `safe` - default behaviour after `2.11.0` release. Trying to rename properties in a more safe way to prevent runtime errors. With this mode some properties will be excluded from renaming.\n* `unsafe` - default behaviour before `2.11.0` release. Renames properties in an unsafe way without any restrictions.\n\nIf one file is using properties from other file, use [`identifierNamesCache`](#identifiernamescache) option to keep the same property names between these files.\n\n### `reservedNames`\nType: `string[]` Default: `[]`\n\nDisables obfuscation and generation of identifiers, which being matched by passed RegExp patterns.\n\nExample:\n```ts\n\t{\n\t\treservedNames: [\n\t\t\t'^someVariable',\n\t\t\t'functionParameter_\\d'\n\t\t]\n\t}\n```\n\n### `reservedStrings`\nType: `string[]` Default: `[]`\n\nDisables transformation of string literals, which being matched by passed RegExp patterns.\n\nExample:\n```ts\n\t{\n\t\treservedStrings: [\n\t\t\t'react-native',\n\t\t\t'\\.\\/src\\/test',\n\t\t\t'some-string_\\d'\n\t\t]\n\t}\n```\n\n### `seed`\nType: `string|number` Default: `0`\n\nThis option sets seed for random generator. This is useful for creating repeatable results.\n\nIf seed is `0` - random generator will work without seed.\n\n### `selfDefending`\nType: `boolean` Default: `false`\n\n##### :warning: Don't change obfuscated code in any way after obfuscation with this option, because any change like uglifying of code can trigger self defending and code wont work anymore!\n##### :warning: This option forcibly sets `compact` value to `true`\n\nThis option makes the output code resilient against formatting and variable renaming. If one tries to use a JavaScript beautifier on the obfuscated code, the code won't work anymore, making it harder to understand and modify it.\n\n### `simplify`\nType: `boolean` Default: `true`\n\nEnables additional code obfuscation through simplification.\n\n##### :warning: in future releases obfuscation of `boolean` literals (`true` =\u003e `!![]`) will be moved under this option. \n\nExample:\n```ts\n// input\nif (condition1) {\n    const foo = 1;\n    const bar = 2;\n  \n    console.log(foo);\n  \n    return bar;\n} else if (condition2) {\n    console.log(1);\n    console.log(2);\n    console.log(3);\n  \n    return 4;\n} else {\n    return 5;\n}\n\n// output\nif (condition1) {\n    const foo = 0x1, bar = 0x2;\n    return console['log'](foo), bar;\n} else\n    return condition2 ? (console['log'](0x1), console['log'](0x2), console['log'](0x3), 0x4) : 0x5;\n```\n\n### `sourceMap`\nType: `boolean` Default: `false`\n\nEnables source map generation for obfuscated code.\n\nSource maps can be useful to help you debug your obfuscated JavaScript source code. If you want or need to debug in production, you can upload the separate source map file to a secret location and then point your browser there. \n\n### `sourceMapBaseUrl`\nType: `string` Default: ``\n\nSets base url to the source map import url when [`sourceMapMode: 'separate'`](#sourcemapmode).\n \nCLI example:\n```\njavascript-obfuscator input.js --output out.js --source-map true --source-map-base-url 'http://localhost:9000'\n```\n\nResult: \n```\n//# sourceMappingURL=http://localhost:9000/out.js.map\n```\n\n### `sourceMapFileName`\nType: `string` Default: ``\n\nSets file name for output source map when `sourceMapMode: 'separate'`.\n\nCLI example:\n```\njavascript-obfuscator input.js --output out.js --source-map true --source-map-base-url 'http://localhost:9000' --source-map-file-name example\n```\n\nResult: \n```\n//# sourceMappingURL=http://localhost:9000/example.js.map\n```\n\n### `sourceMapMode`\nType: `string` Default: `separate`\n\nSpecifies source map generation mode:\n* `inline` - add source map at the end of each .js files;\n* `separate` - generates corresponding '.map' file with source map. In case you run obfuscator through CLI - adds link to source map file to the end of file with obfuscated code `//# sourceMappingUrl=file.js.map`.\n\n### `sourceMapSourcesMode`\nType: `string` Default: `sources-content`\n\nAllows to control `sources` and `sourcesContent` fields of the source map:\n* `sources-content` - adds dummy `sources` field, adds `sourcesContent` field with the original source code;\n* `sources` - adds `sources` field with a valid source description, does not add `sourcesContent` field. When using NodeJS API it's required to define `inputFileName` option that will be used as `sources` field value.\n\n### `splitStrings`\nType: `boolean` Default: `false`\n\nSplits literal strings into chunks with length of [`splitStringsChunkLength`](#splitstringschunklength) option value.\n\nExample:\n```ts\n// input\n(function(){\n    var test = 'abcdefg';\n})();\n\n// output\n(function(){\n    var _0x5a21 = 'ab' + 'cd' + 'ef' + 'g';\n})();\n```\n\n### `splitStringsChunkLength`\nType: `number` Default: `10`\n\nSets chunk length of [`splitStrings`](#splitstrings) option.\n\n### `stringArray`\nType: `boolean` Default: `true`\n\nRemoves string literals and place them in a special array. For instance, the string `\"Hello World\"` in `var m = \"Hello World\";` will be replaced with something like `var m = _0x12c456[0x1];`\n\n### `stringArrayCallsTransform`\nType: `boolean` Default: `false`\n\n##### :warning: [`stringArray`](#stringarray) option must be enabled\n\nEnables the transformation of calls to the [`stringArray`](#stringarray). All arguments of these calls may be extracted to a different object depending on [`stringArrayCallsTransformThreshold`](#stringarraycallstransformthreshold) value.\nSo it makes it even harder to automatically find calls to the string array.\n\nExample:\n```\nfunction foo() {\n    var k = {\n        c: 0x2f2,\n        d: '0x396',\n        e: '0x397',\n        f: '0x39a',\n        g: '0x39d',\n        h: 0x398,\n        l: 0x394,\n        m: '0x39b',\n        n: '0x39f',\n        o: 0x395,\n        p: 0x395,\n        q: 0x399,\n        r: '0x399'\n    };\n    var c = i(k.d, k.e);\n    var d = i(k.f, k.g);\n    var e = i(k.h, k.l);\n    var f = i(k.m, k.n);\n    function i(c, d) {\n        return b(c - k.c, d);\n    }\n    var g = i(k.o, k.p);\n    var h = i(k.q, k.r);\n}\nfunction j(c, d) {\n    var l = { c: 0x14b };\n    return b(c - -l.c, d);\n}\nconsole[j(-'0xa6', -'0xa6')](foo());\nfunction b(c, d) {\n    var e = a();\n    b = function (f, g) {\n        f = f - 0xa3;\n        var h = e[f];\n        return h;\n    };\n    return b(c, d);\n}\nfunction a() {\n    var m = [\n        'string5',\n        'string1',\n        'log',\n        'string3',\n        'string6',\n        'string2',\n        'string4'\n    ];\n    a = function () {\n        return m;\n    };\n    return a();\n}\n```\n\n### `stringArrayCallsTransformThreshold`\nType: `number` Default: `0.5`\n\n##### :warning: [`stringArray`](#stringarray) and [`stringArrayCallsTransformThreshold`](#stringarraycallstransformthreshold) options must be enabled\n\nYou can use this setting to adjust the probability (from 0 to 1) that calls to the string array will be transformed.\n\n### `stringArrayEncoding`\nType: `string[]` Default: `[]`\n\n##### :warning: `stringArray` option must be enabled\n\nThis option can slow down your script.\n\nEncode all string literals of the [`stringArray`](#stringarray) using `base64` or `rc4` and inserts a special code that used to decode it back at runtime.\n\nEach `stringArray` value will be encoded by the randomly picked encoding from the passed list. This makes possible to use multiple encodings.\n\nAvailable values:\n* `'none'` (`boolean`): doesn't encode `stringArray` value\n* `'base64'` (`string`): encodes `stringArray` value using `base64`\n* `'rc4'` (`string`): encodes `stringArray` value using `rc4`. **About 30-50% slower than `base64`, but harder to get initial values.** It's recommended to disable [`unicodeEscapeSequence`](#unicodeescapesequence) option when using `rc4` encoding to prevent very large size of obfuscated code.\n\nFor example with the following option values some `stringArray` value won't be encoded, and some values will be encoded with `base64` and `rc4` encoding:\n\n```ts\nstringArrayEncoding: [\n    'none',\n    'base64',\n    'rc4'\n]\n```\n\n### `stringArrayIndexesType`\nType: `string[]` Default: `['hexadecimal-number']`\n\n##### :warning: `stringArray` option must be enabled\n\nAllows to control the type of string array call indexes.\n\nEach `stringArray` call index will be transformed by the randomly picked type from the passed list. This makes possible to use multiple types.\n\nAvailable values:\n* `'hexadecimal-number'` (`default`): transforms string array call indexes as hexadecimal numbers\n* `'hexadecimal-numeric-string'`: transforms string array call indexes as hexadecimal numeric string\n\nBefore `2.9.0` release `javascript-obfuscator` transformed all string array call indexes with `hexadecimal-numeric-string` type. This makes some manual deobfuscation slightly harder but it allows easy detection of these calls by automatic deobfuscators.\n\nThe new `hexadecimal-number` type approaches to make harder auto-detect of string array call patterns in the code.\n\nMore types will be added in the future.\n\n### `stringArrayIndexShift`\nType: `boolean` Default: `true`\n\n##### :warning: `stringArray` option must be enabled\n\nEnables additional index shift for all string array calls\n\n### `stringArrayRotate`\nType: `boolean` Default: `true`\n\n##### :warning: [`stringArray`](#stringarray) must be enabled\n\nShift the `stringArray` array by a fixed and random (generated at the code obfuscation) places. This makes it harder to match the order of the removed strings to their original place.\n\n### `stringArrayShuffle`\nType: `boolean` Default: `true`\n\n##### :warning: [`stringArray`](#stringarray) must be enabled\n\nRandomly shuffles the `stringArray` array items.\n\n### `stringArrayWrappersCount`\nType: `number` Default: `1`\n\n##### :warning: [`stringArray`](#stringarray) option must be enabled\n\nSets the count of wrappers for the `string array` inside each root or function scope.\nThe actual count of wrappers inside each scope is limited by a count of `literal` nodes within this scope.\n\nExample:\n```ts\n// Input\nconst foo = 'foo';\nconst bar = 'bar';\n        \nfunction test () {\n    const baz = 'baz';\n    const bark = 'bark';\n    const hawk = 'hawk';\n}\n\nconst eagle = 'eagle';\n\n// Output, stringArrayWrappersCount: 5\nconst _0x3f6c = [\n    'bark',\n    'bar',\n    'foo',\n    'eagle',\n    'hawk',\n    'baz'\n];\nconst _0x48f96e = _0x2e13;\nconst _0x4dfed8 = _0x2e13;\nconst _0x55e970 = _0x2e13;\nfunction _0x2e13(_0x33c4f5, _0x3f6c62) {\n    _0x2e13 = function (_0x2e1388, _0x60b1e) {\n        _0x2e1388 = _0x2e1388 - 0xe2;\n        let _0x53d475 = _0x3f6c[_0x2e1388];\n        return _0x53d475;\n    };\n    return _0x2e13(_0x33c4f5, _0x3f6c62);\n}\nconst foo = _0x48f96e(0xe4);\nconst bar = _0x4dfed8(0xe3);\nfunction test() {\n    const _0x1c262f = _0x2e13;\n    const _0x54d7a4 = _0x2e13;\n    const _0x5142fe = _0x2e13;\n    const _0x1392b0 = _0x1c262f(0xe7);\n    const _0x201a58 = _0x1c262f(0xe2);\n    const _0xd3a7fb = _0x1c262f(0xe6);\n}\nconst eagle = _0x48f96e(0xe5);\n```\n\n### `stringArrayWrappersChainedCalls`\nType: `boolean` Default: `true`\n\n##### :warning: [`stringArray`](#stringarray) and [`stringArrayWrappersCount`](#stringarraywrapperscount) options must be enabled\n\nEnables the chained calls between `string array` wrappers.\n\nExample:\n```ts\n// Input\nconst foo = 'foo';\nconst bar = 'bar';\n        \nfunction test () {\n    const baz = 'baz';\n    const bark = 'bark';\n\n    function test1() {\n        const hawk = 'hawk';\n        const eagle = 'eagle';\n    } \n}\n\n// Output, stringArrayWrappersCount: 5, stringArrayWrappersChainedCalls: true\nconst _0x40c2 = [\n    'bar',\n    'bark',\n    'hawk',\n    'eagle',\n    'foo',\n    'baz'\n];\nconst _0x31c087 = _0x3280;\nconst _0x31759a = _0x3280;\nfunction _0x3280(_0x1f52ee, _0x40c2a2) {\n    _0x3280 = function (_0x3280a4, _0xf07b02) {\n        _0x3280a4 = _0x3280a4 - 0x1c4;\n        let _0x57a182 = _0x40c2[_0x3280a4];\n        return _0x57a182;\n    };\n    return _0x3280(_0x1f52ee, _0x40c2a2);\n}\nconst foo = _0x31c087(0x1c8);\nconst bar = _0x31c087(0x1c4);\nfunction test() {\n    const _0x848719 = _0x31759a;\n    const _0x2693bf = _0x31c087;\n    const _0x2c08e8 = _0x848719(0x1c9);\n    const _0x359365 = _0x2693bf(0x1c5);\n    function _0x175e90() {\n        const _0x310023 = _0x848719;\n        const _0x2302ef = _0x2693bf;\n        const _0x237437 = _0x310023(0x1c6);\n        const _0x56145c = _0x310023(0x1c7);\n    }\n}\n```\n\n### `stringArrayWrappersParametersMaxCount`\nType: `number` Default: `2`\n\n##### :warning: [`stringArray`](#stringarray) option must be enabled\n##### :warning: Currently this option affects only wrappers added by [`stringArrayWrappersType`](#stringarraywrapperstype) `function` option value\n\nAllows to control the maximum number of string array wrappers parameters.\nDefault and minimum value is `2`. Recommended value between `2` and `5`.\n\n### `stringArrayWrappersType`\nType: `string` Default: `variable`\n\n##### :warning: [`stringArray`](#stringarray) and [`stringArrayWrappersCount`](#stringarraywrapperscount) options must be enabled\n\nAllows to select a type of the wrappers that are appending by the `stringArrayWrappersCount` option.\n\nAvailable values:\n* `'variable'`: appends variable wrappers at the top of each scope. Fast performance.\n* `'function'`: appends function wrappers at random positions inside each scope. Slower performance than with `variable` but provides more strict obfuscation.\n\nHighly recommended to use `function` wrappers for higher obfuscation when a performance loss doesn't have a high impact on an obfuscated application.\n\nExample of the `'function'` option value:\n```ts\n// input\nconst foo = 'foo';\n\nfunction test () {\n    const bar = 'bar';\n    console.log(foo, bar);\n}\n\ntest();\n\n// output\nconst a = [\n    'log',\n    'bar',\n    'foo'\n];\nconst foo = d(0x567, 0x568);\nfunction b(c, d) {\n    b = function (e, f) {\n        e = e - 0x185;\n        let g = a[e];\n        return g;\n    };\n    return b(c, d);\n}\nfunction test() {\n    const c = e(0x51c, 0x51b);\n    function e (c, g) {\n        return b(c - 0x396, g);\n    }\n    console[f(0x51b, 0x51d)](foo, c);\n    function f (c, g) {\n        return b(c - 0x396, g);\n    }\n}\nfunction d (c, g) {\n    return b(g - 0x3e1, c);\n}\ntest();\n```\n    \n### `stringArrayThreshold`\nType: `number` Default: `0.8` Min: `0` Max: `1`\n\n##### :warning: [`stringArray`](#stringarray) option must be enabled\n\nYou can use this setting to adjust the probability (from 0 to 1) that a string literal will be inserted into the `stringArray`.\n\nThis setting is especially useful for large code size because it repeatedly calls to the `string array` and can slow down your code.\n\n`stringArrayThreshold: 0` equals to `stringArray: false`.\n\n### `target`\nType: `string` Default: `browser`\n\nAllows to set target environment for obfuscated code.\n\nAvailable values: \n* `browser`;\n* `browser-no-eval`;\n* `node`.\n\nCurrently output code for `browser` and `node` targets is identical, but some browser-specific options are not allowed to use with `node` target.\nOutput code for `browser-no-eval` target is not using `eval`.\n\n### `transformObjectKeys`\nType: `boolean` Default: `false`\n\nEnables transformation of object keys.\n\nExample:\n```ts\n// input\n(function(){\n    var object = {\n        foo: 'test1',\n        bar: {\n            baz: 'test2'\n        }\n    };\n})();\n\n// output\nvar _0x4735 = [\n    'foo',\n    'baz',\n    'bar',\n    'test1',\n    'test2'\n];\nfunction _0x390c(_0x33d6b6, _0x4735f4) {\n    _0x390c = function (_0x390c37, _0x1eed85) {\n        _0x390c37 = _0x390c37 - 0x198;\n        var _0x2275f8 = _0x4735[_0x390c37];\n        return _0x2275f8;\n    };\n    return _0x390c(_0x33d6b6, _0x4735f4);\n}\n(function () {\n    var _0x17d1b7 = _0x390c;\n    var _0xc9b6bb = {};\n    _0xc9b6bb[_0x17d1b7(0x199)] = _0x17d1b7(0x19c);\n    var _0x3d959a = {};\n    _0x3d959a[_0x17d1b7(0x198)] = _0x17d1b7(0x19b);\n    _0x3d959a[_0x17d1b7(0x19a)] = _0xc9b6bb;\n    var _0x41fd86 = _0x3d959a;\n}());\n```\n\n### `unicodeEscapeSequence`\nType: `boolean` Default: `false`\n\nAllows to enable/disable string conversion to unicode escape sequence.\n\nUnicode escape sequence increases code size greatly and strings easily can be reverted to their original view. Recommended to enable this option only for small source code. \n\n## Preset Options\n### High obfuscation, low performance\n\nThe performance will be much slower than without obfuscation\n\n```javascript\n{\n    compact: true,\n    controlFlowFlattening: true,\n    controlFlowFlatteningThreshold: 1,\n    deadCodeInjection: true,\n    deadCodeInjectionThreshold: 1,\n    debugProtection: true,\n    debugProtectionInterval: 4000,\n    disableConsoleOutput: true,\n    identifierNamesGenerator: 'hexadecimal',\n    log: false,\n    numbersToExpressions: true,\n    renameGlobals: false,\n    selfDefending: true,\n    simplify: true,\n    splitStrings: true,\n    splitStringsChunkLength: 5,\n    stringArray: true,\n    stringArrayCallsTransform: true,\n    stringArrayEncoding: ['rc4'],\n    stringArrayIndexShift: true,\n    stringArrayRotate: true,\n    stringArrayShuffle: true,\n    stringArrayWrappersCount: 5,\n    stringArrayWrappersChainedCalls: true,    \n    stringArrayWrappersParametersMaxCount: 5,\n    stringArrayWrappersType: 'function',\n    stringArrayThreshold: 1,\n    transformObjectKeys: true,\n    unicodeEscapeSequence: false\n}\n```\n\n### Medium obfuscation, optimal performance\n\nThe performance will be slower than without obfuscation\n\n```javascript\n{\n    compact: true,\n    controlFlowFlattening: true,\n    controlFlowFlatteningThreshold: 0.75,\n    deadCodeInjection: true,\n    deadCodeInjectionThreshold: 0.4,\n    debugProtection: false,\n    debugProtectionInterval: 0,\n    disableConsoleOutput: true,\n    identifierNamesGenerator: 'hexadecimal',\n    log: false,\n    numbersToExpressions: true,\n    renameGlobals: false,\n    selfDefending: true,\n    simplify: true,\n    splitStrings: true,\n    splitStringsChunkLength: 10,\n    stringArray: true,\n    stringArrayCallsTransform: true,\n    stringArrayCallsTransformThreshold: 0.75,\n    stringArrayEncoding: ['base64'],\n    stringArrayIndexShift: true,\n    stringArrayRotate: true,\n    stringArrayShuffle: true,\n    stringArrayWrappersCount: 2,\n    stringArrayWrappersChainedCalls: true,\n    stringArrayWrappersParametersMaxCount: 4,\n    stringArrayWrappersType: 'function',\n    stringArrayThreshold: 0.75,\n    transformObjectKeys: true,\n    unicodeEscapeSequence: false\n}\n```\n\n### Low obfuscation, High performance\n\nThe performance will be at a relatively normal level\n\n```javascript\n{\n    compact: true,\n    controlFlowFlattening: false,\n    deadCodeInjection: false,\n    debugProtection: false,\n    debugProtectionInterval: 0,\n    disableConsoleOutput: true,\n    identifierNamesGenerator: 'hexadecimal',\n    log: false,\n    numbersToExpressions: false,\n    renameGlobals: false,\n    selfDefending: true,\n    simplify: true,\n    splitStrings: false,\n    stringArray: true,\n    stringArrayCallsTransform: false,\n    stringArrayEncoding: [],\n    stringArrayIndexShift: true,\n    stringArrayRotate: true,\n    stringArrayShuffle: true,\n    stringArrayWrappersCount: 1,\n    stringArrayWrappersChainedCalls: true,\n    stringArrayWrappersParametersMaxCount: 2,\n    stringArrayWrappersType: 'variable',\n    stringArrayThreshold: 0.75,\n    unicodeEscapeSequence: false\n}\n```\n\n### Default preset, High performance\n\n```javascript\n{\n    compact: true,\n    controlFlowFlattening: false,\n    deadCodeInjection: false,\n    debugProtection: false,\n    debugProtectionInterval: 0,\n    disableConsoleOutput: false,\n    identifierNamesGenerator: 'hexadecimal',\n    log: false,\n    numbersToExpressions: false,\n    renameGlobals: false,\n    selfDefending: false,\n    simplify: true,\n    splitStrings: false,\n    stringArray: true,\n    stringArrayCallsTransform: false,\n    stringArrayCallsTransformThreshold: 0.5,\n    stringArrayEncoding: [],\n    stringArrayIndexShift: true,\n    stringArrayRotate: true,\n    stringArrayShuffle: true,\n    stringArrayWrappersCount: 1,\n    stringArrayWrappersChainedCalls: true,\n    stringArrayWrappersParametersMaxCount: 2,\n    stringArrayWrappersType: 'variable',\n    stringArrayThreshold: 0.75,\n    unicodeEscapeSequence: false\n}\n```\n\n\u003c!-- ##options-end## --\u003e\n\n## Obfuscator.io Pro Options\n\n\u003e :warning: **The following VM obfuscation/Pro options are available only via the [Obfuscator.io Pro API](https://obfuscator.io/).**\n\u003e\n\u003e To use these options, you need a Pro API token from [obfuscator.io](https://obfuscator.io) and must call the `obfuscatePro()` method instead of `obfuscate()`. See the [Pro API Methods](#shield-pro-api-methods-vm-obfuscation) section for details.\n\n### `vmObfuscation`\nType: `boolean` Default: `false`\n\nEnables VM-based bytecode obfuscation. When enabled, JavaScript functions are compiled into custom bytecode that runs on an embedded virtual machine. This provides the highest level of protection as the original code logic is completely transformed.\n\n**Example:**\nYour readable code like `return qty * price` becomes a list of numbers like `[0x15,0x03,0x17,...]` that only the embedded VM interpreter can execute. The original logic is no longer visible as JavaScript.\n\n### `vmObfuscationThreshold`\nType: `number` Default: `1`\n\nControls what percentage of your root-level functions get VM protection.\n\n\u003e **Warning:** Values other than `1` may cause runtime bugs when VM-obfuscated and non-VM-obfuscated code share top-level variables. A value of `1` is strongly recommended. For selective function obfuscation, use `vmTargetFunctionsMode: 'comment'` with the `// javascript-obfuscator:vm` directive instead.\n\n### `vmPreprocessIdentifiers`\nType: `boolean` Default: `true`\n\nRenames all non-global identifiers to unique hexadecimal names before VM obfuscation. This eliminates variable shadowing that can cause scope resolution issues in the VM bytecode.\n\n**When to disable:** Only disable this if you encounter specific compatibility issues. The preprocessing step ensures correct variable resolution in complex nested scopes.\n\n### `vmTargetFunctions`\nType: `string[]` Default: `[]`\n\nSpecify exactly which root-level functions should get VM protection by name.\n\n**Example:**\n```javascript\n{\n    vmObfuscation: true,\n    vmTargetFunctions: ['someFunctionName']\n}\n```\n\n**Result:** Only these three functions get VM-protected. Everything else stays as regular (but still obfuscated) JavaScript. Perfect for protecting sensitive license checks or authentication logic while keeping the rest of your code lean.\n\n### `vmExcludeFunctions`\nType: `string[]` Default: `[]`\n\nSpecify root-level functions that should never get VM protection. Takes precedence over other settings.\n\n**Example:**\n```javascript\n{\n    vmObfuscation: true,\n    vmExcludeFunctions: ['someFunctionName']\n}\n```\n\n**When to use:** Performance-critical root-level functions (animation loops, real-time data processing) can be excluded to avoid VM overhead while still protecting everything else.\n\n### `vmTargetFunctionsMode`\nType: `string` Default: `root`\n\nControls how functions/methods are selected for VM obfuscation.\n\n| Mode | Description                                                                                                                                                      |\n|------|------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `root` | Default behavior. Only root-level functions are considered for VM obfuscation. Uses `vmTargetFunctions` allow-list and `vmExcludeFunctions` deny-list to filter. |\n| `comment` | Only functions/methods decorated with `/* javascript-obfuscator:vm */` comment are VM-obfuscated. Works with functions/methods at **any nesting level**.         |\n\n**Example - Comment mode:**\n```javascript\n// Source code\nfunction regularFunction() {\n    return 'not virtualized';\n}\n\n/* javascript-obfuscator:vm */\nfunction sensitiveFunction() {\n    return 'this will be VM-protected';\n}\n\nfunction outer() {\n    /* javascript-obfuscator:vm */\n    function nestedSensitive() {\n        return 'nested but still VM-protected';\n    }\n    return nestedSensitive();\n}\n```\n\n```javascript\n// Obfuscator options\n{\n    vmObfuscation: true,\n    vmTargetFunctionsMode: 'comment'\n}\n```\n\n**When to use:** When you need surgical control over exactly which functions get VM protection, especially nested functions that contain sensitive logic. Unlike `vmTargetFunctions` which only works with root-level named functions, comment mode lets you protect any function anywhere in your code.\n\n### `vmWrapTopLevelInitializers`\nType: `boolean` Default: `false`\n\nWraps some top-level variable initializers in IIFEs (Immediately Invoked Function Expressions) so they can be VM-obfuscated.\n\n**What it does:**\nWithout this option, top-level constants and variables remain visible in the output:\n```javascript\n// Input\nconst MY_STRING = \"my-string\";\n\n// Output (without vmWrapTopLevelInitializers)\nconst MY_STRING = \"my-string\";  // String is visible!\n```\n\nWith this option enabled, the initializer is wrapped in an IIFE that gets VM-obfuscated:\n```javascript\n// Input\nconst MY_STRING = \"my-string\";\n\n// Output (with vmWrapTopLevelInitializers: true)\nconst MY_STRING = (() =\u003e { return /* VM bytecode call */ })();  // String hidden in bytecode\n```\n\n**Note:** This option only works when `vmTargetFunctionsMode` is `'root'` (the default).\n\n### `vmDynamicOpcodes`\nType: `boolean` Default: `false`\n\nMakes the VM interpreter smaller and unique for each build.\n\n**What it does:**\n1. **Filters unused instructions** - If your code doesn't use classes, class-related instructions are removed entirely\n2. **Randomizes structure** - The order of instruction handlers is shuffled each build\n\nAs the result - smaller output and each build looks different.\n\n### `vmOpcodeShuffle`\nType: `boolean` Default: `false`\n\nRandomizes the numeric values assigned to each opcode. For example, the `LOAD` instruction might be `1` in one build and `47` in another.\n\n### `vmBytecodeEncoding`\nType: `boolean` Default: `false`\n\nEncodes each bytecode instruction. Instructions are decoded one at a time during execution.\n\n### `vmBytecodeArrayEncoding`\nType: `boolean` Default: `false`\n\nEncodes the entire bytecode array as a single block. The array is decoded once at startup before execution begins. Use together with `vmBytecodeEncoding` for two layers of protection.\n\n### `vmBytecodeArrayEncodingKey`\nType: `string` Default: `''`\n\nCustom encryption key for bytecode array encoding. When set, this key is used instead of the default environment-derived key. The key must be provided at runtime via `vmBytecodeArrayEncodingKeyGetter`.\n\nThis option externalizes the encryption key - it's not embedded in the obfuscated code itself. While the key is still accessible at runtime (and thus not truly secret), this separation prevents static analysis tools from finding the key by examining the code alone.\n\n**Important:** The key must be available **synchronously** when the obfuscated code loads. Use synchronous storage like cookies, localStorage, sessionStorage, global variables, or DOM elements (e.g., server-injected meta tags). Async methods like `fetch()` cannot be used directly in the key getter expression.\n\n### `vmBytecodeArrayEncodingKeyGetter`\nType: `string` Default: `''`\n\n**Synchronous** JavaScript expression that **returns** the encryption key at runtime. This expression is evaluated when the obfuscated code loads, and must return the same key that was provided in `vmBytecodeArrayEncodingKey`.\n\n**The obfuscated code will only work when the key getter returns exactly the same key that was used during obfuscation.** If the keys don't match, decryption will fail and the code will produce garbage or errors. If the key getter returns `undefined`, `null`, or an empty string, the code will throw an error: \"VM decryption key not available\".\n\n**Important:** The key should NOT be defined in the same JavaScript file/script as the obfuscated code. Doing so defeats the purpose of key externalization, as static analysis could still find the key. Store the key in a separate source: server-set cookies, localStorage populated by another script, server-injected HTML meta tags, or a global variable set by a different script that loads before the obfuscated code.\n\nExamples:\n```ts\n// From cookie\nvmBytecodeArrayEncodingKeyGetter: \"document.cookie.match(/vmKey=([^;]+)/)?.[1]\"\n\n// From localStorage\nvmBytecodeArrayEncodingKeyGetter: \"localStorage.getItem('vmKey')\"\n\n// From global variable\nvmBytecodeArrayEncodingKeyGetter: \"window.__VM_KEY__\"\n\n// From meta tag (server-injected)\nvmBytecodeArrayEncodingKeyGetter: \"document.querySelector('meta[name=\\\"vm-key\\\"]').content\"\n\n// From nested object\nvmBytecodeArrayEncodingKeyGetter: \"window.config.encryption.key\"\n```\n\n**Usage example:**\n```ts\n// Build time\nJavaScriptObfuscator.obfuscate(code, {\n    vmObfuscation: true,\n    vmBytecodeArrayEncoding: true,\n    vmBytecodeArrayEncodingKey: 'mySecretKey123',\n    vmBytecodeArrayEncodingKeyGetter: 'window.__VM_KEY__'\n});\n\n// Runtime - key must be set before obfuscated code runs\nwindow.__VM_KEY__ = 'mySecretKey123';\n```\n\n### `vmJumpsEncoding`\nType: `boolean` Default: `false`\n\nEncodes jump targets in the bytecode. Jump offsets are calculated at runtime, hiding the control flow structure (`if`/`else`, loops, etc.) from static analysis.\n\n### `vmDecoyOpcodes`\nType: `boolean` Default: `false`\n\nAdds fake opcode handlers to the VM dispatcher that are never called. For example, if the VM uses 20 real opcodes, this might add 30 fake handlers, making the interpreter appear more complex than it really is.\n\n### `vmDeadCodeInjection`\nType: `boolean` Default: `false`\n\nInjects fake bytecode sequences that are never executed. These look like real instructions but are skipped during runtime, confusing analysis tools that process them.\n\n### `vmSplitDispatcher`\nType: `boolean` Default: `false`\n\nSplits the VM dispatcher into multiple smaller switch statements organized by opcode category, instead of one large monolithic switch. Each category (stack, arithmetic, control flow, etc.) gets its own switch, routed by if/else range checks.\n\nThis option supports `vmDynamicOpcodes` in both modes: `true` (shuffle first, then split into groups) and `false`.\n\n\u003e :warning: When `vmIndirectDispatch` is enabled, this option is ignored. Prefer `vmIndirectDispatch` as it provides better obfuscation with similar performance.\n\n### `vmIndirectDispatch`\nType: `boolean` Default: `false`\n\nUses compile-time generated handler functions for opcode dispatch instead of switch statements. Handlers are generated at compile-time with inlined opcode logic and shuffled positions.\n\nInstead of:\n```javascript\nswitch(op) {\n    case 0: /* handle opcode 0 */ break;\n    case 1: /* handle opcode 1 */ break;\n}\n```\n\nIt generates:\n```javascript\nvar _hm = {0:42, 1:17, ...};  // opcode → handler index mapping\nvar _h = [handler0, handler1, ...];  // shuffled handler array\n_h[_hm[op]](arg);  // single lookup + function call\n```\n\nThis option supports `vmDynamicOpcodes` in both modes.\n\n\u003e :warning: When enabled, this takes priority over `vmSplitDispatcher`. Both options cannot be active simultaneously.\n\n### `vmCompactDispatcher`\nType: `boolean` Default: `false`\n\nUses a single unified dispatcher (generator-based) for both sync and async/generator code execution. By default (`false`), the VM generates two separate dispatchers: a non-generator version for sync code (faster) and a generator version for async/generator code. When enabled, only the generator-based dispatcher is used for all execution.\n\n**Trade-offs:**\n- `false` (default): Larger code size due to dual dispatchers, but faster sync execution (no generator overhead)\n- `true`: Smaller code size with single dispatcher, but sync code has generator protocol overhead\n\nUse this when code size is more important than sync execution speed.\n\n### `vmMacroOps`\nType: `boolean` Default: `false`\n\nCombines common instruction sequences into single \"macro\" opcodes. For example, `LOAD + ADD + STORE` might become a single `MACRO_ADD_TO_VAR` instruction. This breaks pattern recognition and can improve performance.\n\n### `vmDebugProtection`\nType: `boolean` Default: `false`\n\nAdds anti-debugging measures to the VM runtime. Detects debugger presence and alters behavior when debugging is detected.\n\n### `vmRuntimeOpcodeDerivation`\nType: `boolean` Default: `false`\n\nDerives the opcode mapping table at runtime from a seed value instead of hardcoding it. The seed is stored in the bytecode and used to generate the opcode-to-handler mapping via Fisher-Yates shuffle during execution.\n\n### `vmStatefulOpcodes`\nType: `boolean` Default: `false`\n\nMakes opcode meanings depend on position in the bytecode. Each position has a different opcode-to-handler mapping derived from a seed, so the same opcode number performs different operations at different positions.\n\n### `vmStackEncoding`\nType: `boolean` Default: `false`\n\nEncrypts values on the VM stack during execution. Values are encoded when pushed and decoded when popped, so memory inspection shows encrypted data instead of actual values.\n\nThis option heavily affects performance.\n\n### `vmInstructionShuffle`\nType: `boolean` Default: `false`\n\nRandomizes the bytecode instruction layout per function. Each function can have a different instruction array format:\n- Layout 0: `[op, arg, op, arg, ...]` (interleaved - default)\n- Layout 1: `[arg, op, arg, op, ...]` (swapped interleaved)\n- Layout 2: `[op0, op1, ..., arg0, arg1, ...]` (opcodes first, then arguments)\n- Layout 3: `[arg0, arg1, ..., op0, op1, ...]` (arguments first, then opcodes)\n\nThis makes pattern recognition across functions harder during analysis.\n\n### `vmRandomizeKeys`\nType: `boolean` Default: `false`\n\nRandomizes the property key names used in bytecode objects. Standard keys like `i` (instructions), `c` (constants) become random 2-character identifiers, making the bytecode structure different for each build.\n\n### `vmBytecodeFormat`\nType: `string` Default: `binary`\n\nControls how bytecode is stored in the output.\n\n**Options:**\n- `binary` - Compact binary format. Smaller size, recommended for production.\n- `json` - Human-readable JSON format. Larger size, useful for debugging.\n\n### `strictMode`\nType: `boolean | null` Default: `null`\n\nAllows to specify how the obfuscator should treat code regarding JavaScript strict mode.\n\nAvailable values:\n* `null` (default) - auto-detect strict mode from the code. If the code has explicit `'use strict'` directive, ES module syntax, or class methods, it's treated as strict mode. Otherwise, sloppy mode is assumed.\n* `true` - force strict mode treatment for all code, even without explicit `'use strict'` directive. Use this when your code will run in strict mode context (e.g., in ES modules, bundlers, or modern frameworks).\n* `false` - only explicit strict mode indicators (`'use strict'`, ES modules, class methods) are treated as strict. Parent scope inheritance still applies per JS spec.\n\n### `parseHtml`\nType: `boolean` Default: `false`\n\nEnables obfuscation of JavaScript within HTML `\u003cscript\u003e` tags.\n\nWhen enabled, the obfuscator will:\n- Auto-detect if input is HTML (by checking for `\u003c!DOCTYPE`, `\u003chtml\u003e`, `\u003chead\u003e`, `\u003cbody\u003e`, or `\u003cscript\u003e` tags)\n- Extract JavaScript from `\u003cscript\u003e` tags marked with the `data-javascript-obfuscator` attribute\n- Obfuscate each marked script individually while preserving the HTML structure\n- Inject obfuscated code back into the original positions\n\n**Important:** Only scripts with the `data-javascript-obfuscator` attribute are obfuscated. Each marked script is obfuscated individually and independently. This means:\n- Code inside marked script tags **must be isolated** - it must NOT reference variables, functions, or classes defined in other marked script tags\n- Unmarked scripts can still access globals defined by marked scripts (via `var` declarations or explicit `globalThis` assignments)\n- This gives you explicit control over which scripts to protect\n\n**Obfuscated (must have `data-javascript-obfuscator` attribute):**\n- `\u003cscript data-javascript-obfuscator\u003e` - regular scripts\n- `\u003cscript type=\"text/javascript\" data-javascript-obfuscator\u003e` - explicitly typed scripts\n- Scripts with any additional attributes (`id`, `class`, other `data-*`, etc.)\n\n**Skipped (left unchanged):**\n- Scripts without `data-javascript-obfuscator` attribute\n- `\u003cscript type=\"module\"\u003e` - ES modules (even with the attribute)\n- `\u003cscript src=\"...\"\u003e` - external scripts (even with the attribute)\n- Empty script tags\n\n**Note:** Source maps are not generated when `parseHtml` is enabled, as they would not map correctly to the HTML output.\n\nExample:\n```ts\n// input\nconst html = `\u003c!DOCTYPE html\u003e\n\u003chtml\u003e\n  \u003cbody\u003e\n    \u003c!-- This script will NOT be obfuscated --\u003e\n    \u003cscript\u003e\n      var helper = 'utility';\n    \u003c/script\u003e\n    \n    \u003c!-- This script WILL be obfuscated --\u003e\n    \u003cscript data-javascript-obfuscator\u003e\n      var greeting = 'Hello World';\n      console.log(greeting);\n    \u003c/script\u003e\n  \u003c/body\u003e\n\u003c/html\u003e`;\n\nJavaScriptObfuscator.obfuscate(html, {\n    parseHtml: true,\n    stringArray: true\n});\n\n// output: HTML with only the marked script obfuscated\n```\n\n## Frequently Asked Questions\n\n### What javascript versions are supported?\n\n`es3`, `es5`, `es2015`, `es2016`, `es2017`, `es2018`, `es2019` and partially `es2020`\n\n### I want to use feature that described in `README.md` but it's not working!\n\nThe README on the master branch might not match that of the latest stable release.\n\n### Why CLI command not working?\n\nTry to run `npm link javascript-obfuscator` command or install it globally with `npm i -g javascript-obfuscator`\n\n### Online version?\n\n[obfuscator.io](https://obfuscator.io)\n\n### JSX support?\n\nNo. JSX support isn't planned.\n\n### How to change kind of variables of inserted nodes (`var`, `let` or `const`)?\n\nSee: [`Kind of variables`](#kind-of-variables)\n\n### Why I got `null` value instead of `BigInt` number?\n\n`BigInt` obfuscation works correctly only in environments that support `BigInt` values. See [ESTree spec](https://github.com/estree/estree/blob/master/es2020.md#bigintliteral)\n\n### I enabled `renameProperties` option, and my code broke! What to do?\n\nTry `renamePropertiesMode: 'safe'` option, if it still doesn't work, just disable this option.\n\n## GitHub Sponsors\n\n\u003ca href=\"https://github.com/microsoft\" target=\"_blank\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/6154722?s=200\u0026v=4\"\u003e\u003c/a\u003e\n\n## Backers\n\nSupport us with a monthly donation and help us continue our activities. [[Become a backer](https://opencollective.com/javascript-obfuscator#backer)]\n\n\u003ca href=\"https://opencollective.com/javascript-obfuscator/backer/0/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/javascript-obfuscator/backer/0/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/javascript-obfuscator/backer/1/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/javascript-obfuscator/backer/1/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/javascript-obfuscator/backer/2/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/javascript-obfuscator/backer/2/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/javascript-obfuscator/backer/3/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/javascript-obfuscator/backer/3/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/javascript-obfuscator/backer/4/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/javascript-obfuscator/backer/4/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/javascript-obfuscator/backer/5/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/javascript-obfuscator/backer/5/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/javascript-obfuscator/backer/6/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/javascript-obfuscator/backer/6/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/javascript-obfuscator/backer/7/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/javascript-obfuscator/backer/7/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/javascript-obfuscator/backer/8/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/javascript-obfuscator/backer/8/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/javascript-obfuscator/backer/9/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/javascript-obfuscator/backer/9/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/javascript-obfuscator/backer/10/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/javascript-obfuscator/backer/10/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/javascript-obfuscator/backer/11/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/javascript-obfuscator/backer/11/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/javascript-obfuscator/backer/12/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/javascript-obfuscator/backer/12/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/javascript-obfuscator/backer/13/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/javascript-obfuscator/backer/13/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/javascript-obfuscator/backer/14/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/javascript-obfuscator/backer/14/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/javascript-obfuscator/backer/15/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/javascript-obfuscator/backer/15/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/javascript-obfuscator/backer/16/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/javascript-obfuscator/backer/16/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/javascript-obfuscator/backer/17/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/javascript-obfuscator/backer/17/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/javascript-obfuscator/backer/18/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/javascript-obfuscator/backer/18/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/javascript-obfuscator/backer/19/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/javascript-obfuscator/backer/19/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/javascript-obfuscator/backer/20/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/javascript-obfuscator/backer/20/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/javascript-obfuscator/backer/21/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/javascript-obfuscator/backer/21/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/javascript-obfuscator/backer/22/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/javascript-obfuscator/backer/22/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/javascript-obfuscator/backer/23/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/javascript-obfuscator/backer/23/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/javascript-obfuscator/backer/24/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/javascript-obfuscator/backer/24/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/javascript-obfuscator/backer/25/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/javascript-obfuscator/backer/25/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/javascript-obfuscator/backer/26/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/javascript-obfuscator/backer/26/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/javascript-obfuscator/backer/27/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/javascript-obfuscator/backer/27/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/javascript-obfuscator/backer/28/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/javascript-obfuscator/backer/28/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/javascript-obfuscator/backer/29/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/javascript-obfuscator/backer/29/avatar.svg\"\u003e\u003c/a\u003e\n\n\n## Open Collective Sponsors\n\nBecome a sponsor and get your logo on our README on Github with a link to your site.\n\n\u003ca href=\"https://opencollective.com/javascript-obfuscator/sponsor/0/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/javascript-obfuscator/sponsor/0/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/javascript-obfuscator/sponsor/1/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/javascript-obfuscator/sponsor/1/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/javascript-obfuscator/sponsor/2/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/javascript-obfuscator/sponsor/2/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/javascript-obfuscator/sponsor/3/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/javascript-obfuscator/sponsor/3/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/javascript-obfuscator/sponsor/4/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/javascript-obfuscator/sponsor/4/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/javascript-obfuscator/sponsor/5/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/javascript-obfuscator/sponsor/5/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/javascript-obfuscator/sponsor/6/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/javascript-obfuscator/sponsor/6/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/javascript-obfuscator/sponsor/7/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/javascript-obfuscator/sponsor/7/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/javascript-obfuscator/sponsor/8/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/javascript-obfuscator/sponsor/8/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/javascript-obfuscator/sponsor/9/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/javascript-obfuscator/sponsor/9/avatar.svg\"\u003e\u003c/a\u003e\n\n\n## License\n[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fjavascript-obfuscator%2Fjavascript-obfuscator.svg?type=large)](https://app.fossa.io/projects/git%2Bgithub.com%2Fjavascript-obfuscator%2Fjavascript-obfuscator?ref=badge_large)\n\nCopyright (C) 2016-2026 [Timofei Kachalov](http://github.com/sanex3339).\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n  * Redistributions of source code must retain the above copyright\n    notice, this list of conditions and the following disclaimer.\n  * Redistributions in binary form must reproduce the above copyright\n    notice, this list of conditions and the following disclaimer in the\n    documentation and/or other materials provided with the distribution.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL \u003cCOPYRIGHT HOLDER\u003e BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\nTHIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n","funding_links":["https://github.com/sponsors/sanex3339","https://opencollective.com/javascript-obfuscator","https://github.com/javascript-obfuscator/javascript-obfuscator#you-can-support-this-project-by-donating","https://opencollective.com/javascript-obfuscator/backer/0/website","https://opencollective.com/javascript-obfuscator/backer/1/website","https://opencollective.com/javascript-obfuscator/backer/2/website","https://opencollective.com/javascript-obfuscator/backer/3/website","https://opencollective.com/javascript-obfuscator/backer/4/website","https://opencollective.com/javascript-obfuscator/backer/5/website","https://opencollective.com/javascript-obfuscator/backer/6/website","https://opencollective.com/javascript-obfuscator/backer/7/website","https://opencollective.com/javascript-obfuscator/backer/8/website","https://opencollective.com/javascript-obfuscator/backer/9/website","https://opencollective.com/javascript-obfuscator/backer/10/website","https://opencollective.com/javascript-obfuscator/backer/11/website","https://opencollective.com/javascript-obfuscator/backer/12/website","https://opencollective.com/javascript-obfuscator/backer/13/website","https://opencollective.com/javascript-obfuscator/backer/14/website","https://opencollective.com/javascript-obfuscator/backer/15/website","https://opencollective.com/javascript-obfuscator/backer/16/website","https://opencollective.com/javascript-obfuscator/backer/17/website","https://opencollective.com/javascript-obfuscator/backer/18/website","https://opencollective.com/javascript-obfuscator/backer/19/website","https://opencollective.com/javascript-obfuscator/backer/20/website","https://opencollective.com/javascript-obfuscator/backer/21/website","https://opencollective.com/javascript-obfuscator/backer/22/website","https://opencollective.com/javascript-obfuscator/backer/23/website","https://opencollective.com/javascript-obfuscator/backer/24/website","https://opencollective.com/javascript-obfuscator/backer/25/website","https://opencollective.com/javascript-obfuscator/backer/26/website","https://opencollective.com/javascript-obfuscator/backer/27/website","https://opencollective.com/javascript-obfuscator/backer/28/website","https://opencollective.com/javascript-obfuscator/backer/29/website"],"categories":["TypeScript","Repository","By Industry","JavaScript框架","Projects","Library","TypeScript (64)","\u003ca id=\"783f861b9f822127dba99acb55687cbb\"\u003e\u003c/a\u003e工具","cryptography","GIT 仓库","typescript","browser","\u003ca name=\"TypeScript\"\u003e\u003c/a\u003eTypeScript","Security"],"sub_categories":["Source Code Obfuscator/Protect","Security","其他_文本生成、文本对话","JavaScript","\u003ca id=\"85bb0c28850ffa2b4fd44f70816db306\"\u003e\u003c/a\u003e混淆器\u0026\u0026Obfuscate","其他","Utility Plugins","Video"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjavascript-obfuscator%2Fjavascript-obfuscator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjavascript-obfuscator%2Fjavascript-obfuscator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjavascript-obfuscator%2Fjavascript-obfuscator/lists"}