浏览代码

NodeGroups refactoring wip

sanex3339 8 年之前
父节点
当前提交
ee074402a2

+ 147 - 106
dist/index.js

@@ -88,7 +88,7 @@ module.exports =
 /******/ 	__webpack_require__.p = "";
 /******/
 /******/ 	// Load entry module and return exports
-/******/ 	return __webpack_require__(__webpack_require__.s = 86);
+/******/ 	return __webpack_require__(__webpack_require__.s = 87);
 /******/ })
 /************************************************************************/
 /******/ ([
@@ -296,7 +296,7 @@ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Cons
 
 var escodegen = __webpack_require__(12);
 var esprima = __webpack_require__(24);
-var estraverse = __webpack_require__(4);
+var estraverse = __webpack_require__(5);
 var NodeType_1 = __webpack_require__(7);
 var Nodes_1 = __webpack_require__(2);
 var Utils_1 = __webpack_require__(0);
@@ -669,12 +669,6 @@ exports.NodeAppender = NodeAppender;
 /* 4 */
 /***/ function(module, exports) {
 
-module.exports = require("estraverse");
-
-/***/ },
-/* 5 */
-/***/ function(module, exports) {
-
 "use strict";
 "use strict";
 
@@ -684,6 +678,12 @@ module.exports = require("estraverse");
 })(exports.AppendState || (exports.AppendState = {}));
 var AppendState = exports.AppendState;
 
+/***/ },
+/* 5 */
+/***/ function(module, exports) {
+
+module.exports = require("estraverse");
+
 /***/ },
 /* 6 */
 /***/ function(module, exports) {
@@ -828,7 +828,7 @@ exports.JavaScriptObfuscator = JavaScriptObfuscator;
 
 /***/ },
 /* 11 */
-/***/ function(module, exports) {
+/***/ function(module, exports, __webpack_require__) {
 
 "use strict";
 "use strict";
@@ -837,19 +837,26 @@ var _createClass = (function () { function defineProperties(target, props) { for
 
 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
 
+var AppendState_1 = __webpack_require__(4);
+
 var AbstractNodesGroup = function () {
     function AbstractNodesGroup(stackTraceData, options) {
         _classCallCheck(this, AbstractNodesGroup);
 
-        this.nodes = new Map();
+        this.appendState = AppendState_1.AppendState.BeforeObfuscation;
         this.stackTraceData = stackTraceData;
         this.options = options;
     }
 
     _createClass(AbstractNodesGroup, [{
-        key: "getNodes",
-        value: function getNodes() {
-            return this.nodes;
+        key: "syncCustomNodesWithNodesGroup",
+        value: function syncCustomNodesWithNodesGroup(customNodes) {
+            var _this = this;
+
+            customNodes.forEach(function (node) {
+                node.setAppendState(_this.appendState);
+            });
+            return customNodes;
         }
     }]);
 
@@ -996,7 +1003,7 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen
 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
 
 __webpack_require__(8);
-var AppendState_1 = __webpack_require__(5);
+var AppendState_1 = __webpack_require__(4);
 var SingleNodeCallControllerTemplate_1 = __webpack_require__(65);
 var NoCustomNodesPreset_1 = __webpack_require__(16);
 var AbstractCustomNode_1 = __webpack_require__(6);
@@ -1422,8 +1429,8 @@ function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr
 
 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
 
-var estraverse = __webpack_require__(4);
-var AppendState_1 = __webpack_require__(5);
+var estraverse = __webpack_require__(5);
+var AppendState_1 = __webpack_require__(4);
 var NodeType_1 = __webpack_require__(7);
 var CatchClauseObfuscator_1 = __webpack_require__(47);
 var ConsoleOutputNodesGroup_1 = __webpack_require__(42);
@@ -1487,8 +1494,12 @@ var Obfuscator = function () {
         value: function initializeCustomNodes(stackTraceData) {
             var _this = this;
 
-            Obfuscator.nodeGroups.map(function (nodeGroupConstructor) {
-                _this.customNodes = new Map([].concat(_toConsumableArray(_this.customNodes), _toConsumableArray(new nodeGroupConstructor(stackTraceData, _this.options).getNodes())));
+            Obfuscator.nodeGroups.forEach(function (nodeGroupConstructor) {
+                var nodeGroupNodes = new nodeGroupConstructor(stackTraceData, _this.options).getNodes();
+                if (!nodeGroupNodes) {
+                    return;
+                }
+                _this.customNodes = new Map([].concat(_toConsumableArray(_this.customNodes), _toConsumableArray(nodeGroupNodes)));
             });
         }
     }, {
@@ -1895,7 +1906,7 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen
 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
 
 __webpack_require__(8);
-var AppendState_1 = __webpack_require__(5);
+var AppendState_1 = __webpack_require__(4);
 var ConsoleOutputDisableExpressionTemplate_1 = __webpack_require__(66);
 var AbstractCustomNode_1 = __webpack_require__(6);
 var NodeAppender_1 = __webpack_require__(3);
@@ -1953,7 +1964,7 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen
 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
 
 __webpack_require__(8);
-var AppendState_1 = __webpack_require__(5);
+var AppendState_1 = __webpack_require__(4);
 var DebufProtectionFunctionCallTemplate_1 = __webpack_require__(67);
 var AbstractCustomNode_1 = __webpack_require__(6);
 var NodeAppender_1 = __webpack_require__(3);
@@ -2007,7 +2018,7 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen
 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
 
 __webpack_require__(8);
-var AppendState_1 = __webpack_require__(5);
+var AppendState_1 = __webpack_require__(4);
 var DebugProtectionFunctionIntervalTemplate_1 = __webpack_require__(68);
 var AbstractCustomNode_1 = __webpack_require__(6);
 var NodeAppender_1 = __webpack_require__(3);
@@ -2061,7 +2072,7 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen
 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
 
 __webpack_require__(8);
-var AppendState_1 = __webpack_require__(5);
+var AppendState_1 = __webpack_require__(4);
 var DebugProtectionFunctionTemplate_1 = __webpack_require__(69);
 var AbstractCustomNode_1 = __webpack_require__(6);
 var NodeAppender_1 = __webpack_require__(3);
@@ -2128,7 +2139,7 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen
 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
 
 __webpack_require__(8);
-var AppendState_1 = __webpack_require__(5);
+var AppendState_1 = __webpack_require__(4);
 var DomainLockNodeTemplate_1 = __webpack_require__(70);
 var AbstractCustomNode_1 = __webpack_require__(6);
 var NodeAppender_1 = __webpack_require__(3);
@@ -2195,7 +2206,7 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen
 
 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
 
-var AppendState_1 = __webpack_require__(5);
+var AppendState_1 = __webpack_require__(4);
 var NoCustomNodesPreset_1 = __webpack_require__(16);
 var SelfDefendingTemplate_1 = __webpack_require__(71);
 var AbstractCustomNode_1 = __webpack_require__(6);
@@ -2257,7 +2268,7 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen
 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
 
 __webpack_require__(8);
-var AppendState_1 = __webpack_require__(5);
+var AppendState_1 = __webpack_require__(4);
 var UnicodeArrayEncoding_1 = __webpack_require__(18);
 var NoCustomNodesPreset_1 = __webpack_require__(16);
 var AtobTemplate_1 = __webpack_require__(63);
@@ -2369,7 +2380,7 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen
 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
 
 __webpack_require__(8);
-var AppendState_1 = __webpack_require__(5);
+var AppendState_1 = __webpack_require__(4);
 var UnicodeArrayTemplate_1 = __webpack_require__(76);
 var AbstractCustomNode_1 = __webpack_require__(6);
 var NodeAppender_1 = __webpack_require__(3);
@@ -2456,7 +2467,7 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen
 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
 
 __webpack_require__(8);
-var AppendState_1 = __webpack_require__(5);
+var AppendState_1 = __webpack_require__(4);
 var NoCustomNodesPreset_1 = __webpack_require__(16);
 var SelfDefendingTemplate_1 = __webpack_require__(77);
 var UnicodeArrayRotateFunctionTemplate_1 = __webpack_require__(78);
@@ -2530,6 +2541,8 @@ exports.UnicodeArrayRotateFunctionNode = UnicodeArrayRotateFunctionNode;
 "use strict";
 "use strict";
 
+var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+
 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
 
 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
@@ -2544,20 +2557,23 @@ var NodeCallsControllerFunctionNode_1 = __webpack_require__(17);
 var ConsoleOutputNodesGroup = function (_AbstractNodesGroup_) {
     _inherits(ConsoleOutputNodesGroup, _AbstractNodesGroup_);
 
-    function ConsoleOutputNodesGroup(stackTraceData, options) {
+    function ConsoleOutputNodesGroup() {
         _classCallCheck(this, ConsoleOutputNodesGroup);
 
-        var _this = _possibleConstructorReturn(this, (ConsoleOutputNodesGroup.__proto__ || Object.getPrototypeOf(ConsoleOutputNodesGroup)).call(this, stackTraceData, options));
+        return _possibleConstructorReturn(this, (ConsoleOutputNodesGroup.__proto__ || Object.getPrototypeOf(ConsoleOutputNodesGroup)).apply(this, arguments));
+    }
 
-        if (!_this.options.disableConsoleOutput) {
-            return _possibleConstructorReturn(_this);
+    _createClass(ConsoleOutputNodesGroup, [{
+        key: 'getNodes',
+        value: function getNodes() {
+            if (!this.options.disableConsoleOutput) {
+                return;
+            }
+            var callsControllerFunctionName = 'consoleOutputNodeCallsControllerFunction';
+            var randomStackTraceIndex = NodeAppender_1.NodeAppender.getRandomStackTraceIndex(this.stackTraceData.length);
+            return this.syncCustomNodesWithNodesGroup(new Map([['consoleOutputDisableExpressionNode', new ConsoleOutputDisableExpressionNode_1.ConsoleOutputDisableExpressionNode(this.stackTraceData, callsControllerFunctionName, randomStackTraceIndex, this.options)], ['ConsoleOutputNodeCallsControllerFunctionNode', new NodeCallsControllerFunctionNode_1.NodeCallsControllerFunctionNode(this.stackTraceData, callsControllerFunctionName, randomStackTraceIndex, this.options)]]));
         }
-        var callsControllerFunctionName = 'consoleOutputNodeCallsControllerFunction';
-        var randomStackTraceIndex = NodeAppender_1.NodeAppender.getRandomStackTraceIndex(_this.stackTraceData.length);
-        _this.nodes.set('consoleOutputDisableExpressionNode', new ConsoleOutputDisableExpressionNode_1.ConsoleOutputDisableExpressionNode(_this.stackTraceData, callsControllerFunctionName, randomStackTraceIndex, _this.options));
-        _this.nodes.set('ConsoleOutputNodeCallsControllerFunctionNode', new NodeCallsControllerFunctionNode_1.NodeCallsControllerFunctionNode(_this.stackTraceData, callsControllerFunctionName, randomStackTraceIndex, _this.options));
-        return _this;
-    }
+    }]);
 
     return ConsoleOutputNodesGroup;
 }(AbstractNodesGroup_1.AbstractNodesGroup);
@@ -2571,6 +2587,8 @@ exports.ConsoleOutputNodesGroup = ConsoleOutputNodesGroup;
 "use strict";
 "use strict";
 
+var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+
 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
 
 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
@@ -2581,27 +2599,30 @@ var DebugProtectionFunctionCallNode_1 = __webpack_require__(34);
 var DebugProtectionFunctionIntervalNode_1 = __webpack_require__(35);
 var DebugProtectionFunctionNode_1 = __webpack_require__(36);
 var AbstractNodesGroup_1 = __webpack_require__(11);
-var Utils_1 = __webpack_require__(0);
 
 var DebugProtectionNodesGroup = function (_AbstractNodesGroup_) {
     _inherits(DebugProtectionNodesGroup, _AbstractNodesGroup_);
 
-    function DebugProtectionNodesGroup(stackTraceData, options) {
+    function DebugProtectionNodesGroup() {
         _classCallCheck(this, DebugProtectionNodesGroup);
 
-        var _this = _possibleConstructorReturn(this, (DebugProtectionNodesGroup.__proto__ || Object.getPrototypeOf(DebugProtectionNodesGroup)).call(this, stackTraceData, options));
+        return _possibleConstructorReturn(this, (DebugProtectionNodesGroup.__proto__ || Object.getPrototypeOf(DebugProtectionNodesGroup)).apply(this, arguments));
+    }
 
-        _this.debugProtectionFunctionIdentifier = Utils_1.Utils.getRandomVariableName();
-        if (!_this.options.debugProtection) {
-            return _possibleConstructorReturn(_this);
-        }
-        _this.nodes.set('debugProtectionFunctionNode', new DebugProtectionFunctionNode_1.DebugProtectionFunctionNode(_this.debugProtectionFunctionIdentifier, _this.options));
-        _this.nodes.set('debugProtectionFunctionCallNode', new DebugProtectionFunctionCallNode_1.DebugProtectionFunctionCallNode(_this.debugProtectionFunctionIdentifier, _this.options));
-        if (_this.options.debugProtectionInterval) {
-            _this.nodes.set('debugProtectionFunctionIntervalNode', new DebugProtectionFunctionIntervalNode_1.DebugProtectionFunctionIntervalNode(_this.debugProtectionFunctionIdentifier, _this.options));
+    _createClass(DebugProtectionNodesGroup, [{
+        key: 'getNodes',
+        value: function getNodes() {
+            if (!this.options.debugProtection) {
+                return;
+            }
+            var debugProtectionFunctionName = 'debugProtectionFunction';
+            var customNodes = new Map([['debugProtectionFunctionNode', new DebugProtectionFunctionNode_1.DebugProtectionFunctionNode(debugProtectionFunctionName, this.options)], ['debugProtectionFunctionCallNode', new DebugProtectionFunctionCallNode_1.DebugProtectionFunctionCallNode(debugProtectionFunctionName, this.options)]]);
+            if (this.options.debugProtectionInterval) {
+                customNodes.set('debugProtectionFunctionIntervalNode', new DebugProtectionFunctionIntervalNode_1.DebugProtectionFunctionIntervalNode(debugProtectionFunctionName, this.options));
+            }
+            return this.syncCustomNodesWithNodesGroup(customNodes);
         }
-        return _this;
-    }
+    }]);
 
     return DebugProtectionNodesGroup;
 }(AbstractNodesGroup_1.AbstractNodesGroup);
@@ -2615,6 +2636,8 @@ exports.DebugProtectionNodesGroup = DebugProtectionNodesGroup;
 "use strict";
 "use strict";
 
+var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+
 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
 
 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
@@ -2629,20 +2652,23 @@ var NodeCallsControllerFunctionNode_1 = __webpack_require__(17);
 var DomainLockNodesGroup = function (_AbstractNodesGroup_) {
     _inherits(DomainLockNodesGroup, _AbstractNodesGroup_);
 
-    function DomainLockNodesGroup(stackTraceData, options) {
+    function DomainLockNodesGroup() {
         _classCallCheck(this, DomainLockNodesGroup);
 
-        var _this = _possibleConstructorReturn(this, (DomainLockNodesGroup.__proto__ || Object.getPrototypeOf(DomainLockNodesGroup)).call(this, stackTraceData, options));
+        return _possibleConstructorReturn(this, (DomainLockNodesGroup.__proto__ || Object.getPrototypeOf(DomainLockNodesGroup)).apply(this, arguments));
+    }
 
-        if (!_this.options.domainLock.length) {
-            return _possibleConstructorReturn(_this);
+    _createClass(DomainLockNodesGroup, [{
+        key: 'getNodes',
+        value: function getNodes() {
+            if (!this.options.domainLock.length) {
+                return;
+            }
+            var callsControllerFunctionName = 'domainLockCallsControllerFunction';
+            var randomStackTraceIndex = NodeAppender_1.NodeAppender.getRandomStackTraceIndex(this.stackTraceData.length);
+            return this.syncCustomNodesWithNodesGroup(new Map([['DomainLockNode', new DomainLockNode_1.DomainLockNode(this.stackTraceData, callsControllerFunctionName, randomStackTraceIndex, this.options)], ['DomainLockNodeCallsControllerFunctionNode', new NodeCallsControllerFunctionNode_1.NodeCallsControllerFunctionNode(this.stackTraceData, callsControllerFunctionName, randomStackTraceIndex, this.options)]]));
         }
-        var callsControllerFunctionName = 'domainLockCallsControllerFunction';
-        var randomStackTraceIndex = NodeAppender_1.NodeAppender.getRandomStackTraceIndex(_this.stackTraceData.length);
-        _this.nodes.set('DomainLockNode', new DomainLockNode_1.DomainLockNode(_this.stackTraceData, callsControllerFunctionName, randomStackTraceIndex, _this.options));
-        _this.nodes.set('DomainLockNodeCallsControllerFunctionNode', new NodeCallsControllerFunctionNode_1.NodeCallsControllerFunctionNode(_this.stackTraceData, callsControllerFunctionName, randomStackTraceIndex, _this.options));
-        return _this;
-    }
+    }]);
 
     return DomainLockNodesGroup;
 }(AbstractNodesGroup_1.AbstractNodesGroup);
@@ -2656,13 +2682,15 @@ exports.DomainLockNodesGroup = DomainLockNodesGroup;
 "use strict";
 "use strict";
 
+var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+
 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
 
 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
 
 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
 
-var AppendState_1 = __webpack_require__(5);
+var AppendState_1 = __webpack_require__(4);
 var AbstractNodesGroup_1 = __webpack_require__(11);
 var NodeAppender_1 = __webpack_require__(3);
 var NodeCallsControllerFunctionNode_1 = __webpack_require__(17);
@@ -2672,25 +2700,27 @@ var Utils_1 = __webpack_require__(0);
 var SelfDefendingNodesGroup = function (_AbstractNodesGroup_) {
     _inherits(SelfDefendingNodesGroup, _AbstractNodesGroup_);
 
-    function SelfDefendingNodesGroup(stackTraceData, options) {
+    function SelfDefendingNodesGroup() {
         _classCallCheck(this, SelfDefendingNodesGroup);
 
-        var _this = _possibleConstructorReturn(this, (SelfDefendingNodesGroup.__proto__ || Object.getPrototypeOf(SelfDefendingNodesGroup)).call(this, stackTraceData, options));
+        var _this = _possibleConstructorReturn(this, (SelfDefendingNodesGroup.__proto__ || Object.getPrototypeOf(SelfDefendingNodesGroup)).apply(this, arguments));
 
-        if (!_this.options.selfDefending) {
-            return _possibleConstructorReturn(_this);
-        }
-        var callsControllerFunctionName = Utils_1.Utils.getRandomVariableName();
-        var randomStackTraceIndex = NodeAppender_1.NodeAppender.getRandomStackTraceIndex(_this.stackTraceData.length);
-        var selfDefendingUnicodeNode = new SelfDefendingUnicodeNode_1.SelfDefendingUnicodeNode(_this.stackTraceData, callsControllerFunctionName, randomStackTraceIndex, _this.options);
-        var nodeCallsControllerFunctionNode = new NodeCallsControllerFunctionNode_1.NodeCallsControllerFunctionNode(_this.stackTraceData, callsControllerFunctionName, randomStackTraceIndex, _this.options);
-        selfDefendingUnicodeNode.setAppendState(AppendState_1.AppendState.AfterObfuscation);
-        nodeCallsControllerFunctionNode.setAppendState(AppendState_1.AppendState.AfterObfuscation);
-        _this.nodes.set('selfDefendingUnicodeNode', selfDefendingUnicodeNode);
-        _this.nodes.set('SelfDefendingNodeCallsControllerFunctionNode', nodeCallsControllerFunctionNode);
+        _this.appendState = AppendState_1.AppendState.AfterObfuscation;
         return _this;
     }
 
+    _createClass(SelfDefendingNodesGroup, [{
+        key: 'getNodes',
+        value: function getNodes() {
+            if (!this.options.selfDefending) {
+                return;
+            }
+            var callsControllerFunctionName = Utils_1.Utils.getRandomVariableName();
+            var randomStackTraceIndex = NodeAppender_1.NodeAppender.getRandomStackTraceIndex(this.stackTraceData.length);
+            return this.syncCustomNodesWithNodesGroup(new Map([['selfDefendingUnicodeNode', new SelfDefendingUnicodeNode_1.SelfDefendingUnicodeNode(this.stackTraceData, callsControllerFunctionName, randomStackTraceIndex, this.options)], ['SelfDefendingNodeCallsControllerFunctionNode', new NodeCallsControllerFunctionNode_1.NodeCallsControllerFunctionNode(this.stackTraceData, callsControllerFunctionName, randomStackTraceIndex, this.options)]]));
+        }
+    }]);
+
     return SelfDefendingNodesGroup;
 }(AbstractNodesGroup_1.AbstractNodesGroup);
 
@@ -2703,12 +2733,15 @@ exports.SelfDefendingNodesGroup = SelfDefendingNodesGroup;
 "use strict";
 "use strict";
 
+var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+
 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
 
 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
 
 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
 
+var AppendState_1 = __webpack_require__(4);
 var AbstractNodesGroup_1 = __webpack_require__(11);
 var UnicodeArray_1 = __webpack_require__(30);
 var UnicodeArrayCallsWrapper_1 = __webpack_require__(39);
@@ -2719,34 +2752,41 @@ var Utils_1 = __webpack_require__(0);
 var UnicodeArrayNodesGroup = function (_AbstractNodesGroup_) {
     _inherits(UnicodeArrayNodesGroup, _AbstractNodesGroup_);
 
-    function UnicodeArrayNodesGroup(stackTraceData, options) {
+    function UnicodeArrayNodesGroup() {
         _classCallCheck(this, UnicodeArrayNodesGroup);
 
-        var _this = _possibleConstructorReturn(this, (UnicodeArrayNodesGroup.__proto__ || Object.getPrototypeOf(UnicodeArrayNodesGroup)).call(this, stackTraceData, options));
+        var _this = _possibleConstructorReturn(this, (UnicodeArrayNodesGroup.__proto__ || Object.getPrototypeOf(UnicodeArrayNodesGroup)).apply(this, arguments));
 
+        _this.appendState = AppendState_1.AppendState.AfterObfuscation;
         _this.unicodeArrayName = Utils_1.Utils.getRandomVariableName(UnicodeArrayNode_1.UnicodeArrayNode.UNICODE_ARRAY_RANDOM_LENGTH);
         _this.unicodeArrayTranslatorName = Utils_1.Utils.getRandomVariableName(UnicodeArrayNode_1.UnicodeArrayNode.UNICODE_ARRAY_RANDOM_LENGTH);
-        if (!_this.options.unicodeArray) {
-            return _possibleConstructorReturn(_this);
-        }
-        if (_this.options.rotateUnicodeArray) {
-            _this.unicodeArrayRotateValue = Utils_1.Utils.getRandomGenerator().integer({
-                min: 100,
-                max: 500
-            });
-        } else {
-            _this.unicodeArrayRotateValue = 0;
-        }
-        var unicodeArray = new UnicodeArray_1.UnicodeArray();
-        var unicodeArrayNode = new UnicodeArrayNode_1.UnicodeArrayNode(unicodeArray, _this.unicodeArrayName, _this.unicodeArrayRotateValue, _this.options);
-        _this.nodes.set('unicodeArrayNode', unicodeArrayNode);
-        _this.nodes.set('unicodeArrayCallsWrapper', new UnicodeArrayCallsWrapper_1.UnicodeArrayCallsWrapper(_this.unicodeArrayTranslatorName, _this.unicodeArrayName, unicodeArray, _this.options));
-        if (_this.options.rotateUnicodeArray) {
-            _this.nodes.set('unicodeArrayRotateFunctionNode', new UnicodeArrayRotateFunctionNode_1.UnicodeArrayRotateFunctionNode(_this.unicodeArrayName, unicodeArray, _this.unicodeArrayRotateValue, _this.options));
-        }
         return _this;
     }
 
+    _createClass(UnicodeArrayNodesGroup, [{
+        key: 'getNodes',
+        value: function getNodes() {
+            if (!this.options.unicodeArray) {
+                return;
+            }
+            if (this.options.rotateUnicodeArray) {
+                this.unicodeArrayRotateValue = Utils_1.Utils.getRandomGenerator().integer({
+                    min: 100,
+                    max: 500
+                });
+            } else {
+                this.unicodeArrayRotateValue = 0;
+            }
+            var unicodeArray = new UnicodeArray_1.UnicodeArray();
+            var unicodeArrayNode = new UnicodeArrayNode_1.UnicodeArrayNode(unicodeArray, this.unicodeArrayName, this.unicodeArrayRotateValue, this.options);
+            var customNodes = new Map([['unicodeArrayNode', unicodeArrayNode], ['unicodeArrayCallsWrapper', new UnicodeArrayCallsWrapper_1.UnicodeArrayCallsWrapper(this.unicodeArrayTranslatorName, this.unicodeArrayName, unicodeArray, this.options)]]);
+            if (this.options.rotateUnicodeArray) {
+                customNodes.set('unicodeArrayRotateFunctionNode', new UnicodeArrayRotateFunctionNode_1.UnicodeArrayRotateFunctionNode(this.unicodeArrayName, unicodeArray, this.unicodeArrayRotateValue, this.options));
+            }
+            return this.syncCustomNodesWithNodesGroup(customNodes);
+        }
+    }]);
+
     return UnicodeArrayNodesGroup;
 }(AbstractNodesGroup_1.AbstractNodesGroup);
 
@@ -2767,7 +2807,7 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen
 
 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
 
-var estraverse = __webpack_require__(4);
+var estraverse = __webpack_require__(5);
 var NodeType_1 = __webpack_require__(7);
 var AbstractNodeObfuscator_1 = __webpack_require__(9);
 var IdentifierReplacer_1 = __webpack_require__(15);
@@ -2838,7 +2878,7 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen
 
 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
 
-var estraverse = __webpack_require__(4);
+var estraverse = __webpack_require__(5);
 var NodeType_1 = __webpack_require__(7);
 var AbstractNodeObfuscator_1 = __webpack_require__(9);
 var IdentifierReplacer_1 = __webpack_require__(15);
@@ -2913,7 +2953,7 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen
 
 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
 
-var estraverse = __webpack_require__(4);
+var estraverse = __webpack_require__(5);
 var NodeType_1 = __webpack_require__(7);
 var AbstractNodeObfuscator_1 = __webpack_require__(9);
 var IdentifierReplacer_1 = __webpack_require__(15);
@@ -3060,7 +3100,7 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen
 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
 
 var escodegen = __webpack_require__(12);
-var estraverse = __webpack_require__(4);
+var estraverse = __webpack_require__(5);
 var NodeType_1 = __webpack_require__(7);
 var AbstractNodeObfuscator_1 = __webpack_require__(9);
 var Nodes_1 = __webpack_require__(2);
@@ -3144,7 +3184,7 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen
 
 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
 
-var estraverse = __webpack_require__(4);
+var estraverse = __webpack_require__(5);
 var AbstractNodeObfuscator_1 = __webpack_require__(9);
 var Nodes_1 = __webpack_require__(2);
 var Utils_1 = __webpack_require__(0);
@@ -3206,7 +3246,7 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen
 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
 
 var escodegen = __webpack_require__(12);
-var estraverse = __webpack_require__(4);
+var estraverse = __webpack_require__(5);
 var NodeType_1 = __webpack_require__(7);
 var AbstractNodeObfuscator_1 = __webpack_require__(9);
 var Nodes_1 = __webpack_require__(2);
@@ -3291,7 +3331,7 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen
 
 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
 
-var estraverse = __webpack_require__(4);
+var estraverse = __webpack_require__(5);
 var NodeType_1 = __webpack_require__(7);
 var AbstractNodeObfuscator_1 = __webpack_require__(9);
 var IdentifierReplacer_1 = __webpack_require__(15);
@@ -3709,7 +3749,7 @@ var _createClass = (function () { function defineProperties(target, props) { for
 
 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
 
-var estraverse = __webpack_require__(4);
+var estraverse = __webpack_require__(5);
 var NodeType_1 = __webpack_require__(7);
 var FunctionDeclarationCalleeDataExtractor_1 = __webpack_require__(60);
 var FunctionExpressionCalleeDataExtractor_1 = __webpack_require__(61);
@@ -3802,7 +3842,7 @@ var _createClass = (function () { function defineProperties(target, props) { for
 
 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
 
-var estraverse = __webpack_require__(4);
+var estraverse = __webpack_require__(5);
 var Nodes_1 = __webpack_require__(2);
 var NodeUtils_1 = __webpack_require__(1);
 
@@ -3861,7 +3901,7 @@ var _createClass = (function () { function defineProperties(target, props) { for
 
 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
 
-var estraverse = __webpack_require__(4);
+var estraverse = __webpack_require__(5);
 var Nodes_1 = __webpack_require__(2);
 var NodeUtils_1 = __webpack_require__(1);
 
@@ -3923,7 +3963,7 @@ var _createClass = (function () { function defineProperties(target, props) { for
 
 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
 
-var estraverse = __webpack_require__(4);
+var estraverse = __webpack_require__(5);
 var Nodes_1 = __webpack_require__(2);
 var NodeUtils_1 = __webpack_require__(1);
 
@@ -4283,7 +4323,8 @@ module.exports = require("fs");
 module.exports = require("mkdirp");
 
 /***/ },
-/* 86 */
+/* 86 */,
+/* 87 */
 /***/ function(module, exports, __webpack_require__) {
 
 "use strict";

+ 13 - 5
src/Obfuscator.ts

@@ -3,10 +3,10 @@ import * as ESTree from 'estree';
 
 import { ICustomNode } from './interfaces/custom-nodes/ICustomNode';
 import { IObfuscator } from './interfaces/IObfuscator';
-import { INodesGroup } from './interfaces/INodesGroup';
 import { IOptions } from './interfaces/IOptions';
 import { IStackTraceData } from './interfaces/stack-trace-analyzer/IStackTraceData';
 
+import { TNodeGroup } from './types/TNodeGroup';
 import { TNodeObfuscator } from './types/TNodeObfuscator';
 
 import { AppendState } from './enums/AppendState';
@@ -31,9 +31,9 @@ import { StackTraceAnalyzer } from './stack-trace-analyzer/StackTraceAnalyzer';
 
 export class Obfuscator implements IObfuscator {
     /**
-     * @type {(new (stackTraceData: IStackTraceData[], options: IOptions) => INodesGroup)[]}
+     * @type {TNodeGroup[]}
      */
-    private static nodeGroups: (new (stackTraceData: IStackTraceData[], options: IOptions) => INodesGroup)[] = [
+    private static nodeGroups: TNodeGroup[] = [
         DomainLockNodesGroup,
         SelfDefendingNodesGroup,
         ConsoleOutputNodesGroup,
@@ -125,10 +125,18 @@ export class Obfuscator implements IObfuscator {
      * @param stackTraceData
      */
     private initializeCustomNodes (stackTraceData: IStackTraceData[]): void {
-        Obfuscator.nodeGroups.map((nodeGroupConstructor) => {
+        Obfuscator.nodeGroups.forEach((nodeGroupConstructor: TNodeGroup) => {
+            const nodeGroupNodes: Map <string, ICustomNode> | undefined = new nodeGroupConstructor(
+                stackTraceData, this.options
+            ).getNodes();
+
+            if (!nodeGroupNodes) {
+                return;
+            }
+
             this.customNodes = new Map <string, ICustomNode> ([
                 ...this.customNodes,
-                ...new nodeGroupConstructor(stackTraceData, this.options).getNodes()
+                ...nodeGroupNodes
             ]);
         });
     }

+ 2 - 2
src/interfaces/INodesGroup.d.ts

@@ -2,7 +2,7 @@ import { ICustomNode } from './custom-nodes/ICustomNode';
 
 export interface INodesGroup {
     /**
-     * @returns {Map <string, ICustomNode>}
+     * @returns {Map <string, ICustomNode> | undefined}
      */
-    getNodes (): Map <string, ICustomNode>;
+    getNodes (): Map <string, ICustomNode> | undefined;
 }

+ 16 - 5
src/node-groups/AbstractNodesGroup.ts

@@ -1,14 +1,15 @@
 import { ICustomNode } from '../interfaces/custom-nodes/ICustomNode';
-
 import { INodesGroup } from '../interfaces/INodesGroup';
 import { IOptions } from '../interfaces/IOptions';
 import { IStackTraceData } from '../interfaces/stack-trace-analyzer/IStackTraceData';
 
+import { AppendState } from '../enums/AppendState';
+
 export abstract class AbstractNodesGroup implements INodesGroup {
     /**
-     * @type {Map<string, AbstractCustomNode>}
+     * @type {AppendState}
      */
-    protected nodes: Map <string, ICustomNode> = new Map <string, ICustomNode> ();
+    protected appendState: AppendState = AppendState.BeforeObfuscation;
 
     /**
      * @type {IStackTraceData[]}
@@ -30,9 +31,19 @@ export abstract class AbstractNodesGroup implements INodesGroup {
     }
 
     /**
+     * @returns {Map<string, ICustomNode> | undefined}
+     */
+    public abstract getNodes (): Map <string, ICustomNode> | undefined;
+
+    /**
+     * @param customNodes
      * @returns {Map<string, ICustomNode>}
      */
-    public getNodes (): Map <string, ICustomNode> {
-        return this.nodes;
+    protected syncCustomNodesWithNodesGroup (customNodes: Map <string, ICustomNode>): Map <string, ICustomNode> {
+        customNodes.forEach((node: ICustomNode) => {
+            node.setAppendState(this.appendState);
+        });
+
+        return customNodes;
     }
 }

+ 23 - 25
src/node-groups/ConsoleOutputNodesGroup.ts

@@ -1,5 +1,4 @@
-import { IOptions } from '../interfaces/IOptions';
-import { IStackTraceData } from '../interfaces/stack-trace-analyzer/IStackTraceData';
+import { ICustomNode } from '../interfaces/custom-nodes/ICustomNode';
 
 import { AbstractNodesGroup } from './AbstractNodesGroup';
 import { ConsoleOutputDisableExpressionNode } from '../custom-nodes/console-output-nodes/ConsoleOutputDisableExpressionNode';
@@ -8,12 +7,9 @@ import { NodeCallsControllerFunctionNode } from '../custom-nodes/node-calls-cont
 
 export class ConsoleOutputNodesGroup extends AbstractNodesGroup {
     /**
-     * @param stackTraceData
-     * @param options
+     * @returns {Map<string, ICustomNode>}
      */
-    constructor (stackTraceData: IStackTraceData[], options: IOptions) {
-        super(stackTraceData, options);
-
+    public getNodes (): Map <string, ICustomNode> | undefined {
         if (!this.options.disableConsoleOutput) {
             return;
         }
@@ -21,23 +17,25 @@ export class ConsoleOutputNodesGroup extends AbstractNodesGroup {
         const callsControllerFunctionName: string = 'consoleOutputNodeCallsControllerFunction';
         const randomStackTraceIndex: number = NodeAppender.getRandomStackTraceIndex(this.stackTraceData.length);
 
-        this.nodes.set(
-            'consoleOutputDisableExpressionNode',
-            new ConsoleOutputDisableExpressionNode(
-                this.stackTraceData,
-                callsControllerFunctionName,
-                randomStackTraceIndex,
-                this.options
-            )
-        );
-        this.nodes.set(
-            'ConsoleOutputNodeCallsControllerFunctionNode',
-            new NodeCallsControllerFunctionNode(
-                this.stackTraceData,
-                callsControllerFunctionName,
-                randomStackTraceIndex,
-                this.options
-            )
-        );
+        return this.syncCustomNodesWithNodesGroup(new Map <string, ICustomNode> ([
+            [
+                'consoleOutputDisableExpressionNode',
+                new ConsoleOutputDisableExpressionNode(
+                    this.stackTraceData,
+                    callsControllerFunctionName,
+                    randomStackTraceIndex,
+                    this.options
+                )
+            ],
+            [
+                'ConsoleOutputNodeCallsControllerFunctionNode',
+                new NodeCallsControllerFunctionNode(
+                    this.stackTraceData,
+                    callsControllerFunctionName,
+                    randomStackTraceIndex,
+                    this.options
+                )
+            ]
+        ]));
     }
 }

+ 18 - 23
src/node-groups/DebugProtectionNodesGroup.ts

@@ -1,44 +1,39 @@
-import { IOptions } from '../interfaces/IOptions';
-import { IStackTraceData } from '../interfaces/stack-trace-analyzer/IStackTraceData';
+import { ICustomNode } from '../interfaces/custom-nodes/ICustomNode';
 
 import { DebugProtectionFunctionCallNode } from '../custom-nodes/debug-protection-nodes/DebugProtectionFunctionCallNode';
 import { DebugProtectionFunctionIntervalNode } from '../custom-nodes/debug-protection-nodes/DebugProtectionFunctionIntervalNode';
 import { DebugProtectionFunctionNode } from '../custom-nodes/debug-protection-nodes/DebugProtectionFunctionNode';
 
 import { AbstractNodesGroup } from './AbstractNodesGroup';
-import { Utils } from '../Utils';
 
 export class DebugProtectionNodesGroup extends AbstractNodesGroup {
     /**
-     * @type {string}
+     * @returns {Map<string, ICustomNode> | undefined}
      */
-    private debugProtectionFunctionIdentifier: string = Utils.getRandomVariableName();
-
-    /**
-     * @param stackTraceData
-     * @param options
-     */
-    constructor (stackTraceData: IStackTraceData[], options: IOptions) {
-        super(stackTraceData, options);
-
+    public getNodes (): Map <string, ICustomNode> | undefined {
         if (!this.options.debugProtection) {
             return;
         }
 
-        this.nodes.set(
-            'debugProtectionFunctionNode',
-            new DebugProtectionFunctionNode(this.debugProtectionFunctionIdentifier, this.options)
-        );
-        this.nodes.set(
-            'debugProtectionFunctionCallNode',
-            new DebugProtectionFunctionCallNode(this.debugProtectionFunctionIdentifier, this.options)
-        );
+        const debugProtectionFunctionName: string = 'debugProtectionFunction';
+        const customNodes: Map <string, ICustomNode> = new Map <string, ICustomNode> ([
+            [
+                'debugProtectionFunctionNode',
+                new DebugProtectionFunctionNode(debugProtectionFunctionName, this.options)
+            ],
+            [
+                'debugProtectionFunctionCallNode',
+                new DebugProtectionFunctionCallNode(debugProtectionFunctionName, this.options)
+            ]
+        ]);
 
         if (this.options.debugProtectionInterval) {
-            this.nodes.set(
+            customNodes.set(
                 'debugProtectionFunctionIntervalNode',
-                new DebugProtectionFunctionIntervalNode(this.debugProtectionFunctionIdentifier, this.options)
+                new DebugProtectionFunctionIntervalNode(debugProtectionFunctionName, this.options)
             );
         }
+
+        return this.syncCustomNodesWithNodesGroup(customNodes);
     }
 }

+ 23 - 26
src/node-groups/DomainLockNodesGroup.ts

@@ -1,19 +1,14 @@
-import { IOptions } from '../interfaces/IOptions';
-import { IStackTraceData } from '../interfaces/stack-trace-analyzer/IStackTraceData';
-
 import { AbstractNodesGroup } from './AbstractNodesGroup';
 import { NodeAppender } from '../NodeAppender';
 import { DomainLockNode } from '../custom-nodes/domain-lock-nodes/DomainLockNode';
 import { NodeCallsControllerFunctionNode } from '../custom-nodes/node-calls-controller-nodes/NodeCallsControllerFunctionNode';
+import { ICustomNode } from '../interfaces/custom-nodes/ICustomNode';
 
 export class DomainLockNodesGroup extends AbstractNodesGroup {
     /**
-     * @param stackTraceData
-     * @param options
+     * @returns {Map<string, ICustomNode> | undefined}
      */
-    constructor (stackTraceData: IStackTraceData[], options: IOptions) {
-        super(stackTraceData, options);
-
+    public getNodes (): Map <string, ICustomNode> | undefined {
         if (!this.options.domainLock.length) {
             return;
         }
@@ -21,23 +16,25 @@ export class DomainLockNodesGroup extends AbstractNodesGroup {
         const callsControllerFunctionName: string = 'domainLockCallsControllerFunction';
         const randomStackTraceIndex: number = NodeAppender.getRandomStackTraceIndex(this.stackTraceData.length);
 
-        this.nodes.set(
-            'DomainLockNode',
-            new DomainLockNode(
-                this.stackTraceData,
-                callsControllerFunctionName,
-                randomStackTraceIndex,
-                this.options
-            )
-        );
-        this.nodes.set(
-            'DomainLockNodeCallsControllerFunctionNode',
-            new NodeCallsControllerFunctionNode(
-                this.stackTraceData,
-                callsControllerFunctionName,
-                randomStackTraceIndex,
-                this.options
-            )
-        );
+        return this.syncCustomNodesWithNodesGroup(new Map <string, ICustomNode> ([
+            [
+                'DomainLockNode',
+                new DomainLockNode(
+                    this.stackTraceData,
+                    callsControllerFunctionName,
+                    randomStackTraceIndex,
+                    this.options
+                )
+            ],
+            [
+                'DomainLockNodeCallsControllerFunctionNode',
+                new NodeCallsControllerFunctionNode(
+                    this.stackTraceData,
+                    callsControllerFunctionName,
+                    randomStackTraceIndex,
+                    this.options
+                )
+            ]
+        ]));
     }
 }

+ 26 - 29
src/node-groups/SelfDefendingNodesGroup.ts

@@ -1,6 +1,4 @@
 import { ICustomNode } from '../interfaces/custom-nodes/ICustomNode';
-import { IOptions } from '../interfaces/IOptions';
-import { IStackTraceData } from '../interfaces/stack-trace-analyzer/IStackTraceData';
 
 import { AppendState } from '../enums/AppendState';
 
@@ -12,41 +10,40 @@ import { Utils } from '../Utils';
 
 export class SelfDefendingNodesGroup extends AbstractNodesGroup {
     /**
-     * @param stackTraceData
-     * @param options
+     * @type {AppendState}
      */
-    constructor (stackTraceData: IStackTraceData[], options: IOptions) {
-        super(stackTraceData, options);
+    protected appendState: AppendState = AppendState.AfterObfuscation;
 
+    /**
+     * @returns {Map<string, ICustomNode> | undefined}
+     */
+    public getNodes (): Map <string, ICustomNode> | undefined {
         if (!this.options.selfDefending) {
             return;
         }
 
         const callsControllerFunctionName: string = Utils.getRandomVariableName();
         const randomStackTraceIndex: number = NodeAppender.getRandomStackTraceIndex(this.stackTraceData.length);
-        const selfDefendingUnicodeNode: ICustomNode = new SelfDefendingUnicodeNode(
-            this.stackTraceData,
-            callsControllerFunctionName,
-            randomStackTraceIndex,
-            this.options
-        );
-        const nodeCallsControllerFunctionNode: ICustomNode = new NodeCallsControllerFunctionNode(
-            this.stackTraceData,
-            callsControllerFunctionName,
-            randomStackTraceIndex,
-            this.options
-        );
-
-        selfDefendingUnicodeNode.setAppendState(AppendState.AfterObfuscation);
-        nodeCallsControllerFunctionNode.setAppendState(AppendState.AfterObfuscation);
 
-        this.nodes.set(
-            'selfDefendingUnicodeNode',
-            selfDefendingUnicodeNode
-        );
-        this.nodes.set(
-            'SelfDefendingNodeCallsControllerFunctionNode',
-            nodeCallsControllerFunctionNode
-        );
+        return this.syncCustomNodesWithNodesGroup(new Map <string, ICustomNode> ([
+            [
+                'selfDefendingUnicodeNode',
+                new SelfDefendingUnicodeNode(
+                    this.stackTraceData,
+                    callsControllerFunctionName,
+                    randomStackTraceIndex,
+                    this.options
+                )
+            ],
+            [
+                'SelfDefendingNodeCallsControllerFunctionNode',
+                new NodeCallsControllerFunctionNode(
+                    this.stackTraceData,
+                    callsControllerFunctionName,
+                    randomStackTraceIndex,
+                    this.options
+                )
+            ]
+        ]));
     }
 }

+ 26 - 19
src/node-groups/UnicodeArrayNodesGroup.ts

@@ -1,6 +1,6 @@
 import { ICustomNode } from '../interfaces/custom-nodes/ICustomNode';
-import { IOptions } from '../interfaces/IOptions';
-import { IStackTraceData } from '../interfaces/stack-trace-analyzer/IStackTraceData';
+
+import { AppendState } from '../enums/AppendState';
 
 import { AbstractNodesGroup } from './AbstractNodesGroup';
 import { UnicodeArray } from '../UnicodeArray';
@@ -10,6 +10,11 @@ import { UnicodeArrayRotateFunctionNode } from '../custom-nodes/unicode-array-no
 import { Utils } from '../Utils';
 
 export class UnicodeArrayNodesGroup extends AbstractNodesGroup {
+    /**
+     * @type {AppendState}
+     */
+    protected appendState: AppendState = AppendState.AfterObfuscation;
+
     /**
      * @type {string}
      */
@@ -26,12 +31,9 @@ export class UnicodeArrayNodesGroup extends AbstractNodesGroup {
     private unicodeArrayTranslatorName: string = Utils.getRandomVariableName(UnicodeArrayNode.UNICODE_ARRAY_RANDOM_LENGTH);
 
     /**
-     * @param stackTraceData
-     * @param options
+     * @returns {Map<string, ICustomNode> | undefined}
      */
-    constructor (stackTraceData: IStackTraceData[], options: IOptions) {
-        super(stackTraceData, options);
-
+    public getNodes (): Map <string, ICustomNode> | undefined {
         if (!this.options.unicodeArray) {
             return;
         }
@@ -52,20 +54,23 @@ export class UnicodeArrayNodesGroup extends AbstractNodesGroup {
             this.unicodeArrayRotateValue,
             this.options
         );
-
-        this.nodes.set('unicodeArrayNode', unicodeArrayNode);
-        this.nodes.set(
-            'unicodeArrayCallsWrapper',
-            new UnicodeArrayCallsWrapper(
-                this.unicodeArrayTranslatorName,
-                this.unicodeArrayName,
-                unicodeArray,
-                this.options
-            )
-        );
+        const customNodes: Map <string, ICustomNode> = new Map <string, ICustomNode> ([
+            [
+                'unicodeArrayNode', unicodeArrayNode,
+            ],
+            [
+                'unicodeArrayCallsWrapper',
+                new UnicodeArrayCallsWrapper(
+                    this.unicodeArrayTranslatorName,
+                    this.unicodeArrayName,
+                    unicodeArray,
+                    this.options
+                )
+            ]
+        ]);
 
         if (this.options.rotateUnicodeArray) {
-            this.nodes.set(
+            customNodes.set(
                 'unicodeArrayRotateFunctionNode',
                 new UnicodeArrayRotateFunctionNode(
                     this.unicodeArrayName,
@@ -75,5 +80,7 @@ export class UnicodeArrayNodesGroup extends AbstractNodesGroup {
                 )
             );
         }
+
+       return this.syncCustomNodesWithNodesGroup(customNodes);
     }
 }

+ 5 - 0
src/types/TNodeGroup.d.ts

@@ -0,0 +1,5 @@
+import { INodesGroup } from '../interfaces/INodesGroup';
+import { IOptions } from '../interfaces/IOptions';
+import { IStackTraceData } from '../interfaces/stack-trace-analyzer/IStackTraceData';
+
+export type TNodeGroup = new (stackTraceData: IStackTraceData[], options: IOptions) => INodesGroup;