@loxia-labs/loxia-autopilot-one 1.0.1 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +44 -54
- package/bin/cli.js +1 -115
- package/bin/loxia-terminal-v2.js +3 -0
- package/bin/loxia-terminal.js +3 -0
- package/bin/start-with-terminal.js +3 -0
- package/package.json +14 -15
- package/scripts/install-scanners.js +1 -235
- package/src/analyzers/CSSAnalyzer.js +1 -297
- package/src/analyzers/ConfigValidator.js +1 -690
- package/src/analyzers/ESLintAnalyzer.js +1 -320
- package/src/analyzers/JavaScriptAnalyzer.js +1 -261
- package/src/analyzers/PrettierFormatter.js +1 -247
- package/src/analyzers/PythonAnalyzer.js +1 -266
- package/src/analyzers/SecurityAnalyzer.js +1 -729
- package/src/analyzers/TypeScriptAnalyzer.js +1 -247
- package/src/analyzers/codeCloneDetector/analyzer.js +1 -344
- package/src/analyzers/codeCloneDetector/detector.js +1 -203
- package/src/analyzers/codeCloneDetector/index.js +1 -160
- package/src/analyzers/codeCloneDetector/parser.js +1 -199
- package/src/analyzers/codeCloneDetector/reporter.js +1 -148
- package/src/analyzers/codeCloneDetector/scanner.js +1 -59
- package/src/core/agentPool.js +1 -1474
- package/src/core/agentScheduler.js +1 -2147
- package/src/core/contextManager.js +1 -709
- package/src/core/messageProcessor.js +1 -732
- package/src/core/orchestrator.js +1 -548
- package/src/core/stateManager.js +1 -877
- package/src/index.js +1 -631
- package/src/interfaces/cli.js +1 -549
- package/src/interfaces/terminal/__tests__/smoke/advancedFeatures.test.js +1 -0
- package/src/interfaces/terminal/__tests__/smoke/agentControl.test.js +1 -0
- package/src/interfaces/terminal/__tests__/smoke/agents.test.js +1 -0
- package/src/interfaces/terminal/__tests__/smoke/components.test.js +1 -0
- package/src/interfaces/terminal/__tests__/smoke/connection.test.js +1 -0
- package/src/interfaces/terminal/__tests__/smoke/enhancements.test.js +1 -0
- package/src/interfaces/terminal/__tests__/smoke/imports.test.js +1 -0
- package/src/interfaces/terminal/__tests__/smoke/messages.test.js +1 -0
- package/src/interfaces/terminal/__tests__/smoke/tools.test.js +1 -0
- package/src/interfaces/terminal/api/apiClient.js +1 -0
- package/src/interfaces/terminal/api/messageRouter.js +1 -0
- package/src/interfaces/terminal/api/session.js +1 -0
- package/src/interfaces/terminal/api/websocket.js +1 -0
- package/src/interfaces/terminal/components/AgentCreator.js +1 -0
- package/src/interfaces/terminal/components/AgentEditor.js +1 -0
- package/src/interfaces/terminal/components/AgentSwitcher.js +1 -0
- package/src/interfaces/terminal/components/ErrorBoundary.js +1 -0
- package/src/interfaces/terminal/components/ErrorPanel.js +1 -0
- package/src/interfaces/terminal/components/Header.js +1 -0
- package/src/interfaces/terminal/components/HelpPanel.js +1 -0
- package/src/interfaces/terminal/components/InputBox.js +1 -0
- package/src/interfaces/terminal/components/Layout.js +1 -0
- package/src/interfaces/terminal/components/LoadingSpinner.js +1 -0
- package/src/interfaces/terminal/components/MessageList.js +1 -0
- package/src/interfaces/terminal/components/MultilineTextInput.js +1 -0
- package/src/interfaces/terminal/components/SearchPanel.js +1 -0
- package/src/interfaces/terminal/components/SettingsPanel.js +1 -0
- package/src/interfaces/terminal/components/StatusBar.js +1 -0
- package/src/interfaces/terminal/components/TextInput.js +1 -0
- package/src/interfaces/terminal/config/agentEditorConstants.js +1 -0
- package/src/interfaces/terminal/config/constants.js +1 -0
- package/src/interfaces/terminal/index.js +1 -0
- package/src/interfaces/terminal/state/useAgentControl.js +1 -0
- package/src/interfaces/terminal/state/useAgents.js +1 -0
- package/src/interfaces/terminal/state/useConnection.js +1 -0
- package/src/interfaces/terminal/state/useMessages.js +1 -0
- package/src/interfaces/terminal/state/useTools.js +1 -0
- package/src/interfaces/terminal/utils/debugLogger.js +1 -0
- package/src/interfaces/terminal/utils/settingsStorage.js +1 -0
- package/src/interfaces/terminal/utils/theme.js +1 -0
- package/src/interfaces/webServer.js +1 -2162
- package/src/modules/fileExplorer/controller.js +1 -280
- package/src/modules/fileExplorer/index.js +1 -37
- package/src/modules/fileExplorer/middleware.js +1 -92
- package/src/modules/fileExplorer/routes.js +1 -125
- package/src/modules/fileExplorer/types.js +1 -44
- package/src/services/aiService.js +1 -1232
- package/src/services/apiKeyManager.js +1 -164
- package/src/services/benchmarkService.js +1 -366
- package/src/services/budgetService.js +1 -539
- package/src/services/contextInjectionService.js +1 -247
- package/src/services/conversationCompactionService.js +1 -637
- package/src/services/errorHandler.js +1 -810
- package/src/services/fileAttachmentService.js +1 -544
- package/src/services/modelRouterService.js +1 -366
- package/src/services/modelsService.js +1 -322
- package/src/services/qualityInspector.js +1 -796
- package/src/services/tokenCountingService.js +1 -536
- package/src/tools/agentCommunicationTool.js +1 -1344
- package/src/tools/agentDelayTool.js +1 -485
- package/src/tools/asyncToolManager.js +1 -604
- package/src/tools/baseTool.js +1 -800
- package/src/tools/browserTool.js +1 -920
- package/src/tools/cloneDetectionTool.js +1 -621
- package/src/tools/dependencyResolverTool.js +1 -1215
- package/src/tools/fileContentReplaceTool.js +1 -875
- package/src/tools/fileSystemTool.js +1 -1107
- package/src/tools/fileTreeTool.js +1 -853
- package/src/tools/imageTool.js +1 -901
- package/src/tools/importAnalyzerTool.js +1 -1060
- package/src/tools/jobDoneTool.js +1 -248
- package/src/tools/seekTool.js +1 -956
- package/src/tools/staticAnalysisTool.js +1 -1778
- package/src/tools/taskManagerTool.js +1 -2873
- package/src/tools/terminalTool.js +1 -2304
- package/src/tools/webTool.js +1 -1430
- package/src/types/agent.js +1 -519
- package/src/types/contextReference.js +1 -972
- package/src/types/conversation.js +1 -730
- package/src/types/toolCommand.js +1 -747
- package/src/utilities/attachmentValidator.js +1 -292
- package/src/utilities/configManager.js +1 -582
- package/src/utilities/constants.js +1 -722
- package/src/utilities/directoryAccessManager.js +1 -535
- package/src/utilities/fileProcessor.js +1 -307
- package/src/utilities/logger.js +1 -436
- package/src/utilities/tagParser.js +1 -1246
- package/src/utilities/toolConstants.js +1 -317
- package/web-ui/build/index.html +2 -2
- package/web-ui/build/static/{index-Dy2bYbOa.css → index-CClD1090.css} +1 -1
- package/web-ui/build/static/{index-CjkkcnFA.js → index-lCBai6dX.js} +66 -67
|
@@ -1,1060 +1 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @file tools/importAnalyzerTool.js
|
|
3
|
-
* @description Modern tool for analyzing and detecting broken imports/exports in Node.js projects
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { promises as fs } from 'fs';
|
|
7
|
-
import path from 'path';
|
|
8
|
-
import { BaseTool } from './baseTool.js';
|
|
9
|
-
import TagParser from '../utilities/tagParser.js';
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Configuration constants for the import analyzer
|
|
13
|
-
*/
|
|
14
|
-
const ANALYZER_CONFIG = {
|
|
15
|
-
DEFAULT_MODE: 'full',
|
|
16
|
-
VALID_MODES: ['full', 'quick', 'fix'],
|
|
17
|
-
DEFAULT_OUTPUT: 'summary',
|
|
18
|
-
VALID_OUTPUTS: ['summary', 'detailed', 'json'],
|
|
19
|
-
DEFAULT_IGNORE_FILE: '.gitignore',
|
|
20
|
-
MAX_FILES: 10000, // Safety limit for file count
|
|
21
|
-
SUPPORTED_EXTENSIONS: ['.js', '.mjs', '.ts', '.jsx', '.tsx'],
|
|
22
|
-
DEFAULT_IGNORE_PATTERNS: ['node_modules', '.git', 'dist', 'build', 'coverage'],
|
|
23
|
-
FILE_READ_TIMEOUT: 5000 // Timeout for reading large files
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* ImportAnalyzerTool - Modern implementation
|
|
28
|
-
* Analyzes JavaScript/TypeScript projects to detect broken imports, missing exports, and dependency issues
|
|
29
|
-
*/
|
|
30
|
-
export class ImportAnalyzerTool extends BaseTool {
|
|
31
|
-
/**
|
|
32
|
-
* Get tool description for agent system prompt
|
|
33
|
-
* @returns {string} Formatted tool description
|
|
34
|
-
*/
|
|
35
|
-
getDescription() {
|
|
36
|
-
return `Tool: Import Analyzer - Analyze JavaScript/TypeScript imports and exports
|
|
37
|
-
|
|
38
|
-
**Purpose:** Analyzes JavaScript/TypeScript projects to detect broken imports, missing exports, circular dependencies, and unused exports.
|
|
39
|
-
|
|
40
|
-
**Invocation Syntax:**
|
|
41
|
-
|
|
42
|
-
XML Format:
|
|
43
|
-
\`\`\`xml
|
|
44
|
-
<import-analyzer>
|
|
45
|
-
<path>./src</path>
|
|
46
|
-
<mode>full</mode>
|
|
47
|
-
<output>summary</output>
|
|
48
|
-
<ignore-file>.gitignore</ignore-file>
|
|
49
|
-
</import-analyzer>
|
|
50
|
-
\`\`\`
|
|
51
|
-
|
|
52
|
-
JSON Format:
|
|
53
|
-
\`\`\`json
|
|
54
|
-
{
|
|
55
|
-
"toolId": "import-analyzer",
|
|
56
|
-
"parameters": {
|
|
57
|
-
"path": "./src",
|
|
58
|
-
"mode": "full",
|
|
59
|
-
"output": "summary",
|
|
60
|
-
"ignoreFile": ".gitignore"
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
\`\`\`
|
|
64
|
-
|
|
65
|
-
**Parameters:**
|
|
66
|
-
- **path** (string, optional): Path to directory to analyze. Default: "."
|
|
67
|
-
- **mode** (string, optional): Analysis mode. Options:
|
|
68
|
-
- "full" - Complete analysis (default)
|
|
69
|
-
- "quick" - Fast scan for missing files only
|
|
70
|
-
- "fix" - Includes fix suggestions
|
|
71
|
-
- **output** (string, optional): Output format. Options:
|
|
72
|
-
- "summary" - Concise summary (default)
|
|
73
|
-
- "detailed" - Full report with fixes
|
|
74
|
-
- "json" - Machine-readable format
|
|
75
|
-
- **ignoreFile** (string, optional): Ignore file name. Default: ".gitignore"
|
|
76
|
-
|
|
77
|
-
**What It Detects:**
|
|
78
|
-
- Missing files (imports pointing to non-existent files)
|
|
79
|
-
- Missing exports (symbols not exported from target files)
|
|
80
|
-
- Circular dependencies (files that depend on each other in a loop)
|
|
81
|
-
- Unused exports (exports never imported anywhere)
|
|
82
|
-
|
|
83
|
-
**Examples:**
|
|
84
|
-
|
|
85
|
-
1. Quick project scan:
|
|
86
|
-
\`\`\`xml
|
|
87
|
-
<import-analyzer>
|
|
88
|
-
<mode>quick</mode>
|
|
89
|
-
</import-analyzer>
|
|
90
|
-
\`\`\`
|
|
91
|
-
|
|
92
|
-
2. Full analysis with detailed report:
|
|
93
|
-
\`\`\`xml
|
|
94
|
-
<import-analyzer>
|
|
95
|
-
<mode>full</mode>
|
|
96
|
-
<output>detailed</output>
|
|
97
|
-
</import-analyzer>
|
|
98
|
-
\`\`\`
|
|
99
|
-
|
|
100
|
-
3. Analyze specific directory:
|
|
101
|
-
\`\`\`json
|
|
102
|
-
{
|
|
103
|
-
"toolId": "import-analyzer",
|
|
104
|
-
"parameters": { "path": "./src/components", "mode": "full" }
|
|
105
|
-
}
|
|
106
|
-
\`\`\`
|
|
107
|
-
|
|
108
|
-
**Notes:**
|
|
109
|
-
- Supports ES6 modules (import/export) and CommonJS (require/module.exports)
|
|
110
|
-
- Respects .gitignore patterns
|
|
111
|
-
- Correctly handles commented imports and multi-line statements
|
|
112
|
-
- Works with .js, .mjs, .ts, .jsx, .tsx files`;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
/**
|
|
116
|
-
* Parse tool parameters from raw content (XML or JSON)
|
|
117
|
-
* @param {string|Object} content - Raw tool content or parsed object
|
|
118
|
-
* @returns {Object} Parsed parameters
|
|
119
|
-
*/
|
|
120
|
-
parseParameters(content) {
|
|
121
|
-
// If already an object, validate and return
|
|
122
|
-
if (typeof content === 'object' && content !== null) {
|
|
123
|
-
return {
|
|
124
|
-
path: content.path || '.',
|
|
125
|
-
mode: content.mode || ANALYZER_CONFIG.DEFAULT_MODE,
|
|
126
|
-
output: content.output || ANALYZER_CONFIG.DEFAULT_OUTPUT,
|
|
127
|
-
ignoreFile: content.ignoreFile || ANALYZER_CONFIG.DEFAULT_IGNORE_FILE
|
|
128
|
-
};
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
// Parse XML content
|
|
132
|
-
if (typeof content === 'string') {
|
|
133
|
-
// Try modern XML format first: <import-analyzer>...</import-analyzer>
|
|
134
|
-
const modernPattern = /<import-analyzer([^>]*)>([\s\S]*?)<\/import-analyzer>/i;
|
|
135
|
-
const modernMatch = modernPattern.exec(content);
|
|
136
|
-
|
|
137
|
-
if (modernMatch) {
|
|
138
|
-
const attributesStr = modernMatch[1];
|
|
139
|
-
const innerContent = modernMatch[2];
|
|
140
|
-
|
|
141
|
-
// Parse attributes from opening tag
|
|
142
|
-
const pathAttr = /path=["']([^"']*)["']/i.exec(attributesStr);
|
|
143
|
-
const modeAttr = /mode=["']([^"']*)["']/i.exec(attributesStr);
|
|
144
|
-
const outputAttr = /output=["']([^"']*)["']/i.exec(attributesStr);
|
|
145
|
-
const ignoreFileAttr = /ignore-file=["']([^"']*)["']/i.exec(attributesStr);
|
|
146
|
-
|
|
147
|
-
// Extract from inner content
|
|
148
|
-
const pathPattern = /<path>(.*?)<\/path>/i;
|
|
149
|
-
const pathMatch = pathPattern.exec(innerContent);
|
|
150
|
-
|
|
151
|
-
const modePattern = /<mode>(.*?)<\/mode>/i;
|
|
152
|
-
const modeMatch = modePattern.exec(innerContent);
|
|
153
|
-
|
|
154
|
-
const outputPattern = /<output>(.*?)<\/output>/i;
|
|
155
|
-
const outputMatch = outputPattern.exec(innerContent);
|
|
156
|
-
|
|
157
|
-
const ignoreFilePattern = /<ignore-file>(.*?)<\/ignore-file>/i;
|
|
158
|
-
const ignoreFileMatch = ignoreFilePattern.exec(innerContent);
|
|
159
|
-
|
|
160
|
-
// Content takes precedence over attributes
|
|
161
|
-
const extractedPath = (pathMatch ? pathMatch[1].trim() : null) || (pathAttr ? pathAttr[1] : '.');
|
|
162
|
-
const extractedMode = (modeMatch ? modeMatch[1].trim() : null) || (modeAttr ? modeAttr[1] : ANALYZER_CONFIG.DEFAULT_MODE);
|
|
163
|
-
const extractedOutput = (outputMatch ? outputMatch[1].trim() : null) || (outputAttr ? outputAttr[1] : ANALYZER_CONFIG.DEFAULT_OUTPUT);
|
|
164
|
-
const extractedIgnoreFile = (ignoreFileMatch ? ignoreFileMatch[1].trim() : null) || (ignoreFileAttr ? ignoreFileAttr[1] : ANALYZER_CONFIG.DEFAULT_IGNORE_FILE);
|
|
165
|
-
|
|
166
|
-
return {
|
|
167
|
-
path: extractedPath,
|
|
168
|
-
mode: extractedMode,
|
|
169
|
-
output: extractedOutput,
|
|
170
|
-
ignoreFile: extractedIgnoreFile
|
|
171
|
-
};
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
// Try legacy format with TagParser
|
|
175
|
-
try {
|
|
176
|
-
const parsed = TagParser.parseTags(content, 'analyze');
|
|
177
|
-
|
|
178
|
-
if (parsed && parsed.length > 0) {
|
|
179
|
-
const analyzeCommand = parsed[0];
|
|
180
|
-
|
|
181
|
-
return {
|
|
182
|
-
path: analyzeCommand.attributes.path || '.',
|
|
183
|
-
mode: analyzeCommand.attributes.mode || ANALYZER_CONFIG.DEFAULT_MODE,
|
|
184
|
-
output: analyzeCommand.attributes.output || ANALYZER_CONFIG.DEFAULT_OUTPUT,
|
|
185
|
-
ignoreFile: analyzeCommand.attributes['ignore-file'] || ANALYZER_CONFIG.DEFAULT_IGNORE_FILE
|
|
186
|
-
};
|
|
187
|
-
}
|
|
188
|
-
} catch (error) {
|
|
189
|
-
// Fall through to error
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
throw new Error('Invalid import-analyzer format. Use <import-analyzer> tags or JSON format.');
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
throw new Error('Invalid parameter format. Expected string (XML) or object (JSON).');
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
/**
|
|
199
|
-
* Validate parameters
|
|
200
|
-
* @param {Object} params - Parameters to validate
|
|
201
|
-
* @throws {Error} If validation fails
|
|
202
|
-
* @private
|
|
203
|
-
*/
|
|
204
|
-
_validateParameters(params) {
|
|
205
|
-
if (!params || typeof params !== 'object') {
|
|
206
|
-
throw new Error('Parameters must be an object');
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
if (params.path && typeof params.path !== 'string') {
|
|
210
|
-
throw new Error('path must be a string');
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
if (params.mode && !ANALYZER_CONFIG.VALID_MODES.includes(params.mode)) {
|
|
214
|
-
throw new Error(`Invalid mode: ${params.mode}. Must be one of: ${ANALYZER_CONFIG.VALID_MODES.join(', ')}`);
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
if (params.output && !ANALYZER_CONFIG.VALID_OUTPUTS.includes(params.output)) {
|
|
218
|
-
throw new Error(`Invalid output: ${params.output}. Must be one of: ${ANALYZER_CONFIG.VALID_OUTPUTS.join(', ')}`);
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
if (params.ignoreFile && typeof params.ignoreFile !== 'string') {
|
|
222
|
-
throw new Error('ignoreFile must be a string');
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
/**
|
|
227
|
-
* Validate and resolve file path
|
|
228
|
-
* @param {string} targetPath - Target path from parameters
|
|
229
|
-
* @param {Object} context - Execution context
|
|
230
|
-
* @returns {string} Resolved absolute path
|
|
231
|
-
* @throws {Error} If path is invalid or inaccessible
|
|
232
|
-
* @private
|
|
233
|
-
*/
|
|
234
|
-
_resolveAndValidatePath(targetPath, context) {
|
|
235
|
-
const { projectDir, directoryAccess } = context;
|
|
236
|
-
|
|
237
|
-
// Determine working directory
|
|
238
|
-
let workingDirectory = projectDir || process.cwd();
|
|
239
|
-
|
|
240
|
-
if (directoryAccess && directoryAccess.workingDirectory) {
|
|
241
|
-
workingDirectory = directoryAccess.workingDirectory;
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
// Resolve the target path
|
|
245
|
-
const resolvedPath = path.isAbsolute(targetPath)
|
|
246
|
-
? path.normalize(targetPath)
|
|
247
|
-
: path.normalize(path.join(workingDirectory, targetPath));
|
|
248
|
-
|
|
249
|
-
// Security: Check for path traversal
|
|
250
|
-
const realWorkingDir = path.normalize(workingDirectory);
|
|
251
|
-
if (!resolvedPath.startsWith(realWorkingDir)) {
|
|
252
|
-
throw new Error(`Path traversal detected: ${targetPath} resolves outside working directory`);
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
return resolvedPath;
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
/**
|
|
259
|
-
* Execute tool with parsed parameters
|
|
260
|
-
* @param {Object} params - Parsed parameters
|
|
261
|
-
* @param {Object} context - Execution context
|
|
262
|
-
* @returns {Promise<Object>} Execution result
|
|
263
|
-
*/
|
|
264
|
-
async execute(params, context = {}) {
|
|
265
|
-
try {
|
|
266
|
-
// Validate parameters
|
|
267
|
-
this._validateParameters(params);
|
|
268
|
-
|
|
269
|
-
const { path: targetPath, mode, output, ignoreFile } = params;
|
|
270
|
-
const { projectDir, agentId, directoryAccess } = context;
|
|
271
|
-
|
|
272
|
-
// Resolve and validate path
|
|
273
|
-
const resolvedPath = this._resolveAndValidatePath(targetPath, context);
|
|
274
|
-
|
|
275
|
-
this.logger?.info('Import analyzer executing', {
|
|
276
|
-
mode,
|
|
277
|
-
resolvedPath,
|
|
278
|
-
output,
|
|
279
|
-
agentId
|
|
280
|
-
});
|
|
281
|
-
|
|
282
|
-
const outputLines = [];
|
|
283
|
-
outputLines.push(`🔍 Analyzing imports in: ${resolvedPath}`);
|
|
284
|
-
outputLines.push(`Mode: ${mode}`);
|
|
285
|
-
outputLines.push(`Output: ${output}\n`);
|
|
286
|
-
|
|
287
|
-
// Check if path exists
|
|
288
|
-
try {
|
|
289
|
-
await fs.access(resolvedPath);
|
|
290
|
-
} catch {
|
|
291
|
-
return {
|
|
292
|
-
success: false,
|
|
293
|
-
error: `Path does not exist: ${resolvedPath}`,
|
|
294
|
-
output: outputLines.join('\n')
|
|
295
|
-
};
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
// Run analysis
|
|
299
|
-
const analyzer = new ImportExportAnalyzer(resolvedPath, ignoreFile, this.logger);
|
|
300
|
-
const results = await analyzer.analyze(mode);
|
|
301
|
-
|
|
302
|
-
// Format output based on requested format
|
|
303
|
-
let formattedOutput;
|
|
304
|
-
switch (output) {
|
|
305
|
-
case 'json':
|
|
306
|
-
// For JSON output, don't include header lines
|
|
307
|
-
formattedOutput = JSON.stringify(results, null, 2);
|
|
308
|
-
break;
|
|
309
|
-
case 'detailed':
|
|
310
|
-
formattedOutput = this._formatDetailedOutput(results);
|
|
311
|
-
outputLines.push(formattedOutput);
|
|
312
|
-
break;
|
|
313
|
-
case 'summary':
|
|
314
|
-
default:
|
|
315
|
-
formattedOutput = this._formatSummaryOutput(results);
|
|
316
|
-
outputLines.push(formattedOutput);
|
|
317
|
-
break;
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
return {
|
|
321
|
-
success: true,
|
|
322
|
-
mode,
|
|
323
|
-
message: 'Import analysis completed',
|
|
324
|
-
statistics: {
|
|
325
|
-
totalFiles: results.summary.totalFiles,
|
|
326
|
-
totalImports: results.summary.totalImports,
|
|
327
|
-
totalExports: results.summary.totalExports,
|
|
328
|
-
issuesFound: results.fileNotFoundImports.length + Object.values(results.missingExports).reduce((sum, arr) => sum + arr.length, 0)
|
|
329
|
-
},
|
|
330
|
-
output: output === 'json' ? formattedOutput : outputLines.join('\n'),
|
|
331
|
-
results
|
|
332
|
-
};
|
|
333
|
-
|
|
334
|
-
} catch (error) {
|
|
335
|
-
this.logger?.error('Import analyzer error:', error);
|
|
336
|
-
|
|
337
|
-
return {
|
|
338
|
-
success: false,
|
|
339
|
-
error: error.message,
|
|
340
|
-
output: error.message
|
|
341
|
-
};
|
|
342
|
-
}
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
/**
|
|
346
|
-
* Format summary output
|
|
347
|
-
* @param {Object} results - Analysis results
|
|
348
|
-
* @returns {string} Formatted output
|
|
349
|
-
* @private
|
|
350
|
-
*/
|
|
351
|
-
_formatSummaryOutput(results) {
|
|
352
|
-
const lines = [];
|
|
353
|
-
|
|
354
|
-
lines.push('📊 Import/Export Analysis Summary');
|
|
355
|
-
lines.push('================================\n');
|
|
356
|
-
|
|
357
|
-
lines.push(`📁 Files analyzed: ${results.summary.totalFiles}`);
|
|
358
|
-
lines.push(`📥 Total imports: ${results.summary.totalImports}`);
|
|
359
|
-
lines.push(`📤 Total exports: ${results.summary.totalExports}\n`);
|
|
360
|
-
|
|
361
|
-
// Critical issues
|
|
362
|
-
const missingFilesCount = results.fileNotFoundImports.length;
|
|
363
|
-
const missingExportsCount = Object.values(results.missingExports).reduce((sum, arr) => sum + arr.length, 0);
|
|
364
|
-
const circularDepsCount = results.circularDependencies ? results.circularDependencies.length : 0;
|
|
365
|
-
|
|
366
|
-
if (missingFilesCount > 0) {
|
|
367
|
-
lines.push(`❌ Missing files: ${missingFilesCount} imports pointing to non-existent files`);
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
if (missingExportsCount > 0) {
|
|
371
|
-
lines.push(`⚠️ Missing exports: ${missingExportsCount} symbols not exported from their sources`);
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
if (circularDepsCount > 0) {
|
|
375
|
-
lines.push(`🔄 Circular dependencies: ${circularDepsCount} circular dependency chains detected`);
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
if (missingFilesCount === 0 && missingExportsCount === 0 && circularDepsCount === 0) {
|
|
379
|
-
lines.push('✅ No import/export issues detected!');
|
|
380
|
-
} else {
|
|
381
|
-
lines.push('\n🔍 Top Issues to Fix:');
|
|
382
|
-
|
|
383
|
-
// Show top 5 files with issues
|
|
384
|
-
if (Object.keys(results.missingFiles || {}).length > 0) {
|
|
385
|
-
lines.push('\n Missing Files:');
|
|
386
|
-
Object.entries(results.missingFiles).slice(0, 3).forEach(([file, issues]) => {
|
|
387
|
-
lines.push(` • ${file} has ${issues.length} broken import(s)`);
|
|
388
|
-
});
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
if (Object.keys(results.missingExports).length > 0) {
|
|
392
|
-
lines.push('\n Missing Exports:');
|
|
393
|
-
Object.entries(results.missingExports).slice(0, 3).forEach(([file, issues]) => {
|
|
394
|
-
lines.push(` • ${file} imports ${issues.length} non-existent symbol(s)`);
|
|
395
|
-
});
|
|
396
|
-
}
|
|
397
|
-
|
|
398
|
-
lines.push('\n💡 Run with output="detailed" for complete analysis and fix suggestions');
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
return lines.join('\n');
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
/**
|
|
405
|
-
* Format detailed output
|
|
406
|
-
* @param {Object} results - Analysis results
|
|
407
|
-
* @returns {string} Formatted output
|
|
408
|
-
* @private
|
|
409
|
-
*/
|
|
410
|
-
_formatDetailedOutput(results) {
|
|
411
|
-
const lines = [];
|
|
412
|
-
|
|
413
|
-
lines.push('📊 Detailed Import/Export Analysis Report');
|
|
414
|
-
lines.push('=========================================\n');
|
|
415
|
-
|
|
416
|
-
lines.push('📈 Statistics:');
|
|
417
|
-
lines.push(` • Files analyzed: ${results.summary.totalFiles}`);
|
|
418
|
-
lines.push(` • Total imports: ${results.summary.totalImports}`);
|
|
419
|
-
lines.push(` • Total exports: ${results.summary.totalExports}\n`);
|
|
420
|
-
|
|
421
|
-
// Missing files section
|
|
422
|
-
if (results.fileNotFoundImports.length > 0) {
|
|
423
|
-
lines.push('❌ MISSING FILES');
|
|
424
|
-
lines.push('─────────────────');
|
|
425
|
-
|
|
426
|
-
const fileGroups = {};
|
|
427
|
-
results.fileNotFoundImports.forEach(item => {
|
|
428
|
-
if (!fileGroups[item.importingFile]) {
|
|
429
|
-
fileGroups[item.importingFile] = [];
|
|
430
|
-
}
|
|
431
|
-
fileGroups[item.importingFile].push(item);
|
|
432
|
-
});
|
|
433
|
-
|
|
434
|
-
Object.entries(fileGroups).forEach(([file, imports]) => {
|
|
435
|
-
lines.push(`\n📄 ${file}:`);
|
|
436
|
-
imports.forEach(imp => {
|
|
437
|
-
const importType = imp.isDefault ? 'default' : imp.isNamespace ? 'namespace' : 'named';
|
|
438
|
-
lines.push(` ⚠️ Cannot find file: ${imp.importedFromFile}`);
|
|
439
|
-
lines.push(` Trying to import: ${imp.importedSymbol} (${importType})`);
|
|
440
|
-
lines.push(` 💡 Fix: Check if file exists or correct the import path`);
|
|
441
|
-
});
|
|
442
|
-
});
|
|
443
|
-
}
|
|
444
|
-
|
|
445
|
-
// Missing exports section
|
|
446
|
-
if (Object.keys(results.missingExports).length > 0) {
|
|
447
|
-
lines.push('\n⚠️ MISSING EXPORTS');
|
|
448
|
-
lines.push('──────────────────');
|
|
449
|
-
|
|
450
|
-
Object.entries(results.missingExports).forEach(([file, issues]) => {
|
|
451
|
-
lines.push(`\n📄 ${file}:`);
|
|
452
|
-
issues.forEach(issue => {
|
|
453
|
-
const importType = issue.isDefault ? 'default' : issue.isNamespace ? 'namespace' : 'named';
|
|
454
|
-
lines.push(` ❌ Symbol not exported: "${issue.importedSymbol}" (${importType})`);
|
|
455
|
-
lines.push(` From file: ${issue.importedFromFile}`);
|
|
456
|
-
|
|
457
|
-
if (issue.availableExports.length > 0) {
|
|
458
|
-
lines.push(` 📤 Available exports: ${issue.availableExports.join(', ')}`);
|
|
459
|
-
|
|
460
|
-
// Suggest potential fixes
|
|
461
|
-
if (issue.isDefault && issue.availableExports.includes('default')) {
|
|
462
|
-
lines.push(` 💡 Fix: Default export exists, check import syntax`);
|
|
463
|
-
} else if (issue.isDefault && !issue.availableExports.includes('default')) {
|
|
464
|
-
lines.push(` 💡 Fix: No default export. Use named import: { ${issue.availableExports[0] || 'symbolName'} }`);
|
|
465
|
-
} else {
|
|
466
|
-
// Check for similar names
|
|
467
|
-
const similar = issue.availableExports.find(exp =>
|
|
468
|
-
exp.toLowerCase() === issue.importedSymbol.toLowerCase()
|
|
469
|
-
);
|
|
470
|
-
if (similar) {
|
|
471
|
-
lines.push(` 💡 Fix: Did you mean "${similar}"? (case mismatch)`);
|
|
472
|
-
} else {
|
|
473
|
-
lines.push(` 💡 Fix: Add export for "${issue.importedSymbol}" or use one of the available exports`);
|
|
474
|
-
}
|
|
475
|
-
}
|
|
476
|
-
} else {
|
|
477
|
-
lines.push(` 📤 No exports found in target file`);
|
|
478
|
-
lines.push(` 💡 Fix: Add exports to ${issue.importedFromFile} or check if it's the correct file`);
|
|
479
|
-
}
|
|
480
|
-
});
|
|
481
|
-
});
|
|
482
|
-
}
|
|
483
|
-
|
|
484
|
-
// Circular dependencies
|
|
485
|
-
if (results.circularDependencies && results.circularDependencies.length > 0) {
|
|
486
|
-
lines.push('\n🔄 CIRCULAR DEPENDENCIES');
|
|
487
|
-
lines.push('────────────────────────');
|
|
488
|
-
|
|
489
|
-
results.circularDependencies.forEach((cycle, index) => {
|
|
490
|
-
lines.push(`\n Cycle ${index + 1}:`);
|
|
491
|
-
cycle.forEach((file, i) => {
|
|
492
|
-
if (i < cycle.length - 1) {
|
|
493
|
-
lines.push(` ${file} → ${cycle[i + 1]}`);
|
|
494
|
-
}
|
|
495
|
-
});
|
|
496
|
-
lines.push(` 💡 Fix: Refactor to break the circular dependency`);
|
|
497
|
-
});
|
|
498
|
-
}
|
|
499
|
-
|
|
500
|
-
// Unused exports (if available)
|
|
501
|
-
if (results.unusedExports && Object.keys(results.unusedExports).length > 0) {
|
|
502
|
-
lines.push('\n🗑️ POTENTIALLY UNUSED EXPORTS');
|
|
503
|
-
lines.push('──────────────────────────────');
|
|
504
|
-
|
|
505
|
-
Object.entries(results.unusedExports).slice(0, 10).forEach(([file, exports]) => {
|
|
506
|
-
lines.push(`\n📄 ${file}:`);
|
|
507
|
-
lines.push(` Unused: ${exports.join(', ')}`);
|
|
508
|
-
});
|
|
509
|
-
|
|
510
|
-
lines.push('\n 💡 Note: These exports are not imported within this project');
|
|
511
|
-
lines.push(' They might be used by external packages or could be removed');
|
|
512
|
-
}
|
|
513
|
-
|
|
514
|
-
// Summary and recommendations
|
|
515
|
-
lines.push('\n📋 RECOMMENDATIONS');
|
|
516
|
-
lines.push('──────────────────');
|
|
517
|
-
|
|
518
|
-
const totalIssues = results.fileNotFoundImports.length +
|
|
519
|
-
Object.values(results.missingExports).reduce((sum, arr) => sum + arr.length, 0);
|
|
520
|
-
|
|
521
|
-
if (totalIssues === 0) {
|
|
522
|
-
lines.push('✅ Your import/export structure looks good!');
|
|
523
|
-
} else {
|
|
524
|
-
lines.push(`Found ${totalIssues} issue(s) that need attention:`);
|
|
525
|
-
|
|
526
|
-
if (results.fileNotFoundImports.length > 0) {
|
|
527
|
-
lines.push(` 1. Fix ${results.fileNotFoundImports.length} missing file reference(s)`);
|
|
528
|
-
}
|
|
529
|
-
|
|
530
|
-
if (Object.keys(results.missingExports).length > 0) {
|
|
531
|
-
lines.push(` 2. Resolve ${Object.values(results.missingExports).reduce((sum, arr) => sum + arr.length, 0)} missing export(s)`);
|
|
532
|
-
}
|
|
533
|
-
|
|
534
|
-
if (results.circularDependencies && results.circularDependencies.length > 0) {
|
|
535
|
-
lines.push(` 3. Refactor ${results.circularDependencies.length} circular dependency chain(s)`);
|
|
536
|
-
}
|
|
537
|
-
}
|
|
538
|
-
|
|
539
|
-
return lines.join('\n');
|
|
540
|
-
}
|
|
541
|
-
}
|
|
542
|
-
|
|
543
|
-
/**
|
|
544
|
-
* Internal analyzer class
|
|
545
|
-
*/
|
|
546
|
-
class ImportExportAnalyzer {
|
|
547
|
-
constructor(rootDir, ignoreFile = '.gitignore', logger = null) {
|
|
548
|
-
this.rootDir = path.resolve(rootDir);
|
|
549
|
-
this.ignoreFile = ignoreFile;
|
|
550
|
-
this.logger = logger;
|
|
551
|
-
this.ignorePatterns = [...ANALYZER_CONFIG.DEFAULT_IGNORE_PATTERNS];
|
|
552
|
-
this.imports = [];
|
|
553
|
-
this.exports = new Map();
|
|
554
|
-
this.dependencies = new Map(); // For circular dependency detection
|
|
555
|
-
}
|
|
556
|
-
|
|
557
|
-
async loadIgnoreFile() {
|
|
558
|
-
try {
|
|
559
|
-
const ignoreFilePath = path.join(this.rootDir, this.ignoreFile);
|
|
560
|
-
const content = await fs.readFile(ignoreFilePath, 'utf-8');
|
|
561
|
-
const patterns = content
|
|
562
|
-
.split('\n')
|
|
563
|
-
.map(line => line.trim())
|
|
564
|
-
.filter(line => line && !line.startsWith('#'));
|
|
565
|
-
|
|
566
|
-
this.ignorePatterns.push(...patterns);
|
|
567
|
-
this.logger?.debug('Loaded ignore patterns', { count: patterns.length });
|
|
568
|
-
} catch {
|
|
569
|
-
// Ignore file doesn't exist, use defaults
|
|
570
|
-
this.logger?.debug('No ignore file found, using defaults');
|
|
571
|
-
}
|
|
572
|
-
}
|
|
573
|
-
|
|
574
|
-
shouldIgnoreFile(filePath) {
|
|
575
|
-
const relativePath = path.relative(this.rootDir, filePath);
|
|
576
|
-
return this.ignorePatterns.some(pattern => {
|
|
577
|
-
if (pattern.includes('*')) {
|
|
578
|
-
const regex = new RegExp(pattern.replace(/\*/g, '.*'));
|
|
579
|
-
return regex.test(relativePath) || regex.test(path.basename(filePath));
|
|
580
|
-
}
|
|
581
|
-
return relativePath.includes(pattern) || path.basename(filePath) === pattern;
|
|
582
|
-
});
|
|
583
|
-
}
|
|
584
|
-
|
|
585
|
-
async getAllFiles(dir) {
|
|
586
|
-
const files = [];
|
|
587
|
-
|
|
588
|
-
const traverse = async (currentDir) => {
|
|
589
|
-
try {
|
|
590
|
-
const entries = await fs.readdir(currentDir, { withFileTypes: true });
|
|
591
|
-
|
|
592
|
-
for (const entry of entries) {
|
|
593
|
-
const fullPath = path.join(currentDir, entry.name);
|
|
594
|
-
|
|
595
|
-
if (this.shouldIgnoreFile(fullPath)) {
|
|
596
|
-
continue;
|
|
597
|
-
}
|
|
598
|
-
|
|
599
|
-
if (entry.isDirectory()) {
|
|
600
|
-
await traverse(fullPath);
|
|
601
|
-
} else if (entry.isFile()) {
|
|
602
|
-
const ext = path.extname(entry.name);
|
|
603
|
-
if (ANALYZER_CONFIG.SUPPORTED_EXTENSIONS.includes(ext)) {
|
|
604
|
-
files.push(fullPath);
|
|
605
|
-
}
|
|
606
|
-
}
|
|
607
|
-
}
|
|
608
|
-
} catch (error) {
|
|
609
|
-
// Skip directories we can't read
|
|
610
|
-
this.logger?.warn('Cannot read directory', { dir: currentDir, error: error.message });
|
|
611
|
-
}
|
|
612
|
-
};
|
|
613
|
-
|
|
614
|
-
await traverse(dir);
|
|
615
|
-
|
|
616
|
-
// Safety check
|
|
617
|
-
if (files.length > ANALYZER_CONFIG.MAX_FILES) {
|
|
618
|
-
this.logger?.warn(`File count exceeds limit: ${files.length} > ${ANALYZER_CONFIG.MAX_FILES}`);
|
|
619
|
-
throw new Error(`Too many files to analyze: ${files.length} (max: ${ANALYZER_CONFIG.MAX_FILES})`);
|
|
620
|
-
}
|
|
621
|
-
|
|
622
|
-
return files;
|
|
623
|
-
}
|
|
624
|
-
|
|
625
|
-
async parseImports(content, filePath) {
|
|
626
|
-
const imports = [];
|
|
627
|
-
const lines = content.split('\n');
|
|
628
|
-
const relativePath = this.getRelativePath(filePath);
|
|
629
|
-
|
|
630
|
-
// Track dependencies for circular detection
|
|
631
|
-
if (!this.dependencies.has(relativePath)) {
|
|
632
|
-
this.dependencies.set(relativePath, new Set());
|
|
633
|
-
}
|
|
634
|
-
|
|
635
|
-
for (let i = 0; i < lines.length; i++) {
|
|
636
|
-
const line = lines[i].trim();
|
|
637
|
-
|
|
638
|
-
if (line.startsWith('//') || line.startsWith('/*')) continue;
|
|
639
|
-
|
|
640
|
-
// Build multi-line statements
|
|
641
|
-
let fullStatement = line;
|
|
642
|
-
let j = i;
|
|
643
|
-
while (!fullStatement.includes(';') && !fullStatement.match(/from\s+['"`][^'"`]+['"`]/) && j < lines.length - 1) {
|
|
644
|
-
j++;
|
|
645
|
-
const nextLine = lines[j].trim();
|
|
646
|
-
// Skip commented lines when building multi-line statements
|
|
647
|
-
if (nextLine.startsWith('//') || nextLine.startsWith('/*')) {
|
|
648
|
-
continue;
|
|
649
|
-
}
|
|
650
|
-
fullStatement += ' ' + nextLine;
|
|
651
|
-
}
|
|
652
|
-
|
|
653
|
-
// ES6 imports
|
|
654
|
-
const importRegex = /import\s+(?:(?:\{([^}]+)\})|(?:([^,\s]+)(?:\s*,\s*\{([^}]+)\})?)|(?:\*\s+as\s+([^,\s]+)))\s+from\s+['"`]([^'"`]+)['"`]/g;
|
|
655
|
-
let match;
|
|
656
|
-
|
|
657
|
-
while ((match = importRegex.exec(fullStatement)) !== null) {
|
|
658
|
-
const [, namedImports, defaultImport, additionalNamed, namespaceImport, source] = match;
|
|
659
|
-
const resolvedSource = await this.resolveImportPath(source, filePath);
|
|
660
|
-
|
|
661
|
-
// Track dependency
|
|
662
|
-
if (!resolvedSource.isExternal && resolvedSource.exists) {
|
|
663
|
-
this.dependencies.get(relativePath).add(resolvedSource.path);
|
|
664
|
-
}
|
|
665
|
-
|
|
666
|
-
if (defaultImport) {
|
|
667
|
-
imports.push({
|
|
668
|
-
importingFile: relativePath,
|
|
669
|
-
importedSymbol: defaultImport.trim(),
|
|
670
|
-
importedFromFile: resolvedSource.path,
|
|
671
|
-
fileExists: resolvedSource.exists,
|
|
672
|
-
isExternal: resolvedSource.isExternal || false,
|
|
673
|
-
isDefault: true
|
|
674
|
-
});
|
|
675
|
-
}
|
|
676
|
-
|
|
677
|
-
if (namespaceImport) {
|
|
678
|
-
imports.push({
|
|
679
|
-
importingFile: relativePath,
|
|
680
|
-
importedSymbol: namespaceImport.trim(),
|
|
681
|
-
importedFromFile: resolvedSource.path,
|
|
682
|
-
fileExists: resolvedSource.exists,
|
|
683
|
-
isExternal: resolvedSource.isExternal || false,
|
|
684
|
-
isNamespace: true
|
|
685
|
-
});
|
|
686
|
-
}
|
|
687
|
-
|
|
688
|
-
const allNamedImports = [namedImports, additionalNamed].filter(Boolean).join(',');
|
|
689
|
-
if (allNamedImports) {
|
|
690
|
-
const symbols = allNamedImports.split(',').map(s => {
|
|
691
|
-
const parts = s.trim().split(/\s+as\s+/);
|
|
692
|
-
return parts[0].trim();
|
|
693
|
-
});
|
|
694
|
-
|
|
695
|
-
symbols.forEach(symbol => {
|
|
696
|
-
if (symbol) {
|
|
697
|
-
imports.push({
|
|
698
|
-
importingFile: relativePath,
|
|
699
|
-
importedSymbol: symbol,
|
|
700
|
-
importedFromFile: resolvedSource.path,
|
|
701
|
-
fileExists: resolvedSource.exists,
|
|
702
|
-
isExternal: resolvedSource.isExternal || false,
|
|
703
|
-
isDefault: false
|
|
704
|
-
});
|
|
705
|
-
}
|
|
706
|
-
});
|
|
707
|
-
}
|
|
708
|
-
}
|
|
709
|
-
|
|
710
|
-
// CommonJS requires
|
|
711
|
-
const requireRegex = /(?:const|let|var)\s+(?:\{([^}]+)\}|([^=\s]+))\s*=\s*require\(['"`]([^'"`]+)['"`]\)/g;
|
|
712
|
-
while ((match = requireRegex.exec(fullStatement)) !== null) {
|
|
713
|
-
const [, destructured, variable, source] = match;
|
|
714
|
-
const resolvedSource = await this.resolveImportPath(source, filePath);
|
|
715
|
-
|
|
716
|
-
// Track dependency
|
|
717
|
-
if (!resolvedSource.isExternal && resolvedSource.exists) {
|
|
718
|
-
this.dependencies.get(relativePath).add(resolvedSource.path);
|
|
719
|
-
}
|
|
720
|
-
|
|
721
|
-
if (destructured) {
|
|
722
|
-
const symbols = destructured.split(',').map(s => s.trim().split(':')[0].trim());
|
|
723
|
-
symbols.forEach(symbol => {
|
|
724
|
-
if (symbol) {
|
|
725
|
-
imports.push({
|
|
726
|
-
importingFile: relativePath,
|
|
727
|
-
importedSymbol: symbol,
|
|
728
|
-
importedFromFile: resolvedSource.path,
|
|
729
|
-
fileExists: resolvedSource.exists,
|
|
730
|
-
isExternal: resolvedSource.isExternal || false,
|
|
731
|
-
isDefault: false
|
|
732
|
-
});
|
|
733
|
-
}
|
|
734
|
-
});
|
|
735
|
-
} else if (variable) {
|
|
736
|
-
imports.push({
|
|
737
|
-
importingFile: relativePath,
|
|
738
|
-
importedSymbol: variable.trim(),
|
|
739
|
-
importedFromFile: resolvedSource.path,
|
|
740
|
-
fileExists: resolvedSource.exists,
|
|
741
|
-
isExternal: resolvedSource.isExternal || false,
|
|
742
|
-
isDefault: true
|
|
743
|
-
});
|
|
744
|
-
}
|
|
745
|
-
}
|
|
746
|
-
|
|
747
|
-
// Skip lines that were already processed as part of multi-line statement
|
|
748
|
-
i = j;
|
|
749
|
-
}
|
|
750
|
-
|
|
751
|
-
return imports;
|
|
752
|
-
}
|
|
753
|
-
|
|
754
|
-
parseExports(content) {
|
|
755
|
-
const exports = new Set();
|
|
756
|
-
const lines = content.split('\n');
|
|
757
|
-
|
|
758
|
-
for (const line of lines) {
|
|
759
|
-
const trimmedLine = line.trim();
|
|
760
|
-
|
|
761
|
-
if (trimmedLine.startsWith('//') || trimmedLine.startsWith('/*')) continue;
|
|
762
|
-
|
|
763
|
-
// Export default
|
|
764
|
-
if (/export\s+default\s+/.test(trimmedLine)) {
|
|
765
|
-
exports.add('default');
|
|
766
|
-
}
|
|
767
|
-
|
|
768
|
-
// Named exports
|
|
769
|
-
const namedExportMatch = trimmedLine.match(/export\s+\{([^}]+)\}/);
|
|
770
|
-
if (namedExportMatch) {
|
|
771
|
-
const symbols = namedExportMatch[1].split(',').map(s => {
|
|
772
|
-
const parts = s.trim().split(/\s+as\s+/);
|
|
773
|
-
return parts[parts.length - 1].trim();
|
|
774
|
-
});
|
|
775
|
-
symbols.forEach(symbol => exports.add(symbol));
|
|
776
|
-
}
|
|
777
|
-
|
|
778
|
-
// Direct exports
|
|
779
|
-
const directExportMatch = trimmedLine.match(/export\s+(?:const|let|var|function|class|async\s+function)\s+([^=\s(]+)/);
|
|
780
|
-
if (directExportMatch) {
|
|
781
|
-
exports.add(directExportMatch[1]);
|
|
782
|
-
}
|
|
783
|
-
|
|
784
|
-
// Export from
|
|
785
|
-
const exportFromMatch = trimmedLine.match(/export\s+\{([^}]+)\}\s+from/);
|
|
786
|
-
if (exportFromMatch) {
|
|
787
|
-
const symbols = exportFromMatch[1].split(',').map(s => {
|
|
788
|
-
const parts = s.trim().split(/\s+as\s+/);
|
|
789
|
-
return parts[parts.length - 1].trim();
|
|
790
|
-
});
|
|
791
|
-
symbols.forEach(symbol => exports.add(symbol));
|
|
792
|
-
}
|
|
793
|
-
|
|
794
|
-
// Export all
|
|
795
|
-
if (/export\s+\*\s+from/.test(trimmedLine)) {
|
|
796
|
-
exports.add('*');
|
|
797
|
-
}
|
|
798
|
-
|
|
799
|
-
// CommonJS exports
|
|
800
|
-
const moduleExportsMatch = trimmedLine.match(/module\.exports\s*=\s*\{([^}]+)\}/);
|
|
801
|
-
if (moduleExportsMatch) {
|
|
802
|
-
const symbols = moduleExportsMatch[1].split(',').map(s => {
|
|
803
|
-
const parts = s.trim().split(':');
|
|
804
|
-
return parts[0].trim();
|
|
805
|
-
});
|
|
806
|
-
symbols.forEach(symbol => exports.add(symbol));
|
|
807
|
-
}
|
|
808
|
-
|
|
809
|
-
if (/module\.exports\s*=\s*[^{]/.test(trimmedLine)) {
|
|
810
|
-
exports.add('default');
|
|
811
|
-
}
|
|
812
|
-
|
|
813
|
-
const moduleExportsPropMatch = trimmedLine.match(/module\.exports\.([^=\s]+)\s*=/);
|
|
814
|
-
if (moduleExportsPropMatch) {
|
|
815
|
-
exports.add(moduleExportsPropMatch[1]);
|
|
816
|
-
}
|
|
817
|
-
|
|
818
|
-
const exportsPropMatch = trimmedLine.match(/exports\.([^=\s]+)\s*=/);
|
|
819
|
-
if (exportsPropMatch) {
|
|
820
|
-
exports.add(exportsPropMatch[1]);
|
|
821
|
-
}
|
|
822
|
-
}
|
|
823
|
-
|
|
824
|
-
return exports;
|
|
825
|
-
}
|
|
826
|
-
|
|
827
|
-
async resolveImportPath(importPath, currentFile) {
|
|
828
|
-
if (importPath.startsWith('.')) {
|
|
829
|
-
const currentDir = path.dirname(currentFile);
|
|
830
|
-
const resolved = path.resolve(currentDir, importPath);
|
|
831
|
-
|
|
832
|
-
// Try with extension first if provided
|
|
833
|
-
if (path.extname(importPath)) {
|
|
834
|
-
try {
|
|
835
|
-
const stat = await fs.stat(resolved);
|
|
836
|
-
if (stat.isFile()) {
|
|
837
|
-
return {
|
|
838
|
-
path: this.getRelativePath(resolved),
|
|
839
|
-
exists: true
|
|
840
|
-
};
|
|
841
|
-
}
|
|
842
|
-
} catch {
|
|
843
|
-
// File doesn't exist
|
|
844
|
-
}
|
|
845
|
-
}
|
|
846
|
-
|
|
847
|
-
// Try different extensions
|
|
848
|
-
const extensions = ['', '.js', '.mjs', '.ts', '.jsx', '.tsx', '/index.js', '/index.ts', '/index.jsx', '/index.tsx'];
|
|
849
|
-
for (const ext of extensions) {
|
|
850
|
-
const withExt = resolved + ext;
|
|
851
|
-
try {
|
|
852
|
-
const stat = await fs.stat(withExt);
|
|
853
|
-
if (stat.isFile()) {
|
|
854
|
-
return {
|
|
855
|
-
path: this.getRelativePath(withExt),
|
|
856
|
-
exists: true
|
|
857
|
-
};
|
|
858
|
-
}
|
|
859
|
-
} catch {
|
|
860
|
-
// Try next
|
|
861
|
-
}
|
|
862
|
-
}
|
|
863
|
-
|
|
864
|
-
return {
|
|
865
|
-
path: this.getRelativePath(resolved),
|
|
866
|
-
exists: false
|
|
867
|
-
};
|
|
868
|
-
}
|
|
869
|
-
|
|
870
|
-
// Node modules or absolute imports
|
|
871
|
-
return {
|
|
872
|
-
path: importPath,
|
|
873
|
-
exists: true,
|
|
874
|
-
isExternal: true
|
|
875
|
-
};
|
|
876
|
-
}
|
|
877
|
-
|
|
878
|
-
getRelativePath(filePath) {
|
|
879
|
-
return path.relative(this.rootDir, filePath).replace(/\\/g, '/');
|
|
880
|
-
}
|
|
881
|
-
|
|
882
|
-
findCircularDependencies() {
|
|
883
|
-
const cycles = [];
|
|
884
|
-
const visited = new Set();
|
|
885
|
-
const recursionStack = new Set();
|
|
886
|
-
|
|
887
|
-
const dfs = (node, path = []) => {
|
|
888
|
-
if (recursionStack.has(node)) {
|
|
889
|
-
const cycleStart = path.indexOf(node);
|
|
890
|
-
if (cycleStart !== -1) {
|
|
891
|
-
cycles.push([...path.slice(cycleStart), node]);
|
|
892
|
-
}
|
|
893
|
-
return;
|
|
894
|
-
}
|
|
895
|
-
|
|
896
|
-
if (visited.has(node)) {
|
|
897
|
-
return;
|
|
898
|
-
}
|
|
899
|
-
|
|
900
|
-
visited.add(node);
|
|
901
|
-
recursionStack.add(node);
|
|
902
|
-
path.push(node);
|
|
903
|
-
|
|
904
|
-
const deps = this.dependencies.get(node) || new Set();
|
|
905
|
-
for (const dep of deps) {
|
|
906
|
-
dfs(dep, [...path]);
|
|
907
|
-
}
|
|
908
|
-
|
|
909
|
-
recursionStack.delete(node);
|
|
910
|
-
};
|
|
911
|
-
|
|
912
|
-
for (const node of this.dependencies.keys()) {
|
|
913
|
-
if (!visited.has(node)) {
|
|
914
|
-
dfs(node);
|
|
915
|
-
}
|
|
916
|
-
}
|
|
917
|
-
|
|
918
|
-
return cycles;
|
|
919
|
-
}
|
|
920
|
-
|
|
921
|
-
findUnusedExports() {
|
|
922
|
-
const usedExports = new Map();
|
|
923
|
-
|
|
924
|
-
// Track which exports are actually imported
|
|
925
|
-
for (const imp of this.imports) {
|
|
926
|
-
if (!imp.isExternal) {
|
|
927
|
-
if (!usedExports.has(imp.importedFromFile)) {
|
|
928
|
-
usedExports.set(imp.importedFromFile, new Set());
|
|
929
|
-
}
|
|
930
|
-
usedExports.get(imp.importedFromFile).add(imp.importedSymbol);
|
|
931
|
-
}
|
|
932
|
-
}
|
|
933
|
-
|
|
934
|
-
// Find exports that are never imported
|
|
935
|
-
const unusedExports = {};
|
|
936
|
-
for (const [file, exports] of this.exports.entries()) {
|
|
937
|
-
const used = usedExports.get(file) || new Set();
|
|
938
|
-
const unused = Array.from(exports).filter(exp => !used.has(exp) && exp !== '*');
|
|
939
|
-
|
|
940
|
-
if (unused.length > 0) {
|
|
941
|
-
unusedExports[file] = unused;
|
|
942
|
-
}
|
|
943
|
-
}
|
|
944
|
-
|
|
945
|
-
return unusedExports;
|
|
946
|
-
}
|
|
947
|
-
|
|
948
|
-
async analyze(mode = 'full') {
|
|
949
|
-
this.logger?.info('Starting import analysis', { mode, rootDir: this.rootDir });
|
|
950
|
-
|
|
951
|
-
await this.loadIgnoreFile();
|
|
952
|
-
|
|
953
|
-
const files = await this.getAllFiles(this.rootDir);
|
|
954
|
-
this.logger?.info('Found files', { count: files.length });
|
|
955
|
-
|
|
956
|
-
// Parse all files
|
|
957
|
-
for (const file of files) {
|
|
958
|
-
try {
|
|
959
|
-
const content = await fs.readFile(file, 'utf-8');
|
|
960
|
-
const relativeFile = this.getRelativePath(file);
|
|
961
|
-
|
|
962
|
-
const fileImports = await this.parseImports(content, file);
|
|
963
|
-
this.imports.push(...fileImports);
|
|
964
|
-
|
|
965
|
-
const fileExports = this.parseExports(content);
|
|
966
|
-
this.exports.set(relativeFile, fileExports);
|
|
967
|
-
} catch (error) {
|
|
968
|
-
// Skip files with errors
|
|
969
|
-
this.logger?.warn('Error parsing file', { file, error: error.message });
|
|
970
|
-
}
|
|
971
|
-
}
|
|
972
|
-
|
|
973
|
-
this.logger?.info('Parsed all files', { imports: this.imports.length, exports: this.exports.size });
|
|
974
|
-
|
|
975
|
-
// Analyze issues
|
|
976
|
-
const results = {
|
|
977
|
-
summary: {
|
|
978
|
-
totalFiles: files.length,
|
|
979
|
-
totalImports: this.imports.length,
|
|
980
|
-
totalExports: Array.from(this.exports.values()).reduce((sum, exports) => sum + exports.size, 0)
|
|
981
|
-
},
|
|
982
|
-
missingExports: {},
|
|
983
|
-
missingFiles: {},
|
|
984
|
-
fileNotFoundImports: []
|
|
985
|
-
};
|
|
986
|
-
|
|
987
|
-
// Check imports
|
|
988
|
-
for (const importEntry of this.imports) {
|
|
989
|
-
const { importingFile, importedSymbol, importedFromFile, isDefault, isNamespace, fileExists, isExternal } = importEntry;
|
|
990
|
-
|
|
991
|
-
if (!fileExists && !isExternal) {
|
|
992
|
-
results.fileNotFoundImports.push({
|
|
993
|
-
importingFile,
|
|
994
|
-
importedSymbol,
|
|
995
|
-
importedFromFile,
|
|
996
|
-
isDefault: isDefault || false,
|
|
997
|
-
isNamespace: isNamespace || false
|
|
998
|
-
});
|
|
999
|
-
|
|
1000
|
-
if (!results.missingFiles[importingFile]) {
|
|
1001
|
-
results.missingFiles[importingFile] = [];
|
|
1002
|
-
}
|
|
1003
|
-
|
|
1004
|
-
results.missingFiles[importingFile].push({
|
|
1005
|
-
missingFile: importedFromFile,
|
|
1006
|
-
importedSymbol,
|
|
1007
|
-
isDefault: isDefault || false,
|
|
1008
|
-
isNamespace: isNamespace || false
|
|
1009
|
-
});
|
|
1010
|
-
|
|
1011
|
-
continue;
|
|
1012
|
-
}
|
|
1013
|
-
|
|
1014
|
-
if (isExternal) continue;
|
|
1015
|
-
|
|
1016
|
-
const exportingFileExports = this.exports.get(importedFromFile);
|
|
1017
|
-
let exists = false;
|
|
1018
|
-
|
|
1019
|
-
if (exportingFileExports) {
|
|
1020
|
-
if (isNamespace) {
|
|
1021
|
-
exists = exportingFileExports.size > 0;
|
|
1022
|
-
} else if (isDefault) {
|
|
1023
|
-
exists = exportingFileExports.has('default');
|
|
1024
|
-
} else {
|
|
1025
|
-
exists = exportingFileExports.has(importedSymbol) || exportingFileExports.has('*');
|
|
1026
|
-
}
|
|
1027
|
-
}
|
|
1028
|
-
|
|
1029
|
-
if (!exists) {
|
|
1030
|
-
if (!results.missingExports[importingFile]) {
|
|
1031
|
-
results.missingExports[importingFile] = [];
|
|
1032
|
-
}
|
|
1033
|
-
|
|
1034
|
-
results.missingExports[importingFile].push({
|
|
1035
|
-
importedSymbol,
|
|
1036
|
-
importedFromFile,
|
|
1037
|
-
availableExports: exportingFileExports ? Array.from(exportingFileExports) : [],
|
|
1038
|
-
isDefault: isDefault || false,
|
|
1039
|
-
isNamespace: isNamespace || false
|
|
1040
|
-
});
|
|
1041
|
-
}
|
|
1042
|
-
}
|
|
1043
|
-
|
|
1044
|
-
// Additional analysis for full mode
|
|
1045
|
-
if (mode === 'full' || mode === 'fix') {
|
|
1046
|
-
this.logger?.info('Running full analysis');
|
|
1047
|
-
results.circularDependencies = this.findCircularDependencies();
|
|
1048
|
-
results.unusedExports = this.findUnusedExports();
|
|
1049
|
-
}
|
|
1050
|
-
|
|
1051
|
-
this.logger?.info('Analysis complete', {
|
|
1052
|
-
missingFiles: results.fileNotFoundImports.length,
|
|
1053
|
-
missingExports: Object.keys(results.missingExports).length
|
|
1054
|
-
});
|
|
1055
|
-
|
|
1056
|
-
return results;
|
|
1057
|
-
}
|
|
1058
|
-
}
|
|
1059
|
-
|
|
1060
|
-
export default ImportAnalyzerTool;
|
|
1
|
+
const a0_0x5ca787=a0_0x1451;(function(_0x14e71e,_0x52cea4){const _0x67af8e=a0_0x1451,_0x2c3d2=_0x14e71e();while(!![]){try{const _0x47a125=-parseInt(_0x67af8e(0x1e4))/0x1*(-parseInt(_0x67af8e(0x1df))/0x2)+parseInt(_0x67af8e(0x17e))/0x3+-parseInt(_0x67af8e(0x1f8))/0x4*(-parseInt(_0x67af8e(0x18b))/0x5)+parseInt(_0x67af8e(0x1af))/0x6+-parseInt(_0x67af8e(0x1fc))/0x7*(-parseInt(_0x67af8e(0x1d8))/0x8)+parseInt(_0x67af8e(0x1c9))/0x9+-parseInt(_0x67af8e(0x213))/0xa*(parseInt(_0x67af8e(0x191))/0xb);if(_0x47a125===_0x52cea4)break;else _0x2c3d2['push'](_0x2c3d2['shift']());}catch(_0x46b0fb){_0x2c3d2['push'](_0x2c3d2['shift']());}}}(a0_0x4436,0x3a4e2));import{promises as a0_0x388bbf}from'fs';import a0_0x52e509 from'path';import{BaseTool}from'./baseTool.js';import a0_0x3e8737 from'../utilities/tagParser.js';const ANALYZER_CONFIG={'DEFAULT_MODE':'full','VALID_MODES':['full','quick','fix'],'DEFAULT_OUTPUT':a0_0x5ca787(0x1f4),'VALID_OUTPUTS':[a0_0x5ca787(0x1f4),a0_0x5ca787(0x176),'json'],'DEFAULT_IGNORE_FILE':a0_0x5ca787(0x218),'MAX_FILES':0x2710,'SUPPORTED_EXTENSIONS':['.js',a0_0x5ca787(0x1ce),'.ts',a0_0x5ca787(0x1c7),'.tsx'],'DEFAULT_IGNORE_PATTERNS':[a0_0x5ca787(0x1f7),a0_0x5ca787(0x186),a0_0x5ca787(0x1b1),'build',a0_0x5ca787(0x219)],'FILE_READ_TIMEOUT':0x1388};export class ImportAnalyzerTool extends BaseTool{[a0_0x5ca787(0x20a)](){const _0x2373e4=a0_0x5ca787;return _0x2373e4(0x192);}['parseParameters'](_0x4670f0){const _0x2c8a0e=a0_0x5ca787;if(typeof _0x4670f0===_0x2c8a0e(0x1ff)&&_0x4670f0!==null)return{'path':_0x4670f0['path']||'.','mode':_0x4670f0['mode']||ANALYZER_CONFIG[_0x2c8a0e(0x197)],'output':_0x4670f0[_0x2c8a0e(0x179)]||ANALYZER_CONFIG['DEFAULT_OUTPUT'],'ignoreFile':_0x4670f0[_0x2c8a0e(0x19e)]||ANALYZER_CONFIG['DEFAULT_IGNORE_FILE']};if(typeof _0x4670f0===_0x2c8a0e(0x18f)){const _0x48d21e=/<import-analyzer([^>]*)>([\s\S]*?)<\/import-analyzer>/i,_0x508e1d=_0x48d21e['exec'](_0x4670f0);if(_0x508e1d){const _0x3dc16c=_0x508e1d[0x1],_0x488c64=_0x508e1d[0x2],_0x152bf2=/path=["']([^"']*)["']/i[_0x2c8a0e(0x1cb)](_0x3dc16c),_0x2a16e0=/mode=["']([^"']*)["']/i['exec'](_0x3dc16c),_0x3f0e53=/output=["']([^"']*)["']/i[_0x2c8a0e(0x1cb)](_0x3dc16c),_0x241a17=/ignore-file=["']([^"']*)["']/i[_0x2c8a0e(0x1cb)](_0x3dc16c),_0x5716e4=/<path>(.*?)<\/path>/i,_0x3aa1e6=_0x5716e4['exec'](_0x488c64),_0x2ad5f6=/<mode>(.*?)<\/mode>/i,_0xf6e3cb=_0x2ad5f6[_0x2c8a0e(0x1cb)](_0x488c64),_0x254b24=/<output>(.*?)<\/output>/i,_0x1cfd45=_0x254b24[_0x2c8a0e(0x1cb)](_0x488c64),_0x4d64db=/<ignore-file>(.*?)<\/ignore-file>/i,_0x5333=_0x4d64db[_0x2c8a0e(0x1cb)](_0x488c64),_0x456ccf=(_0x3aa1e6?_0x3aa1e6[0x1][_0x2c8a0e(0x1b5)]():null)||(_0x152bf2?_0x152bf2[0x1]:'.'),_0x37ca4f=(_0xf6e3cb?_0xf6e3cb[0x1][_0x2c8a0e(0x1b5)]():null)||(_0x2a16e0?_0x2a16e0[0x1]:ANALYZER_CONFIG['DEFAULT_MODE']),_0x40fc16=(_0x1cfd45?_0x1cfd45[0x1][_0x2c8a0e(0x1b5)]():null)||(_0x3f0e53?_0x3f0e53[0x1]:ANALYZER_CONFIG[_0x2c8a0e(0x1d9)]),_0x350d8b=(_0x5333?_0x5333[0x1]['trim']():null)||(_0x241a17?_0x241a17[0x1]:ANALYZER_CONFIG[_0x2c8a0e(0x17f)]);return{'path':_0x456ccf,'mode':_0x37ca4f,'output':_0x40fc16,'ignoreFile':_0x350d8b};}try{const _0x291d65=a0_0x3e8737[_0x2c8a0e(0x21a)](_0x4670f0,_0x2c8a0e(0x187));if(_0x291d65&&_0x291d65['length']>0x0){const _0x5c9916=_0x291d65[0x0];return{'path':_0x5c9916['attributes'][_0x2c8a0e(0x1c3)]||'.','mode':_0x5c9916[_0x2c8a0e(0x19a)]['mode']||ANALYZER_CONFIG[_0x2c8a0e(0x197)],'output':_0x5c9916['attributes']['output']||ANALYZER_CONFIG[_0x2c8a0e(0x1d9)],'ignoreFile':_0x5c9916[_0x2c8a0e(0x19a)]['ignore-file']||ANALYZER_CONFIG[_0x2c8a0e(0x17f)]};}}catch(_0x566ff9){}throw new Error('Invalid import-analyzer format. Use <import-analyzer> tags or JSON format.');}throw new Error(_0x2c8a0e(0x1d6));}['_validateParameters'](_0x1f0bd2){const _0x18b815=a0_0x5ca787;if(!_0x1f0bd2||typeof _0x1f0bd2!=='object')throw new Error('Parameters\x20must\x20be\x20an\x20object');if(_0x1f0bd2[_0x18b815(0x1c3)]&&typeof _0x1f0bd2['path']!=='string')throw new Error('path\x20must\x20be\x20a\x20string');if(_0x1f0bd2[_0x18b815(0x1e5)]&&!ANALYZER_CONFIG['VALID_MODES']['includes'](_0x1f0bd2['mode']))throw new Error('Invalid\x20mode:\x20'+_0x1f0bd2[_0x18b815(0x1e5)]+_0x18b815(0x1f3)+ANALYZER_CONFIG['VALID_MODES'][_0x18b815(0x1be)](',\x20'));if(_0x1f0bd2[_0x18b815(0x179)]&&!ANALYZER_CONFIG['VALID_OUTPUTS'][_0x18b815(0x1db)](_0x1f0bd2[_0x18b815(0x179)]))throw new Error(_0x18b815(0x19d)+_0x1f0bd2[_0x18b815(0x179)]+'.\x20Must\x20be\x20one\x20of:\x20'+ANALYZER_CONFIG[_0x18b815(0x1d1)]['join'](',\x20'));if(_0x1f0bd2['ignoreFile']&&typeof _0x1f0bd2[_0x18b815(0x19e)]!==_0x18b815(0x18f))throw new Error('ignoreFile\x20must\x20be\x20a\x20string');}[a0_0x5ca787(0x1a1)](_0x67a97d,_0x3fc8d8){const _0xb4a9f1=a0_0x5ca787,{projectDir:_0x2dc812,directoryAccess:_0x201590}=_0x3fc8d8;let _0x3b03a7=_0x2dc812||process[_0xb4a9f1(0x1d5)]();_0x201590&&_0x201590[_0xb4a9f1(0x1bc)]&&(_0x3b03a7=_0x201590[_0xb4a9f1(0x1bc)]);const _0x167802=a0_0x52e509[_0xb4a9f1(0x1b2)](_0x67a97d)?a0_0x52e509['normalize'](_0x67a97d):a0_0x52e509[_0xb4a9f1(0x196)](a0_0x52e509[_0xb4a9f1(0x1be)](_0x3b03a7,_0x67a97d)),_0x39f1d5=a0_0x52e509['normalize'](_0x3b03a7);if(!_0x167802[_0xb4a9f1(0x17a)](_0x39f1d5))throw new Error('Path\x20traversal\x20detected:\x20'+_0x67a97d+'\x20resolves\x20outside\x20working\x20directory');return _0x167802;}async[a0_0x5ca787(0x18e)](_0x348b18,_0x21cd77={}){const _0x42577b=a0_0x5ca787;try{this['_validateParameters'](_0x348b18);const {path:_0x3032f9,mode:_0x46879b,output:_0x4eadc1,ignoreFile:_0x454b52}=_0x348b18,{projectDir:_0x4824e6,agentId:_0x2197a6,directoryAccess:_0x3da82b}=_0x21cd77,_0x2d22aa=this['_resolveAndValidatePath'](_0x3032f9,_0x21cd77);this['logger']?.[_0x42577b(0x1e9)]('Import\x20analyzer\x20executing',{'mode':_0x46879b,'resolvedPath':_0x2d22aa,'output':_0x4eadc1,'agentId':_0x2197a6});const _0x205ca7=[];_0x205ca7['push'](_0x42577b(0x1cc)+_0x2d22aa),_0x205ca7[_0x42577b(0x1ad)](_0x42577b(0x1ed)+_0x46879b),_0x205ca7['push'](_0x42577b(0x177)+_0x4eadc1+'\x0a');try{await a0_0x388bbf['access'](_0x2d22aa);}catch{return{'success':![],'error':_0x42577b(0x20b)+_0x2d22aa,'output':_0x205ca7['join']('\x0a')};}const _0x141daa=new ImportExportAnalyzer(_0x2d22aa,_0x454b52,this['logger']),_0x5a6fa1=await _0x141daa['analyze'](_0x46879b);let _0x1f212c;switch(_0x4eadc1){case _0x42577b(0x198):_0x1f212c=JSON['stringify'](_0x5a6fa1,null,0x2);break;case'detailed':_0x1f212c=this['_formatDetailedOutput'](_0x5a6fa1),_0x205ca7[_0x42577b(0x1ad)](_0x1f212c);break;case _0x42577b(0x1f4):default:_0x1f212c=this['_formatSummaryOutput'](_0x5a6fa1),_0x205ca7['push'](_0x1f212c);break;}return{'success':!![],'mode':_0x46879b,'message':'Import\x20analysis\x20completed','statistics':{'totalFiles':_0x5a6fa1['summary'][_0x42577b(0x201)],'totalImports':_0x5a6fa1[_0x42577b(0x1f4)]['totalImports'],'totalExports':_0x5a6fa1['summary'][_0x42577b(0x212)],'issuesFound':_0x5a6fa1[_0x42577b(0x180)]['length']+Object[_0x42577b(0x200)](_0x5a6fa1[_0x42577b(0x188)])['reduce']((_0x2a8b52,_0x559dfc)=>_0x2a8b52+_0x559dfc['length'],0x0)},'output':_0x4eadc1===_0x42577b(0x198)?_0x1f212c:_0x205ca7[_0x42577b(0x1be)]('\x0a'),'results':_0x5a6fa1};}catch(_0x1b1376){return this['logger']?.['error']('Import\x20analyzer\x20error:',_0x1b1376),{'success':![],'error':_0x1b1376[_0x42577b(0x210)],'output':_0x1b1376[_0x42577b(0x210)]};}}[a0_0x5ca787(0x1f1)](_0x9bc8ec){const _0x2d9cf7=a0_0x5ca787,_0x372448=[];_0x372448[_0x2d9cf7(0x1ad)](_0x2d9cf7(0x1cd)),_0x372448['push']('================================\x0a'),_0x372448[_0x2d9cf7(0x1ad)]('📁\x20Files\x20analyzed:\x20'+_0x9bc8ec['summary'][_0x2d9cf7(0x201)]),_0x372448['push'](_0x2d9cf7(0x1bd)+_0x9bc8ec['summary']['totalImports']),_0x372448[_0x2d9cf7(0x1ad)](_0x2d9cf7(0x184)+_0x9bc8ec['summary'][_0x2d9cf7(0x212)]+'\x0a');const _0x547651=_0x9bc8ec[_0x2d9cf7(0x180)][_0x2d9cf7(0x206)],_0x4ae9df=Object[_0x2d9cf7(0x200)](_0x9bc8ec[_0x2d9cf7(0x188)])['reduce']((_0x16dde0,_0x45abe3)=>_0x16dde0+_0x45abe3['length'],0x0),_0x3a0e84=_0x9bc8ec[_0x2d9cf7(0x20e)]?_0x9bc8ec[_0x2d9cf7(0x20e)][_0x2d9cf7(0x206)]:0x0;return _0x547651>0x0&&_0x372448['push']('❌\x20Missing\x20files:\x20'+_0x547651+_0x2d9cf7(0x203)),_0x4ae9df>0x0&&_0x372448['push']('⚠️\x20\x20Missing\x20exports:\x20'+_0x4ae9df+_0x2d9cf7(0x1a4)),_0x3a0e84>0x0&&_0x372448['push'](_0x2d9cf7(0x20d)+_0x3a0e84+'\x20circular\x20dependency\x20chains\x20detected'),_0x547651===0x0&&_0x4ae9df===0x0&&_0x3a0e84===0x0?_0x372448['push']('\u2705 No import/export issues detected!'):(_0x372448[_0x2d9cf7(0x1ad)]('\x0a🔍\x20Top\x20Issues\x20to\x20Fix:'),Object['keys'](_0x9bc8ec['missingFiles']||{})[_0x2d9cf7(0x206)]>0x0&&(_0x372448[_0x2d9cf7(0x1ad)]('\x0a\x20\x20Missing\x20Files:'),Object[_0x2d9cf7(0x175)](_0x9bc8ec[_0x2d9cf7(0x18a)])['slice'](0x0,0x3)[_0x2d9cf7(0x1bb)](([_0x5d3dde,_0x200573])=>{const _0x10e4b9=_0x2d9cf7;_0x372448[_0x10e4b9(0x1ad)]('\x20\x20\x20\x20•\x20'+_0x5d3dde+'\x20has\x20'+_0x200573[_0x10e4b9(0x206)]+'\x20broken\x20import(s)');})),Object[_0x2d9cf7(0x1a3)](_0x9bc8ec[_0x2d9cf7(0x188)])[_0x2d9cf7(0x206)]>0x0&&(_0x372448['push'](_0x2d9cf7(0x1e7)),Object['entries'](_0x9bc8ec[_0x2d9cf7(0x188)])[_0x2d9cf7(0x1b7)](0x0,0x3)[_0x2d9cf7(0x1bb)](([_0x2a017a,_0x3774bc])=>{const _0x5a8c88=_0x2d9cf7;_0x372448['push'](_0x5a8c88(0x1fa)+_0x2a017a+_0x5a8c88(0x1b9)+_0x3774bc['length']+_0x5a8c88(0x20c));})),_0x372448['push'](_0x2d9cf7(0x171))),_0x372448['join']('\x0a');}[a0_0x5ca787(0x1ba)](_0x297546){const _0x3fa0e8=a0_0x5ca787,_0x3e3190=[];_0x3e3190['push'](_0x3fa0e8(0x1ab)),_0x3e3190[_0x3fa0e8(0x1ad)]('=========================================\x0a'),_0x3e3190[_0x3fa0e8(0x1ad)](_0x3fa0e8(0x1c4)),_0x3e3190[_0x3fa0e8(0x1ad)](_0x3fa0e8(0x1f0)+_0x297546[_0x3fa0e8(0x1f4)][_0x3fa0e8(0x201)]),_0x3e3190[_0x3fa0e8(0x1ad)]('\x20\x20•\x20Total\x20imports:\x20'+_0x297546[_0x3fa0e8(0x1f4)]['totalImports']),_0x3e3190[_0x3fa0e8(0x1ad)](_0x3fa0e8(0x1de)+_0x297546[_0x3fa0e8(0x1f4)][_0x3fa0e8(0x212)]+'\x0a');if(_0x297546[_0x3fa0e8(0x180)]['length']>0x0){_0x3e3190['push'](_0x3fa0e8(0x1a5)),_0x3e3190[_0x3fa0e8(0x1ad)](_0x3fa0e8(0x199));const _0x50c2fe={};_0x297546['fileNotFoundImports']['forEach'](_0x509f3f=>{const _0x4773b3=_0x3fa0e8;!_0x50c2fe[_0x509f3f['importingFile']]&&(_0x50c2fe[_0x509f3f[_0x4773b3(0x207)]]=[]),_0x50c2fe[_0x509f3f[_0x4773b3(0x207)]][_0x4773b3(0x1ad)](_0x509f3f);}),Object['entries'](_0x50c2fe)['forEach'](([_0x21b271,imports])=>{const _0x298a31=_0x3fa0e8;_0x3e3190['push']('\x0a📄\x20'+_0x21b271+':'),imports[_0x298a31(0x1bb)](_0x3caefc=>{const _0x5e0691=_0x298a31,importType=_0x3caefc[_0x5e0691(0x205)]?'default':_0x3caefc[_0x5e0691(0x18c)]?_0x5e0691(0x202):'named';_0x3e3190[_0x5e0691(0x1ad)]('\x20\x20\x20⚠️\x20\x20Cannot\x20find\x20file:\x20'+_0x3caefc[_0x5e0691(0x1f9)]),_0x3e3190[_0x5e0691(0x1ad)](_0x5e0691(0x1a7)+_0x3caefc[_0x5e0691(0x1aa)]+'\x20('+importType+')'),_0x3e3190['push'](_0x5e0691(0x1b8));});});}Object[_0x3fa0e8(0x1a3)](_0x297546['missingExports'])['length']>0x0&&(_0x3e3190['push'](_0x3fa0e8(0x19b)),_0x3e3190['push']('──────────────────'),Object[_0x3fa0e8(0x175)](_0x297546['missingExports'])['forEach'](([_0x303a3c,_0x4aded5])=>{const _0x1522e4=_0x3fa0e8;_0x3e3190['push'](_0x1522e4(0x1ef)+_0x303a3c+':'),_0x4aded5[_0x1522e4(0x1bb)](_0x32500b=>{const _0x517ad6=_0x1522e4,importType=_0x32500b[_0x517ad6(0x205)]?'default':_0x32500b[_0x517ad6(0x18c)]?_0x517ad6(0x202):_0x517ad6(0x1f2);_0x3e3190[_0x517ad6(0x1ad)]('\x20\x20\x20❌\x20Symbol\x20not\x20exported:\x20\x22'+_0x32500b[_0x517ad6(0x1aa)]+_0x517ad6(0x209)+importType+')'),_0x3e3190['push']('\x20\x20\x20\x20\x20\x20From\x20file:\x20'+_0x32500b[_0x517ad6(0x1f9)]);if(_0x32500b[_0x517ad6(0x173)][_0x517ad6(0x206)]>0x0){_0x3e3190['push'](_0x517ad6(0x211)+_0x32500b['availableExports']['join'](',\x20'));if(_0x32500b['isDefault']&&_0x32500b['availableExports']['includes']('default'))_0x3e3190['push'](_0x517ad6(0x215));else{if(_0x32500b[_0x517ad6(0x205)]&&!_0x32500b[_0x517ad6(0x173)]['includes']('default'))_0x3e3190[_0x517ad6(0x1ad)](_0x517ad6(0x1f5)+(_0x32500b[_0x517ad6(0x173)][0x0]||_0x517ad6(0x1ea))+'\x20}');else{const _0x450419=_0x32500b['availableExports'][_0x517ad6(0x1ac)](_0x21d823=>_0x21d823['toLowerCase']()===_0x32500b['importedSymbol'][_0x517ad6(0x216)]());_0x450419?_0x3e3190['push']('\x20\x20\x20\x20\x20\x20💡\x20Fix:\x20Did\x20you\x20mean\x20\x22'+_0x450419+_0x517ad6(0x1e3)):_0x3e3190[_0x517ad6(0x1ad)](_0x517ad6(0x1c8)+_0x32500b[_0x517ad6(0x1aa)]+_0x517ad6(0x189));}}}else _0x3e3190[_0x517ad6(0x1ad)]('\x20\x20\x20\x20\x20\x20📤\x20No\x20exports\x20found\x20in\x20target\x20file'),_0x3e3190[_0x517ad6(0x1ad)]('\x20\x20\x20\x20\x20\x20💡\x20Fix:\x20Add\x20exports\x20to\x20'+_0x32500b[_0x517ad6(0x1f9)]+'\x20or\x20check\x20if\x20it\x27s\x20the\x20correct\x20file');});}));_0x297546[_0x3fa0e8(0x20e)]&&_0x297546['circularDependencies']['length']>0x0&&(_0x3e3190[_0x3fa0e8(0x1ad)](_0x3fa0e8(0x20f)),_0x3e3190['push'](_0x3fa0e8(0x174)),_0x297546['circularDependencies'][_0x3fa0e8(0x1bb)]((_0x10e5cf,_0x21968f)=>{_0x3e3190['push']('\x0a\x20\x20Cycle\x20'+(_0x21968f+0x1)+':'),_0x10e5cf['forEach']((_0x206541,_0x527e52)=>{const _0x3d0570=a0_0x1451;_0x527e52<_0x10e5cf[_0x3d0570(0x206)]-0x1&&_0x3e3190['push'](_0x3d0570(0x17c)+_0x206541+_0x3d0570(0x1eb)+_0x10e5cf[_0x527e52+0x1]);}),_0x3e3190['push']('\x20\x20\x20\x20💡\x20Fix:\x20Refactor\x20to\x20break\x20the\x20circular\x20dependency');}));_0x297546[_0x3fa0e8(0x214)]&&Object['keys'](_0x297546['unusedExports'])['length']>0x0&&(_0x3e3190['push'](_0x3fa0e8(0x182)),_0x3e3190[_0x3fa0e8(0x1ad)](_0x3fa0e8(0x1e2)),Object['entries'](_0x297546[_0x3fa0e8(0x214)])[_0x3fa0e8(0x1b7)](0x0,0xa)[_0x3fa0e8(0x1bb)](([_0x13c656,exports])=>{const _0x394807=_0x3fa0e8;_0x3e3190['push']('\x0a📄\x20'+_0x13c656+':'),_0x3e3190[_0x394807(0x1ad)](_0x394807(0x17d)+exports[_0x394807(0x1be)](',\x20'));}),_0x3e3190[_0x3fa0e8(0x1ad)]('\n \uD83D\uDCA1 Note: These exports are not imported within this project'),_0x3e3190[_0x3fa0e8(0x1ad)]('\x20\x20\x20\x20\x20\x20They\x20might\x20be\x20used\x20by\x20external\x20packages\x20or\x20could\x20be\x20removed'));_0x3e3190['push']('\x0a📋\x20RECOMMENDATIONS'),_0x3e3190['push']('──────────────────');const _0x32c6ce=_0x297546[_0x3fa0e8(0x180)][_0x3fa0e8(0x206)]+Object['values'](_0x297546['missingExports'])[_0x3fa0e8(0x1e6)]((_0x365276,_0x1efe65)=>_0x365276+_0x1efe65['length'],0x0);return _0x32c6ce===0x0?_0x3e3190['push']('\u2705 Your import/export structure looks good!'):(_0x3e3190['push']('Found\x20'+_0x32c6ce+'\x20issue(s)\x20that\x20need\x20attention:'),_0x297546['fileNotFoundImports']['length']>0x0&&_0x3e3190[_0x3fa0e8(0x1ad)]('\x20\x201.\x20Fix\x20'+_0x297546[_0x3fa0e8(0x180)][_0x3fa0e8(0x206)]+_0x3fa0e8(0x208)),Object[_0x3fa0e8(0x1a3)](_0x297546['missingExports'])['length']>0x0&&_0x3e3190['push'](_0x3fa0e8(0x183)+Object['values'](_0x297546['missingExports'])['reduce']((_0x2237e8,_0x3dd315)=>_0x2237e8+_0x3dd315[_0x3fa0e8(0x206)],0x0)+_0x3fa0e8(0x1e0)),_0x297546['circularDependencies']&&_0x297546['circularDependencies']['length']>0x0&&_0x3e3190['push'](_0x3fa0e8(0x1cf)+_0x297546[_0x3fa0e8(0x20e)]['length']+_0x3fa0e8(0x1c5))),_0x3e3190['join']('\x0a');}}class ImportExportAnalyzer{constructor(_0x4d297b,_0x53cf67=a0_0x5ca787(0x218),_0x38f82e=null){const _0x3b9a14=a0_0x5ca787;this[_0x3b9a14(0x195)]=a0_0x52e509['resolve'](_0x4d297b),this[_0x3b9a14(0x19e)]=_0x53cf67,this[_0x3b9a14(0x1a6)]=_0x38f82e,this[_0x3b9a14(0x170)]=[...ANALYZER_CONFIG['DEFAULT_IGNORE_PATTERNS']],this['imports']=[],this[_0x3b9a14(0x1c1)]=new Map(),this[_0x3b9a14(0x17b)]=new Map();}async['loadIgnoreFile'](){const _0xd625cc=a0_0x5ca787;try{const _0x1d6055=a0_0x52e509['join'](this[_0xd625cc(0x195)],this[_0xd625cc(0x19e)]),_0x231d3e=await a0_0x388bbf[_0xd625cc(0x19c)](_0x1d6055,'utf-8'),_0x140440=_0x231d3e[_0xd625cc(0x1b3)]('\x0a')[_0xd625cc(0x1b4)](_0x580ece=>_0x580ece[_0xd625cc(0x1b5)]())[_0xd625cc(0x1b0)](_0x4af990=>_0x4af990&&!_0x4af990[_0xd625cc(0x17a)]('#'));this[_0xd625cc(0x170)]['push'](..._0x140440),this[_0xd625cc(0x1a6)]?.['debug']('Loaded\x20ignore\x20patterns',{'count':_0x140440[_0xd625cc(0x206)]});}catch{this['logger']?.[_0xd625cc(0x1d3)]('No ignore file found, using defaults');}}['shouldIgnoreFile'](_0x57f542){const _0x5ad232=a0_0x5ca787,_0x18d602=a0_0x52e509[_0x5ad232(0x1ca)](this[_0x5ad232(0x195)],_0x57f542);return this[_0x5ad232(0x170)][_0x5ad232(0x1d4)](_0x24a0c0=>{const _0x12a76c=_0x5ad232;if(_0x24a0c0['includes']('*')){const _0x25a3b7=new RegExp(_0x24a0c0['replace'](/\*/g,'.*'));return _0x25a3b7[_0x12a76c(0x1ee)](_0x18d602)||_0x25a3b7['test'](a0_0x52e509[_0x12a76c(0x1fd)](_0x57f542));}return _0x18d602[_0x12a76c(0x1db)](_0x24a0c0)||a0_0x52e509['basename'](_0x57f542)===_0x24a0c0;});}async[a0_0x5ca787(0x1a2)](_0x36a7e8){const _0x52c6a6=a0_0x5ca787,_0x853c7d=[],_0xae8197=async _0x4681df=>{const _0xf58cc5=a0_0x1451;try{const _0x27aaa9=await a0_0x388bbf['readdir'](_0x4681df,{'withFileTypes':!![]});for(const _0x2ee945 of _0x27aaa9){const _0x4b0a5f=a0_0x52e509['join'](_0x4681df,_0x2ee945[_0xf58cc5(0x1a0)]);if(this[_0xf58cc5(0x178)](_0x4b0a5f))continue;if(_0x2ee945['isDirectory']())await _0xae8197(_0x4b0a5f);else{if(_0x2ee945['isFile']()){const _0x381b58=a0_0x52e509[_0xf58cc5(0x1c6)](_0x2ee945['name']);ANALYZER_CONFIG['SUPPORTED_EXTENSIONS']['includes'](_0x381b58)&&_0x853c7d['push'](_0x4b0a5f);}}}}catch(_0x49811a){this['logger']?.['warn']('Cannot\x20read\x20directory',{'dir':_0x4681df,'error':_0x49811a[_0xf58cc5(0x210)]});}};await _0xae8197(_0x36a7e8);if(_0x853c7d['length']>ANALYZER_CONFIG['MAX_FILES']){this[_0x52c6a6(0x1a6)]?.[_0x52c6a6(0x1b6)](_0x52c6a6(0x190)+_0x853c7d[_0x52c6a6(0x206)]+'\x20>\x20'+ANALYZER_CONFIG['MAX_FILES']);throw new Error(_0x52c6a6(0x204)+_0x853c7d['length']+'\x20(max:\x20'+ANALYZER_CONFIG['MAX_FILES']+')');}return _0x853c7d;}async[a0_0x5ca787(0x1da)](_0x508fab,_0x42b74a){const _0x5c868e=a0_0x5ca787,imports=[],_0x4061be=_0x508fab['split']('\x0a'),_0x44ce37=this['getRelativePath'](_0x42b74a);!this['dependencies']['has'](_0x44ce37)&&this['dependencies']['set'](_0x44ce37,new Set());for(let _0xf1a042=0x0;_0xf1a042<_0x4061be[_0x5c868e(0x206)];_0xf1a042++){const _0x21eda3=_0x4061be[_0xf1a042][_0x5c868e(0x1b5)]();if(_0x21eda3[_0x5c868e(0x17a)]('//')||_0x21eda3['startsWith']('/*'))continue;let _0x288898=_0x21eda3,_0x16ba05=_0xf1a042;while(!_0x288898['includes'](';')&&!_0x288898[_0x5c868e(0x217)](/from\s+['"`][^'"`]+['"`]/)&&_0x16ba05<_0x4061be['length']-0x1){_0x16ba05++;const _0x150800=_0x4061be[_0x16ba05][_0x5c868e(0x1b5)]();if(_0x150800[_0x5c868e(0x17a)]('//')||_0x150800['startsWith']('/*'))continue;_0x288898+='\x20'+_0x150800;}const importRegex=/import\s+(?:(?:\{([^}]+)\})|(?:([^,\s]+)(?:\s*,\s*\{([^}]+)\})?)|(?:\*\s+as\s+([^,\s]+)))\s+from\s+['"`]([^'"`]+)['"`]/g;let _0x262b3a;while((_0x262b3a=importRegex['exec'](_0x288898))!==null){const [,_0x107168,defaultImport,_0x2263d5,_0x3fae44,_0x61f8ea]=_0x262b3a,_0x15edae=await this[_0x5c868e(0x1e8)](_0x61f8ea,_0x42b74a);!_0x15edae['isExternal']&&_0x15edae['exists']&&this[_0x5c868e(0x17b)]['get'](_0x44ce37)['add'](_0x15edae['path']);defaultImport&&imports[_0x5c868e(0x1ad)]({'importingFile':_0x44ce37,'importedSymbol':defaultImport[_0x5c868e(0x1b5)](),'importedFromFile':_0x15edae['path'],'fileExists':_0x15edae[_0x5c868e(0x1d7)],'isExternal':_0x15edae['isExternal']||![],'isDefault':!![]});_0x3fae44&&imports['push']({'importingFile':_0x44ce37,'importedSymbol':_0x3fae44['trim'](),'importedFromFile':_0x15edae['path'],'fileExists':_0x15edae[_0x5c868e(0x1d7)],'isExternal':_0x15edae[_0x5c868e(0x1d0)]||![],'isNamespace':!![]});const _0x2f6880=[_0x107168,_0x2263d5]['filter'](Boolean)['join'](',');if(_0x2f6880){const _0x391e3b=_0x2f6880['split'](',')[_0x5c868e(0x1b4)](_0x22756b=>{const _0x53e908=_0x5c868e,_0xa87fc8=_0x22756b[_0x53e908(0x1b5)]()['split'](/\s+as\s+/);return _0xa87fc8[0x0]['trim']();});_0x391e3b['forEach'](_0x25c77a=>{const _0x5f0cb6=_0x5c868e;_0x25c77a&&imports[_0x5f0cb6(0x1ad)]({'importingFile':_0x44ce37,'importedSymbol':_0x25c77a,'importedFromFile':_0x15edae[_0x5f0cb6(0x1c3)],'fileExists':_0x15edae['exists'],'isExternal':_0x15edae['isExternal']||![],'isDefault':![]});});}}const requireRegex=/(?:const|let|var)\s+(?:\{([^}]+)\}|([^=\s]+))\s*=\s*require\(['"`]([^'"`]+)['"`]\)/g;while((_0x262b3a=requireRegex[_0x5c868e(0x1cb)](_0x288898))!==null){const [,_0x40c577,_0x29a558,_0x132fd2]=_0x262b3a,_0x2ce4d8=await this[_0x5c868e(0x1e8)](_0x132fd2,_0x42b74a);!_0x2ce4d8['isExternal']&&_0x2ce4d8['exists']&&this['dependencies']['get'](_0x44ce37)['add'](_0x2ce4d8['path']);if(_0x40c577){const _0x4c8248=_0x40c577[_0x5c868e(0x1b3)](',')[_0x5c868e(0x1b4)](_0x4b89c9=>_0x4b89c9['trim']()['split'](':')[0x0][_0x5c868e(0x1b5)]());_0x4c8248['forEach'](_0x3da53c=>{const _0x10bc19=_0x5c868e;_0x3da53c&&imports[_0x10bc19(0x1ad)]({'importingFile':_0x44ce37,'importedSymbol':_0x3da53c,'importedFromFile':_0x2ce4d8['path'],'fileExists':_0x2ce4d8[_0x10bc19(0x1d7)],'isExternal':_0x2ce4d8['isExternal']||![],'isDefault':![]});});}else _0x29a558&&imports[_0x5c868e(0x1ad)]({'importingFile':_0x44ce37,'importedSymbol':_0x29a558[_0x5c868e(0x1b5)](),'importedFromFile':_0x2ce4d8['path'],'fileExists':_0x2ce4d8[_0x5c868e(0x1d7)],'isExternal':_0x2ce4d8['isExternal']||![],'isDefault':!![]});}_0xf1a042=_0x16ba05;}return imports;}[a0_0x5ca787(0x1f6)](_0x4455d5){const _0x2b35cc=a0_0x5ca787,exports=new Set(),_0x3cab7c=_0x4455d5[_0x2b35cc(0x1b3)]('\x0a');for(const _0x5a5b85 of _0x3cab7c){const _0x528223=_0x5a5b85[_0x2b35cc(0x1b5)]();if(_0x528223['startsWith']('//')||_0x528223['startsWith']('/*'))continue;/export\s+default\s+/[_0x2b35cc(0x1ee)](_0x528223)&&exports['add']('default');const _0x4beb89=_0x528223['match'](/export\s+\{([^}]+)\}/);if(_0x4beb89){const _0x26b031=_0x4beb89[0x1]['split'](',')[_0x2b35cc(0x1b4)](_0x23f421=>{const _0x3f90a0=_0x2b35cc,_0x380567=_0x23f421[_0x3f90a0(0x1b5)]()['split'](/\s+as\s+/);return _0x380567[_0x380567['length']-0x1]['trim']();});_0x26b031['forEach'](_0x180bf5=>exports[_0x2b35cc(0x1dd)](_0x180bf5));}const _0x5b87e5=_0x528223['match'](/export\s+(?:const|let|var|function|class|async\s+function)\s+([^=\s(]+)/);_0x5b87e5&&exports[_0x2b35cc(0x1dd)](_0x5b87e5[0x1]);const exportFromMatch=_0x528223['match'](/export\s+\{([^}]+)\}\s+from/);if(exportFromMatch){const _0x1018a5=exportFromMatch[0x1]['split'](',')['map'](_0x4a2922=>{const _0x26f2a9=_0x2b35cc,_0xa5c0e4=_0x4a2922[_0x26f2a9(0x1b5)]()['split'](/\s+as\s+/);return _0xa5c0e4[_0xa5c0e4['length']-0x1][_0x26f2a9(0x1b5)]();});_0x1018a5['forEach'](_0x4db766=>exports['add'](_0x4db766));}/export\s+\*\s+from/['test'](_0x528223)&&exports['add']('*');const moduleExportsMatch=_0x528223[_0x2b35cc(0x217)](/module\.exports\s*=\s*\{([^}]+)\}/);if(moduleExportsMatch){const _0x4703ab=moduleExportsMatch[0x1][_0x2b35cc(0x1b3)](',')[_0x2b35cc(0x1b4)](_0x44a577=>{const _0x3997d6=_0x2b35cc,_0x300518=_0x44a577['trim']()[_0x3997d6(0x1b3)](':');return _0x300518[0x0][_0x3997d6(0x1b5)]();});_0x4703ab[_0x2b35cc(0x1bb)](_0x3e4403=>exports[_0x2b35cc(0x1dd)](_0x3e4403));}/module\.exports\s*=\s*[^{]/['test'](_0x528223)&&exports['add']('default');const moduleExportsPropMatch=_0x528223['match'](/module\.exports\.([^=\s]+)\s*=/);moduleExportsPropMatch&&exports['add'](moduleExportsPropMatch[0x1]);const exportsPropMatch=_0x528223['match'](/exports\.([^=\s]+)\s*=/);exportsPropMatch&&exports[_0x2b35cc(0x1dd)](exportsPropMatch[0x1]);}return exports;}async[a0_0x5ca787(0x1e8)](importPath,_0x4a6120){const _0x53d772=a0_0x5ca787;if(importPath[_0x53d772(0x17a)]('.')){const _0x34ef77=a0_0x52e509[_0x53d772(0x181)](_0x4a6120),_0x1e1fb0=a0_0x52e509['resolve'](_0x34ef77,importPath);if(a0_0x52e509[_0x53d772(0x1c6)](importPath))try{const _0x5ef718=await a0_0x388bbf['stat'](_0x1e1fb0);if(_0x5ef718[_0x53d772(0x193)]())return{'path':this['getRelativePath'](_0x1e1fb0),'exists':!![]};}catch{}const _0x407584=['',_0x53d772(0x1ae),'.mjs','.ts','.jsx','.tsx',_0x53d772(0x1bf),_0x53d772(0x16f),'/index.jsx',_0x53d772(0x1a9)];for(const _0x320aec of _0x407584){const _0x4dd359=_0x1e1fb0+_0x320aec;try{const _0x223b13=await a0_0x388bbf['stat'](_0x4dd359);if(_0x223b13['isFile']())return{'path':this[_0x53d772(0x1d2)](_0x4dd359),'exists':!![]};}catch{}}return{'path':this['getRelativePath'](_0x1e1fb0),'exists':![]};}return{'path':importPath,'exists':!![],'isExternal':!![]};}[a0_0x5ca787(0x1d2)](_0x37ead8){const _0x33da49=a0_0x5ca787;return a0_0x52e509['relative'](this['rootDir'],_0x37ead8)[_0x33da49(0x1e1)](/\\/g,'/');}['findCircularDependencies'](){const _0x2a885c=a0_0x5ca787,_0x3bf0be=[],_0x53f1fa=new Set(),_0x370777=new Set(),_0x1ff484=(_0x3471bf,_0x24050d=[])=>{const _0x10935a=a0_0x1451;if(_0x370777['has'](_0x3471bf)){const _0x745f52=_0x24050d[_0x10935a(0x1c2)](_0x3471bf);_0x745f52!==-0x1&&_0x3bf0be[_0x10935a(0x1ad)]([..._0x24050d['slice'](_0x745f52),_0x3471bf]);return;}if(_0x53f1fa['has'](_0x3471bf))return;_0x53f1fa[_0x10935a(0x1dd)](_0x3471bf),_0x370777[_0x10935a(0x1dd)](_0x3471bf),_0x24050d['push'](_0x3471bf);const _0x221016=this[_0x10935a(0x17b)][_0x10935a(0x1ec)](_0x3471bf)||new Set();for(const _0x46a339 of _0x221016){_0x1ff484(_0x46a339,[..._0x24050d]);}_0x370777['delete'](_0x3471bf);};for(const _0x2f23d3 of this[_0x2a885c(0x17b)]['keys']()){!_0x53f1fa[_0x2a885c(0x185)](_0x2f23d3)&&_0x1ff484(_0x2f23d3);}return _0x3bf0be;}['findUnusedExports'](){const _0x535f81=a0_0x5ca787,_0x2757a3=new Map();for(const _0x179050 of this['imports']){!_0x179050[_0x535f81(0x1d0)]&&(!_0x2757a3['has'](_0x179050[_0x535f81(0x1f9)])&&_0x2757a3[_0x535f81(0x18d)](_0x179050[_0x535f81(0x1f9)],new Set()),_0x2757a3['get'](_0x179050['importedFromFile'])[_0x535f81(0x1dd)](_0x179050['importedSymbol']));}const _0x5df17a={};for(const [_0x51da99,exports]of this['exports']['entries']()){const _0x18b3ef=_0x2757a3[_0x535f81(0x1ec)](_0x51da99)||new Set(),_0x4055d0=Array[_0x535f81(0x1fb)](exports)['filter'](_0x1f921e=>!_0x18b3ef['has'](_0x1f921e)&&_0x1f921e!=='*');_0x4055d0[_0x535f81(0x206)]>0x0&&(_0x5df17a[_0x51da99]=_0x4055d0);}return _0x5df17a;}async[a0_0x5ca787(0x187)](_0x3c8de2='full'){const _0x3afb47=a0_0x5ca787;this[_0x3afb47(0x1a6)]?.[_0x3afb47(0x1e9)]('Starting import analysis',{'mode':_0x3c8de2,'rootDir':this[_0x3afb47(0x195)]}),await this['loadIgnoreFile']();const _0x48355e=await this[_0x3afb47(0x1a2)](this[_0x3afb47(0x195)]);this['logger']?.[_0x3afb47(0x1e9)](_0x3afb47(0x1c0),{'count':_0x48355e[_0x3afb47(0x206)]});for(const _0x54dd89 of _0x48355e){try{const _0x556670=await a0_0x388bbf[_0x3afb47(0x19c)](_0x54dd89,_0x3afb47(0x194)),_0x4c66d3=this[_0x3afb47(0x1d2)](_0x54dd89),_0x16a6d2=await this[_0x3afb47(0x1da)](_0x556670,_0x54dd89);this[_0x3afb47(0x1dc)][_0x3afb47(0x1ad)](..._0x16a6d2);const _0xcdf6af=this['parseExports'](_0x556670);this[_0x3afb47(0x1c1)]['set'](_0x4c66d3,_0xcdf6af);}catch(_0x14e5a6){this[_0x3afb47(0x1a6)]?.[_0x3afb47(0x1b6)]('Error\x20parsing\x20file',{'file':_0x54dd89,'error':_0x14e5a6['message']});}}this[_0x3afb47(0x1a6)]?.[_0x3afb47(0x1e9)]('Parsed\x20all\x20files',{'imports':this['imports']['length'],'exports':this['exports'][_0x3afb47(0x1a8)]});const _0x365724={'summary':{'totalFiles':_0x48355e['length'],'totalImports':this['imports'][_0x3afb47(0x206)],'totalExports':Array[_0x3afb47(0x1fb)](this[_0x3afb47(0x1c1)]['values']())['reduce']((_0x1ca029,exports)=>_0x1ca029+exports[_0x3afb47(0x1a8)],0x0)},'missingExports':{},'missingFiles':{},'fileNotFoundImports':[]};for(const importEntry of this[_0x3afb47(0x1dc)]){const {importingFile:importingFile,importedSymbol:importedSymbol,importedFromFile:importedFromFile,isDefault:_0x37871d,isNamespace:_0x50c734,fileExists:_0x1e84cd,isExternal:_0x213e1f}=importEntry;if(!_0x1e84cd&&!_0x213e1f){_0x365724[_0x3afb47(0x180)]['push']({'importingFile':importingFile,'importedSymbol':importedSymbol,'importedFromFile':importedFromFile,'isDefault':_0x37871d||![],'isNamespace':_0x50c734||![]});!_0x365724['missingFiles'][importingFile]&&(_0x365724[_0x3afb47(0x18a)][importingFile]=[]);_0x365724['missingFiles'][importingFile][_0x3afb47(0x1ad)]({'missingFile':importedFromFile,'importedSymbol':importedSymbol,'isDefault':_0x37871d||![],'isNamespace':_0x50c734||![]});continue;}if(_0x213e1f)continue;const exportingFileExports=this[_0x3afb47(0x1c1)]['get'](importedFromFile);let _0x15a4cb=![];if(exportingFileExports){if(_0x50c734)_0x15a4cb=exportingFileExports[_0x3afb47(0x1a8)]>0x0;else _0x37871d?_0x15a4cb=exportingFileExports['has']('default'):_0x15a4cb=exportingFileExports[_0x3afb47(0x185)](importedSymbol)||exportingFileExports[_0x3afb47(0x185)]('*');}!_0x15a4cb&&(!_0x365724['missingExports'][importingFile]&&(_0x365724[_0x3afb47(0x188)][importingFile]=[]),_0x365724['missingExports'][importingFile]['push']({'importedSymbol':importedSymbol,'importedFromFile':importedFromFile,'availableExports':exportingFileExports?Array[_0x3afb47(0x1fb)](exportingFileExports):[],'isDefault':_0x37871d||![],'isNamespace':_0x50c734||![]}));}return(_0x3c8de2===_0x3afb47(0x1fe)||_0x3c8de2===_0x3afb47(0x172))&&(this['logger']?.['info'](_0x3afb47(0x19f)),_0x365724[_0x3afb47(0x20e)]=this['findCircularDependencies'](),_0x365724[_0x3afb47(0x214)]=this['findUnusedExports']()),this['logger']?.[_0x3afb47(0x1e9)]('Analysis\x20complete',{'missingFiles':_0x365724['fileNotFoundImports'][_0x3afb47(0x206)],'missingExports':Object['keys'](_0x365724['missingExports'])['length']}),_0x365724;}}function a0_0x1451(_0x5ab676,_0x5e8924){_0x5ab676=_0x5ab676-0x16f;const _0x443642=a0_0x4436();let _0x1451c1=_0x443642[_0x5ab676];if(a0_0x1451['XJKEMg']===undefined){var _0x533c71=function(_0x2dc41f){const _0x4688ad='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x388bbf='',_0x52e509='';for(let _0x3e8737=0x0,_0x4670f0,_0x48d21e,_0x508e1d=0x0;_0x48d21e=_0x2dc41f['charAt'](_0x508e1d++);~_0x48d21e&&(_0x4670f0=_0x3e8737%0x4?_0x4670f0*0x40+_0x48d21e:_0x48d21e,_0x3e8737++%0x4)?_0x388bbf+=String['fromCharCode'](0xff&_0x4670f0>>(-0x2*_0x3e8737&0x6)):0x0){_0x48d21e=_0x4688ad['indexOf'](_0x48d21e);}for(let _0x3dc16c=0x0,_0x488c64=_0x388bbf['length'];_0x3dc16c<_0x488c64;_0x3dc16c++){_0x52e509+='%'+('00'+_0x388bbf['charCodeAt'](_0x3dc16c)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x52e509);};a0_0x1451['FeCJgY']=_0x533c71,a0_0x1451['apaxly']={},a0_0x1451['XJKEMg']=!![];}const _0x478e1d=_0x443642[0x0],_0x523ba8=_0x5ab676+_0x478e1d,_0x583740=a0_0x1451['apaxly'][_0x523ba8];return!_0x583740?(_0x1451c1=a0_0x1451['FeCJgY'](_0x1451c1),a0_0x1451['apaxly'][_0x523ba8]=_0x1451c1):_0x1451c1=_0x583740,_0x1451c1;}export default ImportAnalyzerTool;function a0_0x4436(){const _0x46fe81=['yxzHAwXHyMXLrxHWB3j0CW','4Psa4Psa4Psa4Psa4Psa4Psa4Psa4Psa4Psa4Psa4Psa4Psa4Psa4Psa4Psa4Psa4Psa4Psa4Psa4Psa4Psa4Psa4Psa4Psa','zw50CMLLCW','zgv0ywLSzwq','t3v0Chv0oIa','C2HVDwXKswDUB3jLrMLSzq','B3v0Chv0','C3rHCNrZv2L0Aa','zgvWzw5Kzw5JAwvZ','icaGia','icaGvw51C2vKoIa','mte3nZu5m0zurNjivG','revgqvvmvf9jr05puKvFrKLmrq','zMLSzu5VDezVDw5Ksw1WB3j0CW','zgLYBMfTzq','cVcFL5hVUi8GifbpvevoveLbteXzifvovvnfrcbfwfbpuLrt','icaYlIbszxnVBhzLia','8j+tPcbuB3rHBcbLEhbVCNrZoIa','AgfZ','lMDPDa','yw5HBhL6zq','BwLZC2LUz0v4Cg9YDhm','iIbVCIb1C2uGB25Lig9MihrOzsbHDMfPBgfIBguGzxHWB3j0CW','BwLZC2LUz0zPBgvZ','nde0nurdtxvlwa','Axnoyw1LC3bHy2u','C2v0','zxHLy3v0zq','C3rYAw5N','rMLSzsbJB3vUDcbLEgnLzwrZigXPBwL0oIa','odmYn2XowNLSuW','vg9VBdOGsw1WB3j0iefUywX5EMvYic0Gqw5HBhL6zsbkyxzHu2nYAxb0l1r5Cgvty3jPChqGAw1WB3j0CYbHBMqGzxHWB3j0CWOkkIPqDxjWB3nLoIOQiefUywX5EMvZiePHDMfty3jPChqVvhLWzvnJCMLWDcbWCM9Qzwn0CYb0BYbKzxrLy3qGyNjVA2vUigLTCg9YDhmSig1PC3nPBMCGzxHWB3j0CYWGy2LYy3vSyxiGzgvWzw5Kzw5JAwvZlcbHBMqGDw51C2vKigv4Cg9YDhmUcGOQkKLUDM9JyxrPB24Gu3LUDgf4oIOQcGPytuWGrM9YBwf0oGPGygb4BwWkpgLTCg9YDc1HBMfSExPLCJ4kica8Cgf0Ad4Ul3nYyZWVCgf0Ad4kica8Bw9Kzt5MDwXSpc9TB2rLpGOGidXVDxrWDxq+C3vTBwfYEtWVB3v0Chv0pGOGidXPz25VCMuTzMLSzt4Uz2L0AwDUB3jLpc9Pz25VCMuTzMLSzt4kpc9PBxbVCNqTyw5HBhL6zxi+cMbGyaOksLnptIbgB3jTyxq6cMbGygPZB24kEWOGicj0B29SswqIoIaIAw1WB3j0lwfUywX5EMvYiIWkicaICgfYyw1LDgvYCYi6ihSkicaGicjWyxrOiJOGiI4VC3jJiIWkicaGicjTB2rLiJOGiMz1BgWIlaOGicaGiM91Dhb1Dci6icjZDw1Tyxj5iIWkicaGicjPz25VCMvgAwXLiJOGiI5NAxrPz25VCMuIcIaGFqP9cMbGyaOkkIPqyxjHBwv0zxjZoIOQcI0GkIPWyxrOkIOGkhn0CMLUzYWGB3b0Aw9UywWPoIbqyxrOihrVigrPCMvJDg9YEsb0BYbHBMfSExPLlIbezwzHDwX0oIaIlIiklsaQkM1VzguQkIaOC3rYAw5NlcbVChrPB25HBcK6iefUywX5C2LZig1VzguUie9WDgLVBNm6cIaGlsaIzNvSBciGlsbdB21WBgv0zsbHBMfSExnPCYaOzgvMyxvSDcKkicaTicjXDwLJAYiGlsbgyxn0ihnJyw4GzM9Yig1PC3nPBMCGzMLSzxmGB25SEqOGic0GiMzPEciGlsbjBMnSDwrLCYbMAxGGC3vNz2vZDgLVBNmklsaQkM91Dhb1DcOQicHZDhjPBMCSig9WDgLVBMfSktOGt3v0Chv0igzVCM1HDc4Gt3b0Aw9UCZOkicaTicjZDw1Tyxj5iIaTienVBMnPC2uGC3vTBwfYEsaOzgvMyxvSDcKkicaTicjKzxrHAwXLzciGlsbgDwXSihjLCg9YDcb3AxrOigzPEgvZcIaGlsaIANnVBIiGlsbnywnOAw5LlxjLywrHyMXLigzVCM1HDaOTicOQAwDUB3jLrMLSzsOQicHZDhjPBMCSig9WDgLVBMfSktOGswDUB3jLigzPBguGBMfTzs4GrgvMyxvSDdOGiI5NAxrPz25VCMuIcGOQkLDOyxqGsxqGrgv0zwn0CZOQkGOTie1PC3nPBMCGzMLSzxmGkgLTCg9YDhmGCg9PBNrPBMCGDg8GBM9Ulwv4Axn0zw50igzPBgvZkqOTie1PC3nPBMCGzxHWB3j0CYaOC3LTyM9SCYbUB3qGzxHWB3j0zwqGzNjVBsb0yxjNzxqGzMLSzxmPcI0Gq2LYy3vSyxiGzgvWzw5Kzw5JAwvZicHMAwXLCYb0Agf0igrLCgvUzcbVBIbLywnOig90AgvYigLUigeGBg9VCcKklsbvBNvZzwqGzxHWB3j0CYaOzxHWB3j0CYbUzxzLCIbPBxbVCNrLzcbHBNL3AgvYzsKkcIOQrxHHBxbSzxm6kIOkcJeUiff1AwnRihbYB2PLy3qGC2nHBJOkygbGEg1ScJXPBxbVCNqTyw5HBhL6zxi+cIaGpg1Vzgu+CxvPy2S8l21Vzgu+cJWVAw1WB3j0lwfUywX5EMvYpGPGygakcJiUiez1BgWGyw5HBhLZAxmGD2L0AcbKzxrHAwXLzcbYzxbVCNq6cMbGyhHTBaO8Aw1WB3j0lwfUywX5EMvYpGOGidXTB2rLpMz1BgW8l21Vzgu+cIaGpg91Dhb1Dd5KzxrHAwXLzdWVB3v0Chv0pGO8l2LTCg9YDc1HBMfSExPLCJ4kygbGcGOZlIbbBMfSExPLihnWzwnPzMLJigrPCMvJDg9YEtOkygbGANnVBGP7cIaGiNrVB2Xjzci6icjPBxbVCNqTyw5HBhL6zxiIlaOGicjWyxjHBwv0zxjZiJOGEYaICgf0Aci6iciUl3nYyY9JB21WB25LBNrZiIWGiM1VzguIoIaIzNvSBciGFqP9cMbGyaOkkIPoB3rLCZOQkGOTifn1ChbVCNrZievtnIbTB2r1BgvZicHPBxbVCNqVzxHWB3j0ksbHBMqGq29TBw9UsLmGkhjLCxvPCMuVBw9KDwXLlMv4Cg9YDhmPcI0GuMvZCgvJDhmGlMDPDgLNBM9YzsbWyxr0zxjUCWOTienVCNjLy3rSEsbOyw5KBgvZignVBw1LBNrLzcbPBxbVCNrZigfUzcbTDwX0As1SAw5Lihn0yxrLBwvUDhmklsbxB3jRCYb3AxrOic5QCYWGlM1QCYWGlNrZlcaUANn4lcaUDhn4igzPBgvZ','AxngAwXL','DxrMltG','CM9VDerPCG','BM9YBwfSAxPL','revgqvvmvf9nt0rf','ANnVBG','4Psa4Psa4Psa4Psa4Psa4Psa4Psa4Psa4Psa4Psa4Psa4Psa4Psa4Psa4Psa4Psa4Psa','yxr0CMLIDxrLCW','cUkAOo+4JYaGtuLtu0LorYbfwfbpuLrt','CMvHzezPBgu','sw52ywXPzcbVDxrWDxq6ia','AwDUB3jLrMLSzq','uNvUBMLUzYbMDwXSigfUywX5C2LZ','BMfTzq','x3jLC29SDMvbBMrwywXPzgf0zvbHDgG','z2v0qwXSrMLSzxm','A2v5CW','ihn5BwjVBhmGBM90igv4Cg9YDgvKigzYB20GDgHLAxiGC291CMnLCW','4P2mie1ju1njtKCGrKLmrvm','Bg9Nz2vY','icaGicaGvhj5Aw5NihrVigLTCg9YDdOG','C2L6zq','l2LUzgv4lNrZEa','Aw1WB3j0zwrtEw1IB2W','8j+tIIbezxrHAwXLzcbjBxbVCNqVrxHWB3j0iefUywX5C2LZifjLCg9YDa','zMLUza','ChvZAa','lMPZ','mtu5ndy3neXPA2TztW','zMLSDgvY','zgLZDa','AxnbyNnVBhv0zq','C3bSAxq','BwfW','DhjPBq','D2fYBG','C2XPy2u','icaGicaG8j+sOsbgAxG6ienOzwnRigLMigzPBguGzxHPC3rZig9YignVCNjLy3qGDgHLigLTCg9YDcbWyxrO','igLTCg9YDhmG','x2zVCM1HDerLDgfPBgvKt3v0Chv0','zM9YrwfJAa','D29YA2LUz0rPCMvJDg9YEq','8j+tPsbuB3rHBcbPBxbVCNrZoIa','AM9PBG','l2LUzgv4lMPZ','rM91BMqGzMLSzxm','zxHWB3j0CW','Aw5KzxHpzG','Cgf0Aa','8j+tIcbtDgf0Axn0AwnZoG','ignPCMn1BgfYigrLCgvUzgvUy3KGy2HHAw4OCYK','zxH0BMfTzq','lMPZEa','icaGicaG8j+sOsbgAxG6iefKzcbLEhbVCNqGzM9Yici','mZu0nJa5zvPLC0fQ','CMvSyxrPDMu','zxHLyW','8j+uJsbbBMfSExPPBMCGAw1WB3j0CYbPBJOG','8j+tIIbjBxbVCNqVrxHWB3j0iefUywX5C2LZifn1Bw1HCNK','lM1QCW','icaZlIbszwzHy3rVCIa','AxnfEhrLCM5HBa','vKfmsurFt1vuufvuuW','z2v0uMvSyxrPDMvqyxrO','zgvIDwC','C29Tzq','y3DK','sw52ywXPzcbWyxjHBwv0zxiGzM9YBwf0lIbfEhbLy3rLzcbZDhjPBMCGkfHntcKGB3iGB2jQzwn0icHku09oks4','zxHPC3rZ','mJi0nJm5mLbgwwTwyq','revgqvvmvf9pvvrqvvq','CgfYC2vjBxbVCNrZ','Aw5JBhvKzxm','Aw1WB3j0CW','ywrK','icdIGkiGvg90ywWGzxHWB3j0CZOG','nJmXotrjzeDqzfm','ig1PC3nPBMCGzxHWB3j0khmP','CMvWBgfJzq','4Psa4Psa4Psa4Psa4Psa4Psa4Psa4Psa4Psa4Psa4Psa4Psa4Psa4Psa4Psa4Psa4Psa4Psa4Psa4Psa4Psa4Psa4Psa4Psa4Psa4Psa4Psa4Psa4Psa4Psa','iJ8GkgnHC2uGBwLZBwf0y2GP','mtvgBNjstLO','Bw9Kzq','CMvKDwnL','cIaGtwLZC2LUzYbfEhbVCNrZoG','CMvZB2X2zuLTCg9YDfbHDgG','Aw5MBW','C3LTyM9StMfTzq','iokgKIa','z2v0','tw9KztOG','DgvZDa','cVcFK4qG','icdIGkiGrMLSzxmGyw5HBhL6zwq6ia','x2zVCM1HDfn1Bw1HCNLpDxrWDxq','BMfTzwq','lIbnDxn0igjLig9UzsbVzJOG','C3vTBwfYEq','icaGicaG8j+sOsbgAxG6ie5VigrLzMf1BhqGzxHWB3j0lIbvC2uGBMfTzwqGAw1WB3j0oIb7ia','CgfYC2vfEhbVCNrZ','BM9Kzv9TB2r1BgvZ','mtmZnMLyAhr3sq','Aw1WB3j0zwrgCM9TrMLSzq','icaGiokaOIa','zNjVBq','n0TiBu9QsW','yMfZzw5HBwu','zNvSBa','B2jQzwn0','DMfSDwvZ','Dg90ywXgAwXLCW','BMfTzxnWywnL','igLTCg9YDhmGCg9PBNrPBMCGDg8GBM9Ulwv4Axn0zw50igzPBgvZ','vg9Vig1HBNKGzMLSzxmGDg8Gyw5HBhL6ztOG','AxnezwzHDwX0','BgvUz3rO','Aw1WB3j0Aw5NrMLSzq','ig1PC3nPBMCGzMLSzsbYzwzLCMvUy2uOCYK','iIaO','z2v0rgvZy3jPChrPB24','ugf0AcbKB2vZig5VDcbLEgLZDdOG','ig5VBI1LEgLZDgvUDcbZEw1IB2WOCYK','8j+uHcbdAxjJDwXHCIbKzxbLBMrLBMnPzxm6ia','y2LYy3vSyxjezxbLBMrLBMnPzxm','cVcFLiqGq0Lsq1vmqviGrevqru5eru5dsuvt','BwvZC2fNzq','icaGicaG8j+tPcbbDMfPBgfIBguGzxHWB3j0CZOG','Dg90ywXfEhbVCNrZ','mtK2otbJCMXzzfe','Dw51C2vKrxHWB3j0CW','icaGicaG8j+sOsbgAxG6ierLzMf1BhqGzxHWB3j0igv4Axn0CYWGy2HLy2SGAw1WB3j0ihn5BNrHEa','Dg9mB3DLCKnHC2u','Bwf0y2G','lMDPDgLNBM9Yzq','y292zxjHz2u','CgfYC2vuywDZ','l2LUzgv4lNrZ','AwDUB3jLugf0DgvYBNm','cVcFKQeGuNvUihDPDgGGB3v0Chv0psjKzxrHAwXLzciGzM9YignVBxbSzxrLigfUywX5C2LZigfUzcbMAxGGC3vNz2vZDgLVBNm','zML4'];a0_0x4436=function(){return _0x46fe81;};return a0_0x4436();}
|