diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index a64df512..930f6ca0 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -38,7 +38,7 @@ jobs:
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- - uses: actions/cache@v2
+ - uses: actions/cache@v4
with:
path: '**/node_modules'
key: ${{ runner.os }}-modules-${{ hashFiles('**/yarn.lock') }}
diff --git a/.gitignore b/.gitignore
index b79ba16a..cfe4fd23 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
+.claude
.DS_Store
.idea
.nyc_output
diff --git a/.npmignore b/.npmignore
index 217c0685..d202d73b 100644
--- a/.npmignore
+++ b/.npmignore
@@ -1,4 +1,5 @@
.awcache
+.claude
.github
.idea
.nyc_output
diff --git a/CLAUDE.md b/CLAUDE.md
new file mode 100644
index 00000000..ae03f9f1
--- /dev/null
+++ b/CLAUDE.md
@@ -0,0 +1,1478 @@
+# JavaScript Obfuscator - Project Documentation
+
+## Project Overview
+
+**JavaScript Obfuscator** is a powerful, enterprise-grade code obfuscation tool for JavaScript and Node.js applications. It transforms readable JavaScript code into a protected, difficult-to-understand format while maintaining full functionality. The project is widely used for protecting intellectual property and preventing reverse engineering.
+
+- **Version**: 4.1.1
+- **Author**: Timofey Kachalov (@sanex3339)
+- **License**: BSD-2-Clause
+- **Repository**: https://github.com/javascript-obfuscator/javascript-obfuscator
+- **Homepage**: https://obfuscator.io/
+- **Node Requirement**: >=12.22.0
+
+## Key Features
+
+### Core Obfuscation Techniques
+
+1. **Variable & Function Renaming**: Replaces identifiable names with cryptic hexadecimal or mangled identifiers
+2. **String Extraction & Encryption**: Moves string literals to an encoded array with base64/rc4 encryption
+3. **Dead Code Injection**: Inserts non-functional code blocks to confuse static analysis
+4. **Control Flow Flattening**: Restructures code flow using switch statements to obscure logic
+5. **Code Transformations**: Multiple AST-level transformations including:
+ - Boolean literal obfuscation
+ - Number to expression conversion
+ - Object key transformation
+ - Template literal transformation
+ - Property renaming (safe/unsafe modes)
+
+### Advanced Protection Features
+
+- **Self-Defending Code**: Code that breaks when beautified or modified
+- **Debug Protection**: Anti-debugging mechanisms to prevent DevTools usage
+- **Domain Lock**: Restricts code execution to specific domains/subdomains
+- **Console Output Disabling**: Removes console.* functionality
+- **Unicode Escape Sequences**: Additional string obfuscation layer
+
+## Architecture Overview
+
+### Technology Stack
+
+- **Language**: TypeScript 4.9.5
+- **Parser**: Acorn 8.8.2 (ES3-ES2020 support)
+- **Code Generator**: @javascript-obfuscator/escodegen 2.3.0
+- **AST Traversal**: @javascript-obfuscator/estraverse 5.4.0
+- **DI Framework**: InversifyJS 6.0.1
+- **Testing**: Mocha 10.4.0 + Chai 4.3.7
+- **Build System**: Webpack 5.75.0
+
+### Project Structure
+
+```
+javascript-obfuscator/
+├── src/ # Source code
+│ ├── JavaScriptObfuscator.ts # Main obfuscator class
+│ ├── JavaScriptObfuscatorFacade.ts # Public API facade
+│ ├── JavaScriptObfuscatorCLIFacade.ts # CLI interface
+│ ├── ASTParserFacade.ts # AST parsing wrapper
+│ │
+│ ├── analyzers/ # Code analysis components
+│ │ ├── calls-graph-analyzer/ # Function call graph analysis
+│ │ ├── scope-analyzer/ # Variable scope analysis
+│ │ ├── string-array-storage-analyzer/ # String array optimization
+│ │ ├── number-numerical-expression-analyzer/
+│ │ └── prevailing-kind-of-variables-analyzer/
+│ │
+│ ├── node-transformers/ # AST transformation pipeline
+│ │ ├── AbstractNodeTransformer.ts
+│ │ ├── NodeTransformersRunner.ts
+│ │ ├── converting-transformers/ # Node type conversions
+│ │ ├── control-flow-transformers/ # Control flow flattening
+│ │ ├── dead-code-injection-transformers/ # Dead code generation
+│ │ ├── finalizing-transformers/ # Post-processing transforms
+│ │ ├── initializing-transformers/ # Pre-processing transforms
+│ │ ├── preparing-transformers/ # Preparation phase
+│ │ ├── rename-identifiers-transformers/ # Variable renaming
+│ │ ├── rename-properties-transformers/ # Property renaming
+│ │ ├── simplifying-transformers/ # Code simplification
+│ │ └── string-array-transformers/ # String array handling
+│ │
+│ ├── code-transformers/ # Code-level (not AST) transformers
+│ │ ├── AbstractCodeTransformer.ts
+│ │ ├── CodeTransformersRunner.ts
+│ │ └── CodeTransformerNamesGroupsBuilder.ts
+│ │
+│ ├── custom-code-helpers/ # Injectable code helpers
+│ │ ├── common/ # Global variable templates
+│ │ ├── console-output/ # Console disabling templates
+│ │ ├── debug-protection/ # Anti-debugging templates
+│ │ ├── domain-lock/ # Domain restriction templates
+│ │ ├── self-defending/ # Self-defense templates
+│ │ └── string-array/ # String array wrapper templates
+│ │
+│ ├── custom-nodes/ # Custom AST node generators
+│ │ ├── control-flow-flattening-nodes/
+│ │ ├── dead-code-injection-nodes/
+│ │ ├── object-expression-keys-transformer-nodes/
+│ │ └── string-array-nodes/
+│ │
+│ ├── container/ # Dependency injection
+│ │ ├── InversifyContainerFacade.ts
+│ │ ├── ServiceIdentifiers.ts
+│ │ └── modules/ # DI module definitions
+│ │
+│ ├── options/ # Configuration system
+│ │ ├── Options.ts
+│ │ ├── OptionsNormalizer.ts
+│ │ ├── validators/ # Option validation
+│ │ ├── normalizer-rules/ # Option normalization
+│ │ └── presets/ # Obfuscation presets
+│ │
+│ ├── storages/ # Data storage components
+│ │ ├── string-array-transformers/
+│ │ ├── control-flow-transformers/
+│ │ ├── custom-code-helpers/
+│ │ └── identifier-names-cache/
+│ │
+│ ├── node/ # AST node utilities
+│ │ ├── NodeGuards.ts # Type guards
+│ │ ├── NodeFactory.ts # Node creation
+│ │ ├── NodeAppender.ts # Node insertion
+│ │ ├── NodeStatementUtils.ts
+│ │ └── NodeUtils.ts
+│ │
+│ ├── generators/ # Name/value generators
+│ │ ├── identifier-names-generators/
+│ │ └── string-array-index-nodes-generators/
+│ │
+│ ├── utils/ # Utility functions
+│ │ ├── RandomGenerator.ts
+│ │ ├── ArrayUtils.ts
+│ │ ├── CryptUtils.ts
+│ │ ├── LevelledTopologicalSorter.ts
+│ │ └── Utils.ts
+│ │
+│ ├── cli/ # CLI utilities
+│ │ ├── sanitizers/ # Input sanitizers
+│ │ └── utils/ # File handling
+│ │
+│ ├── enums/ # Enumerations
+│ ├── interfaces/ # TypeScript interfaces
+│ ├── types/ # Type definitions
+│ ├── constants/ # Constants
+│ ├── decorators/ # Decorators
+│ └── logger/ # Logging system
+│
+├── test/ # Test suite
+│ ├── functional-tests/ # Feature tests
+│ ├── unit-tests/ # Unit tests
+│ ├── performance-tests/ # Performance benchmarks
+│ └── index.spec.ts
+│
+├── webpack/ # Build configurations
+│ ├── webpack.node.config.js
+│ └── webpack.browser.config.js
+│
+├── dist/ # Compiled output
+│ ├── index.js # Node.js bundle
+│ └── index.browser.js # Browser bundle
+│
+├── bin/ # CLI executable
+│ └── javascript-obfuscator
+│
+└── typings/ # TypeScript declarations
+```
+
+## Core Workflow
+
+### Obfuscation Pipeline
+
+The obfuscation process follows a multi-stage pipeline defined in `JavaScriptObfuscator.ts`:
+
+```
+1. Code Transformation Stage: PreparingTransformers
+ └─> Raw code preprocessing (e.g., hashbang handling)
+
+2. AST Parsing
+ └─> Parse source code into ESTree-compliant AST using Acorn
+
+3. Node Transformation Stages (sequential):
+ ├─> Initializing
+ │ └─> Initial AST setup, parentification, metadata
+ ├─> Preparing
+ │ └─> Scope analysis, obfuscating guards, identifier collection
+ ├─> DeadCodeInjection (optional)
+ │ └─> Insert dead code blocks
+ ├─> ControlFlowFlattening (optional)
+ │ └─> Flatten control flow with switch statements
+ ├─> RenameProperties (optional)
+ │ └─> Rename object properties
+ ├─> Converting
+ │ └─> Transform nodes (literals, expressions, etc.)
+ ├─> RenameIdentifiers
+ │ └─> Rename variables and functions
+ ├─> StringArray
+ │ └─> Extract strings to array, add wrappers
+ ├─> Simplifying (optional)
+ │ └─> Simplify and merge statements
+ └─> Finalizing
+ └─> Final cleanup, directive placement
+
+4. Code Generation
+ └─> Generate obfuscated code using escodegen
+
+5. Code Transformation Stage: FinalizingTransformers
+ └─> Post-processing on generated code
+
+6. Source Map Generation (optional)
+ └─> Create source maps for debugging
+```
+
+### Dependency Injection Architecture
+
+The project uses **InversifyJS** for dependency injection, providing:
+
+- **Modularity**: Clean separation of concerns
+- **Testability**: Easy mocking and testing
+- **Flexibility**: Runtime configuration of transformers
+- **Scalability**: Easy addition of new transformers
+
+All components are registered in container modules located in `src/container/modules/`.
+
+## Key Components Deep Dive
+
+### 1. JavaScriptObfuscator (Main Engine)
+
+**Location**: `src/JavaScriptObfuscator.ts`
+
+The core orchestrator that:
+- Manages the complete obfuscation pipeline
+- Coordinates code and node transformers
+- Handles AST parsing and code generation
+- Integrates with logger and random generator
+
+**Key Methods**:
+- `obfuscate(sourceCode: string): IObfuscationResult` - Main entry point
+- `parseCode()` - AST parsing with Acorn
+- `transformAstTree()` - Applies transformation stages
+- `generateCode()` - Code generation with escodegen
+
+### 2. Node Transformers
+
+**Location**: `src/node-transformers/`
+
+Each transformer implements `INodeTransformer` interface with:
+- `getVisitor(stage): IVisitor | null` - Returns visitor for specific stage
+- `transformNode(node, parent): Node` - Transforms individual AST node
+
+**Key Transformers**:
+
+- **StringArrayTransformer**: Extracts string literals to centralized array
+- **BooleanLiteralTransformer**: Converts true/false to `!![]` and `![]`
+- **NumberToNumericalExpressionTransformer**: Converts numbers to expressions
+- **BlockStatementControlFlowTransformer**: Implements control flow flattening
+- **DeadCodeInjectionTransformer**: Injects dead code blocks
+- **RenamePropertiesTransformer**: Renames object properties
+- **ScopeIdentifiersTransformer**: Renames variables based on scope
+
+### 3. Analyzers
+
+**Location**: `src/analyzers/`
+
+- **CallsGraphAnalyzer**: Builds function call dependency graph
+- **ScopeAnalyzer**: Analyzes variable scopes using eslint-scope
+- **StringArrayStorageAnalyzer**: Optimizes string array storage
+- **PrevailingKindOfVariablesAnalyzer**: Determines var/let/const usage
+- **NumberNumericalExpressionAnalyzer**: Analyzes numeric expressions
+
+### 4. Custom Code Helpers
+
+**Location**: `src/custom-code-helpers/`
+
+Injectable runtime helpers that provide:
+- **String Array Decoders**: Base64/RC4 decoding functions
+- **Debug Protection**: Anti-debugging wrapper code
+- **Domain Lock**: Domain validation code
+- **Self-Defending**: Code integrity checks
+- **Console Output Disable**: Console method replacements
+
+### 5. Options System
+
+**Location**: `src/options/`
+
+Sophisticated configuration system with:
+- **Validation**: Using class-validator decorators
+- **Normalization**: Automatic option interdependency handling
+- **Presets**: Default, low, medium, and high obfuscation presets
+- **Type Safety**: Full TypeScript support
+
+**Key Option Categories**:
+- Code output (compact, target)
+- String transformations (stringArray*, splitStrings)
+- Control flow (controlFlowFlattening, deadCodeInjection)
+- Naming (identifierNamesGenerator, renameGlobals, renameProperties)
+- Protection (selfDefending, debugProtection, domainLock)
+- Advanced (numbersToExpressions, simplify, transformObjectKeys)
+
+## Important Patterns and Conventions
+
+### 1. Visitor Pattern
+
+Transformers use the visitor pattern for AST traversal:
+
+```typescript
+interface IVisitor {
+ enter?: (node: Node, parent: Node) => Node | VisitorOption;
+ leave?: (node: Node, parent: Node) => Node | VisitorOption;
+}
+```
+
+### 2. Initializable Pattern
+
+Many components implement `IInitializable` for lazy initialization:
+
+```typescript
+interface IInitializable {
+ initialize(...args: any[]): void;
+}
+```
+
+Managed via `@Initializable()` decorator.
+
+### 3. Stage-Based Processing
+
+Both code and node transformers operate in stages:
+
+**Code Transformation Stages**:
+- PreparingTransformers
+- FinalizingTransformers
+
+**Node Transformation Stages**:
+- Initializing
+- Preparing
+- DeadCodeInjection
+- ControlFlowFlattening
+- RenameProperties
+- Converting
+- RenameIdentifiers
+- StringArray
+- Simplifying
+- Finalizing
+
+### 4. Factory Pattern
+
+Extensive use of factories for object creation:
+- `TObfuscationResultFactory`
+- Custom node factories
+- Identifier name generators
+
+### 5. Storage Pattern
+
+Centralized storages for shared data:
+- String array storage
+- Custom code helpers storage
+- Identifier names cache storage
+- Control flow transformers storage
+
+## CLI Usage
+
+**Location**: `bin/javascript-obfuscator`, `src/JavaScriptObfuscatorCLIFacade.ts`
+
+### Basic Commands
+
+```bash
+# Obfuscate single file
+javascript-obfuscator input.js --output output.js
+
+# Obfuscate directory
+javascript-obfuscator ./src --output ./dist
+
+# Use configuration file
+javascript-obfuscator input.js --config config.json
+
+# High obfuscation preset
+javascript-obfuscator input.js --options-preset high-obfuscation
+```
+
+### CLI Features
+
+- Automatic identifier prefix for multiple files
+- Glob pattern exclusions
+- Source map support
+- Identifier names cache (cross-file consistency)
+- Progress logging
+
+## API Usage
+
+### Basic Obfuscation
+
+```javascript
+const JavaScriptObfuscator = require('javascript-obfuscator');
+
+const obfuscationResult = JavaScriptObfuscator.obfuscate(
+ `
+ var foo = 'Hello World';
+ console.log(foo);
+ `,
+ {
+ compact: true,
+ controlFlowFlattening: true
+ }
+);
+
+console.log(obfuscationResult.getObfuscatedCode());
+console.log(obfuscationResult.getSourceMap());
+console.log(obfuscationResult.getIdentifierNamesCache());
+```
+
+### Multiple Files
+
+```javascript
+const sourceCodesObject = {
+ 'file1.js': 'var foo = 1;',
+ 'file2.js': 'var bar = 2;'
+};
+
+const obfuscationResults = JavaScriptObfuscator.obfuscateMultiple(
+ sourceCodesObject,
+ options
+);
+```
+
+### Identifier Names Cache (Cross-File Consistency)
+
+```javascript
+// First file
+const result1 = JavaScriptObfuscator.obfuscate(code1, {
+ identifierNamesCache: {},
+ renameGlobals: true
+});
+const cache = result1.getIdentifierNamesCache();
+
+// Second file using same cache
+const result2 = JavaScriptObfuscator.obfuscate(code2, {
+ identifierNamesCache: cache,
+ renameGlobals: true
+});
+```
+
+## Browser Support
+
+The project includes a browser build at `dist/index.browser.js` that can be used in web environments:
+
+```html
+
+
+```
+
+**Note**: No eval() in `browser-no-eval` target.
+
+## Build System
+
+### Webpack Configuration
+
+- **Node.js build**: `webpack/webpack.node.config.js`
+ - Target: CommonJS module
+ - External dependencies: node_modules
+ - Output: `dist/index.js`
+
+- **Browser build**: `webpack/webpack.browser.config.js`
+ - Target: UMD module
+ - Bundled dependencies
+ - Output: `dist/index.browser.js`
+
+### Build Scripts
+
+```bash
+# Production build
+npm run build
+
+# Development watch mode
+npm run watch
+
+# Build TypeScript typings
+npm run build:typings
+
+# Linting
+npm run eslint
+```
+
+## Testing
+
+### Test Structure
+
+**Location**: `test/`
+
+- **Functional tests**: Feature-level tests for transformers and options
+- **Unit tests**: Component-level tests
+- **Performance tests**: Memory and speed benchmarks
+
+### Running Tests
+
+#### Quick Start
+
+```bash
+# Install dependencies first
+npm install
+# or
+yarn install
+
+# Run all tests (includes dev test, coverage, and memory performance)
+npm test
+# or
+yarn test
+```
+
+#### Individual Test Commands
+
+```bash
+# Run full test suite (test:dev + test:mocha-coverage + test:mocha-memory-performance). This is slow.
+npm run test:full
+yarn run test:full
+
+# Run Mocha tests only (no coverage)
+npm run test:mocha
+yarn run test:mocha
+
+# Run tests with coverage report
+npm run test:mocha-coverage
+yarn run test:mocha-coverage
+
+# Generate detailed coverage report (after running test:mocha-coverage)
+npm run test:mocha-coverage:report
+yarn run test:mocha-coverage:report
+
+# Run memory performance tests (tests memory constraints)
+npm run test:mocha-memory-performance
+yarn run test:mocha-memory-performance
+
+# Run development test (custom dev test file)
+npm run test:dev
+yarn run test:dev
+
+# Run compile performance test
+npm run test:devCompilePerformance
+yarn run test:devCompilePerformance
+
+# Run runtime performance test
+npm run test:devRuntimePerformance
+yarn run test:devRuntimePerformance
+```
+
+#### Test Details
+
+**test:full**
+- Runs the complete test suite
+- Includes: development tests, coverage tests, and memory performance tests
+- This is what runs when you execute `npm test`
+
+**test:mocha**
+- Runs all Mocha tests from `test/index.spec.ts`
+- Uses ts-node for TypeScript execution
+- No code coverage reporting
+
+**test:mocha-coverage**
+- Runs Mocha tests with NYC (Istanbul) code coverage
+- Allocates up to 4GB memory (`--max-old-space-size=4096`)
+- Generates coverage reports (text-summary by default)
+- Use `test:mocha-coverage:report` to generate detailed lcov report
+
+**test:mocha-memory-performance**
+- Tests obfuscator memory usage under constraints
+- Allocates only 280MB memory to test memory efficiency
+- Located at: `test/performance-tests/JavaScriptObfuscatorMemory.spec.ts`
+
+**test:dev**
+- Custom development test script
+- Located at: `test/dev/dev.ts`
+- Useful for quick testing during development
+
+### Test Configuration Files
+
+- **`.mocharc.json`**: Mocha test runner configuration
+- **`.nycrc.json`**: NYC (Istanbul) coverage tool configuration
+- **TypeScript**: Uses ts-node for direct TS execution without compilation
+
+### Running Specific Test Files
+
+You can run individual test files or groups of tests for faster iteration during development.
+
+#### Basic Command Format
+
+```bash
+npx mocha --require ts-node/register --require source-map-support/register
+```
+
+#### Common Examples
+
+```bash
+# Run a specific test file by exact path
+npx mocha --require ts-node/register --require source-map-support/register test/functional-tests/options/Options.spec.ts
+
+# Run CLI tests
+npx mocha --require ts-node/register --require source-map-support/register test/functional-tests/cli/JavaScriptObfuscatorCLI.spec.ts
+
+# Run a specific analyzer test
+npx mocha --require ts-node/register --require source-map-support/register test/functional-tests/analyzers/calls-graph-analyzer/CallsGraphAnalyzer.spec.ts
+
+# Run scope analyzer tests
+npx mocha --require ts-node/register --require source-map-support/register test/functional-tests/analyzers/scope-analyzer/ScopeAnalyzer.spec.ts
+
+# Run string array tests
+npx mocha --require ts-node/register --require source-map-support/register test/functional-tests/custom-code-helpers/string-array/StringArrayCodeHelper.spec.ts
+
+# Run self-defending code tests
+npx mocha --require ts-node/register --require source-map-support/register test/functional-tests/custom-code-helpers/self-defending/SelfDefendingCodeHelper.spec.ts
+```
+
+#### Pattern Matching
+
+Use glob patterns to run multiple related test files:
+
+```bash
+# Run all options-related tests
+npx mocha --require ts-node/register --require source-map-support/register "test/functional-tests/options/**/*.spec.ts"
+
+# Run all analyzer tests
+npx mocha --require ts-node/register --require source-map-support/register "test/functional-tests/analyzers/**/*.spec.ts"
+
+# Run all string array related tests
+npx mocha --require ts-node/register --require source-map-support/register "test/functional-tests/**/*StringArray*.spec.ts"
+
+# Run all control flow tests
+npx mocha --require ts-node/register --require source-map-support/register "test/functional-tests/**/*ControlFlow*.spec.ts"
+
+# Run all node transformer tests
+npx mocha --require ts-node/register --require source-map-support/register "test/functional-tests/node-transformers/**/*.spec.ts"
+
+# Run all unit tests only
+npx mocha --require ts-node/register --require source-map-support/register "test/unit-tests/**/*.spec.ts"
+
+# Run all functional tests only
+npx mocha --require ts-node/register --require source-map-support/register "test/functional-tests/**/*.spec.ts"
+```
+
+#### Running Tests by Category
+
+The test suite is organized into these main categories:
+
+**Functional Tests** (`test/functional-tests/`):
+```bash
+# Options tests
+npx mocha --require ts-node/register --require source-map-support/register "test/functional-tests/options/**/*.spec.ts"
+
+# Analyzers tests
+npx mocha --require ts-node/register --require source-map-support/register "test/functional-tests/analyzers/**/*.spec.ts"
+
+# Node transformers tests
+npx mocha --require ts-node/register --require source-map-support/register "test/functional-tests/node-transformers/**/*.spec.ts"
+
+# Code transformers tests
+npx mocha --require ts-node/register --require source-map-support/register "test/functional-tests/code-transformers/**/*.spec.ts"
+
+# Custom code helpers tests
+npx mocha --require ts-node/register --require source-map-support/register "test/functional-tests/custom-code-helpers/**/*.spec.ts"
+
+# Storage tests
+npx mocha --require ts-node/register --require source-map-support/register "test/functional-tests/storages/**/*.spec.ts"
+
+# CLI tests
+npx mocha --require ts-node/register --require source-map-support/register "test/functional-tests/cli/**/*.spec.ts"
+
+# Generator tests
+npx mocha --require ts-node/register --require source-map-support/register "test/functional-tests/generators/**/*.spec.ts"
+
+# Main obfuscator tests
+npx mocha --require ts-node/register --require source-map-support/register "test/functional-tests/javascript-obfuscator/**/*.spec.ts"
+
+# Issue regression tests
+npx mocha --require ts-node/register --require source-map-support/register "test/functional-tests/issues/**/*.spec.ts"
+```
+
+**Unit Tests** (`test/unit-tests/`):
+```bash
+# All unit tests
+npx mocha --require ts-node/register --require source-map-support/register "test/unit-tests/**/*.spec.ts"
+
+# Options unit tests
+npx mocha --require ts-node/register --require source-map-support/register "test/unit-tests/options/**/*.spec.ts"
+
+# Utils unit tests
+npx mocha --require ts-node/register --require source-map-support/register "test/unit-tests/utils/**/*.spec.ts"
+
+# Node utilities unit tests
+npx mocha --require ts-node/register --require source-map-support/register "test/unit-tests/node/**/*.spec.ts"
+```
+
+**Performance Tests** (`test/performance-tests/`):
+```bash
+# Memory performance tests
+npx mocha --require ts-node/register --require source-map-support/register test/performance-tests/JavaScriptObfuscatorMemory.spec.ts
+```
+
+#### Using Mocha Options with Individual Tests
+
+```bash
+# Run with grep to filter by test description
+npx mocha --require ts-node/register --require source-map-support/register test/functional-tests/options/Options.spec.ts --grep "compact"
+
+# Run and show slow tests
+npx mocha --require ts-node/register --require source-map-support/register test/functional-tests/options/Options.spec.ts --reporter spec
+
+# Run with timeout override (default is 10000ms)
+npx mocha --require ts-node/register --require source-map-support/register test/functional-tests/options/Options.spec.ts --timeout 20000
+
+# Run with bail (stop on first failure)
+npx mocha --require ts-node/register --require source-map-support/register "test/functional-tests/**/*.spec.ts" --bail
+
+# Run and watch for changes
+npx mocha --require ts-node/register --require source-map-support/register test/functional-tests/options/Options.spec.ts --watch
+
+# Run with specific reporter
+npx mocha --require ts-node/register --require source-map-support/register test/functional-tests/options/Options.spec.ts --reporter json
+```
+
+#### Creating Test Aliases (Optional)
+
+For convenience, you can add these aliases to your `package.json` scripts:
+
+```json
+{
+ "scripts": {
+ "test:options": "mocha --require ts-node/register --require source-map-support/register 'test/functional-tests/options/**/*.spec.ts'",
+ "test:analyzers": "mocha --require ts-node/register --require source-map-support/register 'test/functional-tests/analyzers/**/*.spec.ts'",
+ "test:transformers": "mocha --require ts-node/register --require source-map-support/register 'test/functional-tests/node-transformers/**/*.spec.ts'",
+ "test:unit": "mocha --require ts-node/register --require source-map-support/register 'test/unit-tests/**/*.spec.ts'",
+ "test:functional": "mocha --require ts-node/register --require source-map-support/register 'test/functional-tests/**/*.spec.ts'"
+ }
+}
+```
+
+Then run with:
+```bash
+npm run test:options
+npm run test:analyzers
+npm run test:transformers
+```
+
+#### Tips for Running Individual Tests
+
+1. **Use quotes around glob patterns** to prevent shell expansion:
+ ```bash
+ # Good
+ npx mocha "test/**/*.spec.ts"
+
+ # Bad (shell will expand the pattern)
+ npx mocha test/**/*.spec.ts
+ ```
+
+2. **Use --grep to run specific test cases** within a file:
+ ```bash
+ npx mocha --require ts-node/register test/functional-tests/options/Options.spec.ts --grep "should enable compact"
+ ```
+
+3. **Use --bail to stop on first failure** when debugging:
+ ```bash
+ npx mocha --require ts-node/register "test/**/*.spec.ts" --bail
+ ```
+
+4. **Check the exit code** to verify test success in scripts:
+ ```bash
+ npx mocha --require ts-node/register test/functional-tests/options/Options.spec.ts && echo "Tests passed!"
+ ```
+
+5. **Combine with watch mode** for TDD workflow:
+ ```bash
+ npx mocha --require ts-node/register test/functional-tests/options/Options.spec.ts --watch --reporter min
+ ```
+
+## Linting
+
+### Running ESLint
+
+#### Quick Start
+
+```bash
+# Lint all TypeScript files in src/
+npm run eslint
+yarn run eslint
+```
+
+This runs: `eslint src/**/*.ts`
+
+#### Linting Individual Files
+
+You can lint specific files or directories for faster feedback during development.
+
+**Basic Command Format:**
+```bash
+npx eslint
+```
+
+**Common Examples:**
+
+```bash
+# Lint a specific file
+npx eslint src/JavaScriptObfuscator.ts
+
+# Lint the main facade file
+npx eslint src/JavaScriptObfuscatorFacade.ts
+
+# Lint a specific transformer
+npx eslint src/node-transformers/converting-transformers/StringArrayTransformer.ts
+
+# Lint a specific analyzer
+npx eslint src/analyzers/calls-graph-analyzer/CallsGraphAnalyzer.ts
+
+# Lint options file
+npx eslint src/options/Options.ts
+
+# Lint a custom code helper
+npx eslint src/custom-code-helpers/string-array/StringArrayCodeHelper.ts
+
+# Lint container files
+npx eslint src/container/InversifyContainerFacade.ts
+```
+
+#### Linting Multiple Files or Directories
+
+```bash
+# Lint entire src directory
+npx eslint src/
+
+# Lint all files in a specific subdirectory
+npx eslint src/node-transformers/
+
+# Lint all analyzers
+npx eslint src/analyzers/
+
+# Lint all transformers
+npx eslint src/node-transformers/**/*.ts
+
+# Lint all options-related files
+npx eslint src/options/
+
+# Lint all custom code helpers
+npx eslint src/custom-code-helpers/
+
+# Lint all utils
+npx eslint src/utils/
+
+# Lint CLI files
+npx eslint src/cli/
+
+# Lint container modules
+npx eslint src/container/
+
+# Lint storage files
+npx eslint src/storages/
+```
+
+#### Using Glob Patterns
+
+```bash
+# Lint all TypeScript files in src (same as npm run eslint)
+npx eslint "src/**/*.ts"
+
+# Lint all transformer files
+npx eslint "src/**/*Transformer.ts"
+
+# Lint all analyzer files
+npx eslint "src/**/*Analyzer.ts"
+
+# Lint all storage files
+npx eslint "src/**/*Storage.ts"
+
+# Lint all helper files
+npx eslint "src/**/*Helper.ts"
+
+# Lint all files containing "String" in the name
+npx eslint "src/**/*String*.ts"
+
+# Lint all files in node-transformers subdirectories
+npx eslint "src/node-transformers/**/*.ts"
+```
+
+#### Auto-fixing Issues
+
+ESLint can automatically fix many issues:
+
+```bash
+# Auto-fix all files in src/
+npx eslint src/**/*.ts --fix
+
+# Auto-fix a specific file
+npx eslint src/JavaScriptObfuscator.ts --fix
+
+# Auto-fix specific directory
+npx eslint src/node-transformers/ --fix
+
+# Auto-fix with glob pattern
+npx eslint "src/analyzers/**/*.ts" --fix
+
+# Auto-fix only safe fixes (no potentially breaking changes)
+npx eslint src/JavaScriptObfuscator.ts --fix --fix-type suggestion,layout
+```
+
+#### Checking Specific Rules
+
+```bash
+# Show only errors (no warnings)
+npx eslint src/JavaScriptObfuscator.ts --quiet
+
+# Check specific rule only
+npx eslint src/JavaScriptObfuscator.ts --rule 'no-console: error'
+
+# Disable specific rules for a file check
+npx eslint src/JavaScriptObfuscator.ts --rule 'no-console: off'
+
+# Output format options
+npx eslint src/JavaScriptObfuscator.ts --format stylish # Default
+npx eslint src/JavaScriptObfuscator.ts --format json # JSON output
+npx eslint src/JavaScriptObfuscator.ts --format compact # Compact output
+npx eslint src/JavaScriptObfuscator.ts --format unix # Unix style
+```
+
+#### Getting Detailed Information
+
+```bash
+# Show more details about errors
+npx eslint src/JavaScriptObfuscator.ts --format stylish
+
+# List all files that would be linted (dry-run)
+npx eslint src/ --debug 2>&1 | grep "Processing"
+
+# Show timing information for rules
+npx eslint src/JavaScriptObfuscator.ts --debug
+
+# Get statistics about linting
+npx eslint src/ --format json | jq '.[] | {file: .filePath, errors: .errorCount, warnings: .warningCount}'
+```
+
+#### Linting by Component
+
+Organized by project structure:
+
+**Core Files:**
+```bash
+npx eslint src/JavaScriptObfuscator.ts
+npx eslint src/JavaScriptObfuscatorFacade.ts
+npx eslint src/ASTParserFacade.ts
+```
+
+**Node Transformers:**
+```bash
+# All node transformers
+npx eslint src/node-transformers/
+
+# Converting transformers
+npx eslint src/node-transformers/converting-transformers/
+
+# Control flow transformers
+npx eslint src/node-transformers/control-flow-transformers/
+
+# String array transformers
+npx eslint src/node-transformers/string-array-transformers/
+
+# Rename transformers
+npx eslint src/node-transformers/rename-identifiers-transformers/
+npx eslint src/node-transformers/rename-properties-transformers/
+```
+
+**Analyzers:**
+```bash
+# All analyzers
+npx eslint src/analyzers/
+
+# Specific analyzers
+npx eslint src/analyzers/calls-graph-analyzer/
+npx eslint src/analyzers/scope-analyzer/
+npx eslint src/analyzers/string-array-storage-analyzer/
+```
+
+**Options System:**
+```bash
+# All options files
+npx eslint src/options/
+
+# Core options
+npx eslint src/options/Options.ts
+npx eslint src/options/OptionsNormalizer.ts
+
+# Validators
+npx eslint src/options/validators/
+
+# Presets
+npx eslint src/options/presets/
+```
+
+**Custom Code Helpers:**
+```bash
+# All helpers
+npx eslint src/custom-code-helpers/
+
+# String array helpers
+npx eslint src/custom-code-helpers/string-array/
+
+# Debug protection helpers
+npx eslint src/custom-code-helpers/debug-protection/
+
+# Self-defending helpers
+npx eslint src/custom-code-helpers/self-defending/
+```
+
+**Utilities:**
+```bash
+# All utils
+npx eslint src/utils/
+
+# Specific utils
+npx eslint src/utils/RandomGenerator.ts
+npx eslint src/utils/ArrayUtils.ts
+npx eslint src/utils/CryptUtils.ts
+```
+
+#### Integrating with Git
+
+```bash
+# Lint only staged files (useful for pre-commit)
+git diff --cached --name-only --diff-filter=ACM | grep '\.ts$' | xargs npx eslint
+
+# Lint files changed in current branch
+git diff --name-only master | grep '\.ts$' | xargs npx eslint
+
+# Lint files changed in last commit
+git diff HEAD~1 --name-only | grep '\.ts$' | xargs npx eslint
+```
+
+#### Creating Lint Aliases (Optional)
+
+Add these to your `package.json` scripts for convenience:
+
+```json
+{
+ "scripts": {
+ "lint": "eslint src/**/*.ts",
+ "lint:fix": "eslint src/**/*.ts --fix",
+ "lint:transformers": "eslint src/node-transformers/**/*.ts",
+ "lint:analyzers": "eslint src/analyzers/**/*.ts",
+ "lint:options": "eslint src/options/**/*.ts",
+ "lint:utils": "eslint src/utils/**/*.ts",
+ "lint:quiet": "eslint src/**/*.ts --quiet",
+ "lint:staged": "git diff --cached --name-only --diff-filter=ACM | grep '\\.ts$' | xargs eslint"
+ }
+}
+```
+
+Then run with:
+```bash
+npm run lint:transformers
+npm run lint:analyzers
+npm run lint:fix
+```
+
+### ESLint Configuration
+
+**Location**: `.eslintrc.js`
+
+The project uses:
+- **@typescript-eslint**: TypeScript-specific linting rules
+- **eslint-plugin-import**: Import/export validation
+- **eslint-plugin-jsdoc**: JSDoc comment validation
+- **eslint-plugin-no-null**: Prevents null usage (prefer undefined)
+- **eslint-plugin-prefer-arrow**: Enforces arrow functions
+- **eslint-plugin-unicorn**: Additional code quality rules
+
+**Ignored files**: `.eslintignore`
+
+#### Viewing Current ESLint Config
+
+```bash
+# Print effective configuration for a file
+npx eslint --print-config src/JavaScriptObfuscator.ts
+
+# List all rules being applied
+npx eslint --print-config src/JavaScriptObfuscator.ts | grep rules -A 1000
+```
+
+### Code Quality Checks
+
+```bash
+# Run full build (includes webpack, eslint, and tests)
+npm run build
+yarn run build
+
+# The build script runs:
+# 1. webpack:prod (production build)
+# 2. eslint (linting)
+# 3. test (full test suite)
+```
+
+### Tips for Effective Linting
+
+1. **Lint before committing**: Always run linting before creating commits
+ ```bash
+ npx eslint src/ && git commit -m "Your message"
+ ```
+
+2. **Use --fix cautiously**: Review changes before committing auto-fixes
+ ```bash
+ npx eslint src/MyFile.ts --fix
+ git diff # Review changes
+ ```
+
+3. **Focus on errors first**: Use `--quiet` to see only errors
+ ```bash
+ npx eslint src/ --quiet
+ ```
+
+4. **Lint specific files during development**: Don't lint everything when working on one file
+ ```bash
+ npx eslint src/node-transformers/MyNewTransformer.ts
+ ```
+
+5. **Check exit code**: Useful in scripts and CI/CD
+ ```bash
+ npx eslint src/ || echo "Linting failed!"
+ ```
+
+## Development Workflow
+
+### Setting Up Development Environment
+
+```bash
+# 1. Clone the repository
+git clone https://github.com/javascript-obfuscator/javascript-obfuscator.git
+cd javascript-obfuscator
+
+# 2. Install dependencies
+npm install
+# or
+yarn install
+
+# 3. Install Husky hooks (for pre-commit checks)
+npm run prepare
+# or
+yarn run prepare
+```
+
+### Development Commands
+
+```bash
+# Start development mode with watch (auto-recompile on changes)
+npm start
+# or
+npm run watch
+# or
+yarn run watch
+
+# Build for production
+npm run webpack:prod
+yarn run webpack:prod
+
+# Build TypeScript type definitions
+npm run build:typings
+yarn run build:typings
+
+# Full build (webpack + eslint + tests)
+npm run build
+yarn run build
+```
+
+### Pre-commit Hooks
+
+The project uses **Husky** for git hooks:
+
+- **pre-commit**: Automatically runs `npm run build` before each commit
+ - Ensures code compiles
+ - Ensures linting passes
+ - Ensures all tests pass
+
+**Configuration**: `.husky/` directory
+
+### Development Tips
+
+1. **Use watch mode during development**:
+ ```bash
+ npm run watch
+ ```
+ This rebuilds automatically when you save files.
+
+2. **Run specific tests during development**:
+ ```bash
+ npm run test:dev
+ ```
+ Faster than full test suite.
+
+3. **Check linting before committing**:
+ ```bash
+ npm run eslint
+ ```
+ Fix issues before the pre-commit hook runs.
+
+4. **Test memory usage**:
+ ```bash
+ npm run test:mocha-memory-performance
+ ```
+ Ensure your changes don't cause memory issues.
+
+5. **Generate coverage reports**:
+ ```bash
+ npm run test:mocha-coverage
+ npm run test:mocha-coverage:report
+ ```
+ Check test coverage in the generated `coverage/` directory.
+
+## Performance Considerations
+
+### Impact on Code Size
+
+- **Default**: ~15-30% increase
+- **Dead Code Injection**: Up to 200% increase
+- **String Array**: 20-50% increase
+- **Control Flow Flattening**: 30-80% increase
+
+### Runtime Performance
+
+- **No obfuscation**: Baseline
+- **Low preset**: ~10-20% slower
+- **Medium preset**: ~30-50% slower
+- **High preset**: ~50-80% slower
+
+### Optimization Tips
+
+1. Use **thresholds** to apply transformations selectively:
+ - `controlFlowFlatteningThreshold`
+ - `deadCodeInjectionThreshold`
+ - `stringArrayThreshold`
+
+2. Avoid obfuscating:
+ - Third-party libraries
+ - Polyfills
+ - Large vendor bundles
+
+3. Use **seed** option for reproducible builds
+
+4. Enable **simplify** for better performance (enabled by default)
+
+## Security Considerations
+
+### What It Protects
+
+- Makes reverse engineering harder
+- Prevents casual code inspection
+- Protects string literals and algorithms
+- Adds anti-debugging measures
+- Can lock code to specific domains
+
+### What It Doesn't Protect
+
+- Determined attackers with time and tools
+- Network traffic and API endpoints
+- Runtime behavior analysis
+- Secrets embedded in code (use environment variables!)
+
+### Best Practices
+
+1. **Never obfuscate secrets**: Use environment variables or secure vaults
+2. **Combine with other protections**: Minification, HTTPS, CSP headers
+3. **Test thoroughly**: Obfuscation can introduce subtle bugs
+4. **Monitor performance**: High obfuscation impacts runtime speed
+5. **Use source maps carefully**: Keep them private for debugging
+
+## Conditional Comments
+
+Control obfuscation for specific code sections:
+
+```javascript
+var foo = 1;
+// javascript-obfuscator:disable
+var bar = 2; // This won't be obfuscated
+// javascript-obfuscator:enable
+var baz = 3;
+```
+
+## Integration with Build Tools
+
+### Webpack
+
+Use [webpack-obfuscator](https://github.com/javascript-obfuscator/webpack-obfuscator) plugin
+
+### Gulp
+
+Use [gulp-javascript-obfuscator](https://github.com/javascript-obfuscator/gulp-javascript-obfuscator)
+
+### Rollup
+
+Use [rollup-plugin-javascript-obfuscator](https://github.com/javascript-obfuscator/rollup-plugin-javascript-obfuscator)
+
+### Grunt
+
+Use [grunt-contrib-obfuscator](https://github.com/javascript-obfuscator/grunt-contrib-obfuscator)
+
+## Common Issues and Solutions
+
+### Issue: Code breaks after obfuscation
+
+**Solutions**:
+- Add function/variable names to `reservedNames`
+- Add strings to `reservedStrings`
+- Use `renamePropertiesMode: 'safe'` instead of 'unsafe'
+- Disable `renameProperties` if safe mode doesn't work
+- Check for dynamic property access like `obj[dynamicKey]`
+
+### Issue: Performance is too slow
+
+**Solutions**:
+- Use lower obfuscation preset
+- Reduce threshold values
+- Disable `controlFlowFlattening` and `deadCodeInjection`
+- Use `target: 'browser-no-eval'` if applicable
+
+### Issue: Code size is too large
+
+**Solutions**:
+- Disable `deadCodeInjection`
+- Reduce `stringArrayWrappersCount`
+- Use lower `stringArrayThreshold`
+- Disable `unicodeEscapeSequence`
+
+### Issue: Source maps not working
+
+**Solutions**:
+- Ensure `sourceMap: true` in options
+- Set correct `sourceMapMode` ('inline' or 'separate')
+- Specify `inputFileName` when using NodeJS API
+- Use `sourceMapSourcesMode: 'sources-content'` for embedded source
+
+### Issue: Domain lock not working
+
+**Solutions**:
+- Don't use with `target: 'node'`
+- Test in actual browser environment
+- Check domain format (`.example.com` for all subdomains)
+- Ensure `domainLockRedirectUrl` is set
+
+## Extension Points
+
+### Adding Custom Transformers
+
+1. Create transformer class extending `AbstractNodeTransformer`
+2. Implement `getVisitor()` and `transformNode()` methods
+3. Register in appropriate module (`src/container/modules/node-transformers/`)
+4. Add to transformer list in `JavaScriptObfuscator.ts`
+5. Add to `NodeTransformer` enum
+
+### Adding Custom Options
+
+1. Add property to `IOptions` interface
+2. Add validation decorator in `Options.ts`
+3. Add normalizer rule if needed in `options/normalizer-rules/`
+4. Add preset values if applicable
+
+### Adding Custom Code Helpers
+
+1. Create helper group extending `AbstractCustomCodeHelperGroup`
+2. Create template files in `custom-code-helpers/[group]/templates/`
+3. Register in `CustomCodeHelpersModule`
+4. Add to `CustomCodeHelper` enum
+
+## TypeScript Configuration
+
+### Main Config
+
+**Location**: `tsconfig.json`
+
+- **Target**: ES2018
+- **Module**: CommonJS
+- **Strict mode**: Enabled
+- **Decorators**: Enabled (experimental)
+- **Emit decorator metadata**: Enabled
+
+### Special Configs
+
+- `tsconfig.browser.json`: Browser-specific settings
+- `tsconfig.node.json`: Node.js-specific settings
+- `tsconfig.typings.json`: Type declarations generation
+
+## Dependencies Overview
+
+### Production Dependencies
+
+- **@javascript-obfuscator/escodegen**: Modified escodegen for code generation
+- **@javascript-obfuscator/estraverse**: Modified estraverse for AST traversal
+- **acorn**: JavaScript parser (ES3-ES2020)
+- **inversify**: Dependency injection container
+- **eslint-scope**: Scope analysis (from ESLint)
+- **class-validator**: Options validation
+- **chance**: Random data generation
+- **commander**: CLI argument parsing
+- **chalk**: Terminal colors
+- **md5**: Hashing for identifiers
+
+### Development Dependencies
+
+- **TypeScript**: Type system and compiler
+- **Webpack**: Module bundler
+- **Mocha + Chai**: Testing framework
+- **NYC**: Code coverage
+- **ESLint**: Code linting
+- **Sinon**: Test mocking
+
+## Contributing
+
+**Location**: `CONTRIBUTING.md`, `CODE_OF_CONDUCT.md`
+
+1. Fork the repository
+2. Create feature branch
+3. Write tests for new features
+4. Ensure all tests pass
+5. Follow existing code style (ESLint)
+6. Submit pull request
+
+## Versioning and Releases
+
+- Follows semantic versioning (SemVer)
+- Changelog maintained in `CHANGELOG.md`
+- Precommit hooks run build and tests (Husky)
+- Automated CI/CD via GitHub Actions
+
+## Support and Community
+
+- **GitHub Issues**: Bug reports and feature requests
+- **GitHub Discussions**: Questions and general discussion
+- **OpenCollective**: Financial support and sponsorship
+- **GitHub Sponsors**: Direct sponsorship
+
+## License
+
+**BSD-2-Clause License**
+
+Copyright (C) 2016-2024 Timofey Kachalov
+
+See `LICENSE.BSD` for full license text.
+
+## Project Statistics
+
+- **First Release**: 2016
+- **Language**: TypeScript (~90% of codebase)
+- **Test Coverage**: Extensive functional and unit test suite
+- **Supported JavaScript Versions**: ES3, ES5, ES2015-ES2019, partial ES2020
+- **Downloads**: Widely used in production applications
+- **Maintenance**: Actively maintained
+
+## Resources
+
+- **Main Repository**: https://github.com/javascript-obfuscator/javascript-obfuscator
+- **Online Tool**: https://obfuscator.io
+- **NPM Package**: https://www.npmjs.com/package/javascript-obfuscator
+- **Documentation**: In README.md and inline code comments
+
+---
+
+## Quick Reference: File Locations
+
+| Component | Primary Location |
+|-----------|------------------|
+| Main Obfuscator | `src/JavaScriptObfuscator.ts` |
+| Public API | `src/JavaScriptObfuscatorFacade.ts` |
+| CLI | `bin/javascript-obfuscator`, `src/JavaScriptObfuscatorCLIFacade.ts` |
+| Options | `src/options/Options.ts` |
+| Transformers | `src/node-transformers/` |
+| Analyzers | `src/analyzers/` |
+| DI Container | `src/container/InversifyContainerFacade.ts` |
+| Tests | `test/` |
+| Build Config | `webpack/` |
+| Distribution | `dist/` |
+
+## Quick Reference: Key Enums
+
+- **CodeTransformationStage**: PreparingTransformers, FinalizingTransformers
+- **NodeTransformationStage**: Initializing, Preparing, DeadCodeInjection, ControlFlowFlattening, RenameProperties, Converting, RenameIdentifiers, StringArray, Simplifying, Finalizing
+- **OptionsPreset**: default, low-obfuscation, medium-obfuscation, high-obfuscation
+- **StringArrayEncoding**: none, base64, rc4
+- **IdentifierNamesGenerator**: hexadecimal, mangled, mangled-shuffled, dictionary
+- **RenamePropertiesMode**: safe, unsafe
+- **Target**: browser, browser-no-eval, node