@syke1/mcp-server 1.5.6 → 1.6.0

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.
@@ -1,623 +1 @@
1
- "use strict";
2
- /**
3
- * Composite Risk Scoring for SYKE.
4
- *
5
- * Combines multiple signals (fan-in, instability, cyclomatic complexity,
6
- * cascade depth) into a single 0-1 risk score using weighted normalization.
7
- *
8
- * Based on Robert C. Martin's stability metrics and standard software
9
- * engineering coupling/cohesion analysis.
10
- */
11
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
12
- if (k2 === undefined) k2 = k;
13
- var desc = Object.getOwnPropertyDescriptor(m, k);
14
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
15
- desc = { enumerable: true, get: function() { return m[k]; } };
16
- }
17
- Object.defineProperty(o, k2, desc);
18
- }) : (function(o, m, k, k2) {
19
- if (k2 === undefined) k2 = k;
20
- o[k2] = m[k];
21
- }));
22
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
23
- Object.defineProperty(o, "default", { enumerable: true, value: v });
24
- }) : function(o, v) {
25
- o["default"] = v;
26
- });
27
- var __importStar = (this && this.__importStar) || (function () {
28
- var ownKeys = function(o) {
29
- ownKeys = Object.getOwnPropertyNames || function (o) {
30
- var ar = [];
31
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
32
- return ar;
33
- };
34
- return ownKeys(o);
35
- };
36
- return function (mod) {
37
- if (mod && mod.__esModule) return mod;
38
- var result = {};
39
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
40
- __setModuleDefault(result, mod);
41
- return result;
42
- };
43
- })();
44
- Object.defineProperty(exports, "__esModule", { value: true });
45
- exports.RISK_WEIGHTS = void 0;
46
- exports.invalidateProjectMetrics = invalidateProjectMetrics;
47
- exports.computeCouplingMetrics = computeCouplingMetrics;
48
- exports.computeInstability = computeInstability;
49
- exports.computeComplexity = computeComplexity;
50
- exports.computeCascadeDepth = computeCascadeDepth;
51
- exports.classifyCompositeRisk = classifyCompositeRisk;
52
- exports.computeRiskScore = computeRiskScore;
53
- exports.computeProjectMetrics = computeProjectMetrics;
54
- exports.getRiskScore = getRiskScore;
55
- exports.formatRiskScore = formatRiskScore;
56
- const fs = __importStar(require("fs"));
57
- const plugin_1 = require("../languages/plugin");
58
- const pagerank_1 = require("./pagerank");
59
- // ── Weights (tunable constants) ──
60
- exports.RISK_WEIGHTS = {
61
- fanIn: 0.30, // Most important: how many things break
62
- stability: 0.20, // Foundation files are riskier
63
- complexity: 0.20, // Complex files are harder to change safely
64
- cascadeDepth: 0.15, // Deep cascades mean wider blast radius
65
- pageRank: 0.15, // Recursive importance from the dependency graph
66
- };
67
- // ── Risk Level Thresholds ──
68
- const RISK_THRESHOLDS = {
69
- CRITICAL: 0.8,
70
- HIGH: 0.6,
71
- MEDIUM: 0.4,
72
- LOW: 0.2,
73
- };
74
- // ── Cached Project Metrics ──
75
- let cachedProjectMetrics = null;
76
- let cachedProjectRoot = null;
77
- /**
78
- * Invalidate cached project metrics. Call when the graph is rebuilt.
79
- */
80
- function invalidateProjectMetrics() {
81
- cachedProjectMetrics = null;
82
- cachedProjectRoot = null;
83
- }
84
- // ── Core Metric Computations ──
85
- /**
86
- * Compute coupling metrics for a single file from the dependency graph.
87
- */
88
- function computeCouplingMetrics(filePath, graph) {
89
- const fanIn = (graph.reverse.get(filePath) || []).length;
90
- const fanOut = (graph.forward.get(filePath) || []).length;
91
- const transitiveFanIn = computeTransitiveFanIn(filePath, graph);
92
- return { fanIn, fanOut, transitiveFanIn };
93
- }
94
- /**
95
- * BFS reverse traversal to count all transitive dependents.
96
- */
97
- function computeTransitiveFanIn(filePath, graph) {
98
- const visited = new Set();
99
- const queue = [];
100
- const directDeps = graph.reverse.get(filePath) || [];
101
- for (const dep of directDeps) {
102
- if (!visited.has(dep)) {
103
- visited.add(dep);
104
- queue.push(dep);
105
- }
106
- }
107
- while (queue.length > 0) {
108
- const current = queue.shift();
109
- const dependents = graph.reverse.get(current) || [];
110
- for (const dep of dependents) {
111
- if (!visited.has(dep) && dep !== filePath) {
112
- visited.add(dep);
113
- queue.push(dep);
114
- }
115
- }
116
- }
117
- return visited.size;
118
- }
119
- /**
120
- * Robert C. Martin's Instability Index.
121
- *
122
- * I = Ce / (Ca + Ce) where Ca = fanIn, Ce = fanOut
123
- * 0 = maximally stable (everything depends on it, dangerous to change)
124
- * 1 = maximally unstable (leaf node, safe to change)
125
- */
126
- function computeInstability(fanIn, fanOut) {
127
- if (fanIn + fanOut === 0)
128
- return 0.5; // isolated file
129
- return fanOut / (fanIn + fanOut);
130
- }
131
- // ── Cyclomatic Complexity (regex-based) ──
132
- /**
133
- * Language-specific regex patterns for counting decision points.
134
- * Each pattern matches one decision point in source code.
135
- */
136
- const COMPLEXITY_PATTERNS = {
137
- typescript: [
138
- /\bif\s*\(/g,
139
- /\belse\s+if\s*\(/g,
140
- /\bfor\s*\(/g,
141
- /\bwhile\s*\(/g,
142
- /\bdo\s*\{/g,
143
- /\bswitch\s*\(/g,
144
- /\bcase\s+/g,
145
- /\bcatch\s*\(/g,
146
- /\?\s*[^:?]/g, // ternary (simplified)
147
- /&&/g,
148
- /\|\|/g,
149
- /\?\?/g,
150
- ],
151
- javascript: [], // same as typescript, populated below
152
- dart: [
153
- /\bif\s*\(/g,
154
- /\belse\s+if\s*\(/g,
155
- /\bfor\s*\(/g,
156
- /\bwhile\s*\(/g,
157
- /\bdo\s*\{/g,
158
- /\bswitch\s*\(/g,
159
- /\bcase\s+/g,
160
- /\bcatch\s*\(/g,
161
- /\?\s*[^:?]/g,
162
- /&&/g,
163
- /\|\|/g,
164
- /\?\?/g,
165
- /\blate\s+/g,
166
- ],
167
- python: [
168
- /\bif\s+/g,
169
- /\belif\s+/g,
170
- /\bfor\s+/g,
171
- /\bwhile\s+/g,
172
- /\bexcept\s*/g,
173
- /\band\b/g,
174
- /\bor\b/g,
175
- /\bwith\s+/g,
176
- ],
177
- go: [
178
- /\bif\s+/g,
179
- /\bfor\s+/g,
180
- /\bselect\s*\{/g,
181
- /\bcase\s+/g,
182
- /&&/g,
183
- /\|\|/g,
184
- ],
185
- rust: [
186
- /\bif\s+/g,
187
- /\belse\s+if\s+/g,
188
- /\bfor\s+/g,
189
- /\bwhile\s+/g,
190
- /\bloop\s*\{/g,
191
- /\bmatch\s+/g,
192
- /=>/g,
193
- /&&/g,
194
- /\|\|/g,
195
- ],
196
- java: [
197
- /\bif\s*\(/g,
198
- /\belse\s+if\s*\(/g,
199
- /\bfor\s*\(/g,
200
- /\bwhile\s*\(/g,
201
- /\bdo\s*\{/g,
202
- /\bswitch\s*\(/g,
203
- /\bcase\s+/g,
204
- /\bcatch\s*\(/g,
205
- /\?\s*[^:?]/g,
206
- /&&/g,
207
- /\|\|/g,
208
- ],
209
- cpp: [
210
- /\bif\s*\(/g,
211
- /\belse\s+if\s*\(/g,
212
- /\bfor\s*\(/g,
213
- /\bwhile\s*\(/g,
214
- /\bdo\s*\{/g,
215
- /\bswitch\s*\(/g,
216
- /\bcase\s+/g,
217
- /\bcatch\s*\(/g,
218
- /\?\s*[^:?]/g,
219
- /&&/g,
220
- /\|\|/g,
221
- ],
222
- ruby: [
223
- /\bif\s+/g,
224
- /\belsif\s+/g,
225
- /\bunless\s+/g,
226
- /\bwhile\s+/g,
227
- /\buntil\s+/g,
228
- /\bfor\s+/g,
229
- /\bwhen\s+/g,
230
- /\brescue\b/g,
231
- /&&/g,
232
- /\|\|/g,
233
- ],
234
- };
235
- // JavaScript uses same patterns as TypeScript
236
- COMPLEXITY_PATTERNS.javascript = COMPLEXITY_PATTERNS.typescript;
237
- /**
238
- * Map language plugin IDs to complexity pattern keys.
239
- */
240
- const LANGUAGE_ID_MAP = {
241
- typescript: "typescript",
242
- dart: "dart",
243
- python: "python",
244
- go: "go",
245
- rust: "rust",
246
- java: "java",
247
- cpp: "cpp",
248
- ruby: "ruby",
249
- };
250
- /**
251
- * Detect the language for a file based on extension or plugin ID.
252
- */
253
- function detectLanguageForFile(filePath) {
254
- const plugin = (0, plugin_1.getPluginForFile)(filePath);
255
- if (plugin) {
256
- return LANGUAGE_ID_MAP[plugin.id] || "typescript";
257
- }
258
- // Fallback: detect by extension
259
- const ext = filePath.split(".").pop()?.toLowerCase() || "";
260
- const extMap = {
261
- ts: "typescript", tsx: "typescript", js: "javascript", jsx: "javascript",
262
- dart: "dart", py: "python", go: "go", rs: "rust",
263
- java: "java", cpp: "cpp", cc: "cpp", cxx: "cpp", c: "cpp", h: "cpp", hpp: "cpp",
264
- rb: "ruby",
265
- };
266
- return extMap[ext] || "typescript";
267
- }
268
- /**
269
- * Strip comments and string literals from source code to avoid
270
- * false positives in complexity counting.
271
- */
272
- function stripCommentsAndStrings(content) {
273
- // Remove block comments
274
- let stripped = content.replace(/\/\*[\s\S]*?\*\//g, "");
275
- // Remove line comments
276
- stripped = stripped.replace(/\/\/.*$/gm, "");
277
- // Remove Python/Ruby line comments
278
- stripped = stripped.replace(/#.*$/gm, "");
279
- // Remove double-quoted strings (simple approach)
280
- stripped = stripped.replace(/"(?:[^"\\]|\\.)*"/g, '""');
281
- // Remove single-quoted strings
282
- stripped = stripped.replace(/'(?:[^'\\]|\\.)*'/g, "''");
283
- // Remove template literals
284
- stripped = stripped.replace(/`(?:[^`\\]|\\.)*`/g, "``");
285
- return stripped;
286
- }
287
- /**
288
- * Compute cyclomatic complexity of source code using regex-based
289
- * decision point counting.
290
- *
291
- * Returns the raw count of decision points (base complexity of 1 is NOT added).
292
- */
293
- function computeComplexity(content, language) {
294
- const patterns = COMPLEXITY_PATTERNS[language] || COMPLEXITY_PATTERNS.typescript;
295
- const stripped = stripCommentsAndStrings(content);
296
- let count = 0;
297
- for (const pattern of patterns) {
298
- // Reset lastIndex for global regexes
299
- pattern.lastIndex = 0;
300
- const matches = stripped.match(pattern);
301
- if (matches) {
302
- count += matches.length;
303
- }
304
- }
305
- return count;
306
- }
307
- // ── Cascade Depth ──
308
- /**
309
- * Compute the maximum cascade depth from the condensed DAG.
310
- * This is the longest path from the file's SCC through the reverse edges
311
- * of the condensed DAG (i.e., how many layers deep the impact propagates).
312
- */
313
- function computeCascadeDepth(filePath, graph) {
314
- const scc = graph.scc;
315
- if (!scc) {
316
- // Fallback: use simple BFS depth on raw graph
317
- return computeRawCascadeDepth(filePath, graph);
318
- }
319
- const sccIndex = scc.nodeToComponent.get(filePath);
320
- if (sccIndex === undefined)
321
- return 0;
322
- // BFS on condensed DAG reverse edges to find max depth
323
- const visited = new Map(); // SCC index -> depth
324
- visited.set(sccIndex, 0);
325
- const queue = [
326
- { idx: sccIndex, depth: 0 },
327
- ];
328
- let maxDepth = 0;
329
- while (queue.length > 0) {
330
- const { idx, depth } = queue.shift();
331
- const dependentSCCs = scc.condensed.reverse.get(idx) || [];
332
- for (const depSCC of dependentSCCs) {
333
- if (!visited.has(depSCC)) {
334
- const newDepth = depth + 1;
335
- visited.set(depSCC, newDepth);
336
- maxDepth = Math.max(maxDepth, newDepth);
337
- queue.push({ idx: depSCC, depth: newDepth });
338
- }
339
- }
340
- }
341
- return maxDepth;
342
- }
343
- /**
344
- * Fallback: simple BFS depth on the raw reverse graph.
345
- */
346
- function computeRawCascadeDepth(filePath, graph) {
347
- const visited = new Set();
348
- visited.add(filePath);
349
- let currentLevel = [filePath];
350
- let depth = 0;
351
- while (currentLevel.length > 0) {
352
- const nextLevel = [];
353
- for (const file of currentLevel) {
354
- const dependents = graph.reverse.get(file) || [];
355
- for (const dep of dependents) {
356
- if (!visited.has(dep)) {
357
- visited.add(dep);
358
- nextLevel.push(dep);
359
- }
360
- }
361
- }
362
- if (nextLevel.length > 0) {
363
- depth++;
364
- }
365
- currentLevel = nextLevel;
366
- }
367
- return depth;
368
- }
369
- // ── Normalization ──
370
- /**
371
- * Min-max normalize a value to the 0-1 range.
372
- * Returns 0 if max equals min (all values identical).
373
- */
374
- function normalize(value, min, max) {
375
- if (max <= min)
376
- return 0;
377
- return Math.min(1, Math.max(0, (value - min) / (max - min)));
378
- }
379
- // ── Risk Level Classification ──
380
- /**
381
- * Map a composite score (0-1) to a risk level.
382
- */
383
- function classifyCompositeRisk(score) {
384
- if (score >= RISK_THRESHOLDS.CRITICAL)
385
- return "CRITICAL";
386
- if (score >= RISK_THRESHOLDS.HIGH)
387
- return "HIGH";
388
- if (score >= RISK_THRESHOLDS.MEDIUM)
389
- return "MEDIUM";
390
- if (score >= RISK_THRESHOLDS.LOW)
391
- return "LOW";
392
- return "SAFE";
393
- }
394
- // ── Main Scoring Functions ──
395
- /**
396
- * Read file content from disk (used when no content is passed).
397
- */
398
- function readFileContent(filePath) {
399
- try {
400
- return fs.readFileSync(filePath, "utf-8");
401
- }
402
- catch {
403
- return null;
404
- }
405
- }
406
- /**
407
- * Compute the composite risk score for a single file.
408
- *
409
- * If `projectMetrics` is provided, uses pre-computed normalization bounds.
410
- * Otherwise, uses raw metrics without normalization (less accurate but functional).
411
- */
412
- function computeRiskScore(filePath, graph, fileContent, projectMetrics) {
413
- // Compute coupling metrics
414
- const coupling = computeCouplingMetrics(filePath, graph);
415
- // Compute instability
416
- const instability = computeInstability(coupling.fanIn, coupling.fanOut);
417
- // Compute complexity
418
- const content = fileContent ?? readFileContent(filePath);
419
- const language = detectLanguageForFile(filePath);
420
- const complexity = content ? computeComplexity(content, language) : 0;
421
- // Compute cascade depth
422
- const cascadeDepth = computeCascadeDepth(filePath, graph);
423
- // Normalize using project-wide bounds (or use raw values)
424
- let normalizedFanIn;
425
- let normalizedComplexity;
426
- let normalizedCascadeDepth;
427
- if (projectMetrics) {
428
- normalizedFanIn = normalize(coupling.transitiveFanIn, 0, projectMetrics.maxTransitiveFanIn);
429
- normalizedComplexity = normalize(complexity, 0, projectMetrics.maxComplexity);
430
- normalizedCascadeDepth = normalize(cascadeDepth, 0, projectMetrics.maxCascadeDepth);
431
- }
432
- else {
433
- // Without project metrics, use simple heuristic normalization
434
- normalizedFanIn = normalize(coupling.transitiveFanIn, 0, Math.max(coupling.transitiveFanIn, 20));
435
- normalizedComplexity = normalize(complexity, 0, Math.max(complexity, 50));
436
- normalizedCascadeDepth = normalize(cascadeDepth, 0, Math.max(cascadeDepth, 5));
437
- }
438
- // Retrieve PageRank data if available on the graph
439
- let pageRankScore;
440
- let pageRankPercentile;
441
- let normalizedPageRank = 0;
442
- let hasPageRank = false;
443
- if (graph.pageRank) {
444
- const prData = (0, pagerank_1.getFileRank)(filePath, graph.pageRank);
445
- if (prData) {
446
- pageRankScore = prData.score;
447
- pageRankPercentile = prData.percentile;
448
- normalizedPageRank = prData.percentile / 100; // 0-1 range
449
- hasPageRank = true;
450
- }
451
- }
452
- // Composite score — include PageRank if available, otherwise normalize
453
- // remaining weights to sum to 1 for backward compatibility
454
- let composite;
455
- if (hasPageRank) {
456
- composite =
457
- exports.RISK_WEIGHTS.fanIn * normalizedFanIn +
458
- exports.RISK_WEIGHTS.stability * (1 - instability) +
459
- exports.RISK_WEIGHTS.complexity * normalizedComplexity +
460
- exports.RISK_WEIGHTS.cascadeDepth * normalizedCascadeDepth +
461
- exports.RISK_WEIGHTS.pageRank * normalizedPageRank;
462
- }
463
- else {
464
- // Fallback: redistribute pageRank weight proportionally among other signals
465
- const baseSum = exports.RISK_WEIGHTS.fanIn + exports.RISK_WEIGHTS.stability +
466
- exports.RISK_WEIGHTS.complexity + exports.RISK_WEIGHTS.cascadeDepth;
467
- composite =
468
- (exports.RISK_WEIGHTS.fanIn / baseSum) * normalizedFanIn +
469
- (exports.RISK_WEIGHTS.stability / baseSum) * (1 - instability) +
470
- (exports.RISK_WEIGHTS.complexity / baseSum) * normalizedComplexity +
471
- (exports.RISK_WEIGHTS.cascadeDepth / baseSum) * normalizedCascadeDepth;
472
- }
473
- // Clamp to 0-1
474
- const clampedComposite = Math.min(1, Math.max(0, composite));
475
- return {
476
- composite: Math.round(clampedComposite * 100) / 100,
477
- fanIn: coupling.fanIn,
478
- fanOut: coupling.fanOut,
479
- transitiveFanIn: coupling.transitiveFanIn,
480
- instability: Math.round(instability * 100) / 100,
481
- complexity,
482
- normalizedComplexity: Math.round(normalizedComplexity * 100) / 100,
483
- cascadeDepth,
484
- riskLevel: classifyCompositeRisk(clampedComposite),
485
- pageRank: pageRankScore,
486
- pageRankPercentile,
487
- };
488
- }
489
- /**
490
- * Pre-compute metrics for all files in the project.
491
- * This establishes normalization bounds and caches per-file scores.
492
- *
493
- * Uses lazy initialization and caches results until invalidated.
494
- */
495
- function computeProjectMetrics(graph, getFileContent) {
496
- // Return cached if available and for the same project
497
- if (cachedProjectMetrics && cachedProjectRoot === graph.projectRoot) {
498
- return cachedProjectMetrics;
499
- }
500
- const contentGetter = getFileContent || readFileContent;
501
- // Phase 1: Compute raw metrics for all files
502
- const rawMetrics = new Map();
503
- let maxFanIn = 0;
504
- let maxTransitiveFanIn = 0;
505
- let maxComplexity = 0;
506
- let maxCascadeDepth = 0;
507
- for (const filePath of graph.files) {
508
- const coupling = computeCouplingMetrics(filePath, graph);
509
- const instability = computeInstability(coupling.fanIn, coupling.fanOut);
510
- const content = contentGetter(filePath);
511
- const language = detectLanguageForFile(filePath);
512
- const complexity = content ? computeComplexity(content, language) : 0;
513
- const cascadeDepth = computeCascadeDepth(filePath, graph);
514
- rawMetrics.set(filePath, { coupling, instability, complexity, cascadeDepth });
515
- maxFanIn = Math.max(maxFanIn, coupling.fanIn);
516
- maxTransitiveFanIn = Math.max(maxTransitiveFanIn, coupling.transitiveFanIn);
517
- maxComplexity = Math.max(maxComplexity, complexity);
518
- maxCascadeDepth = Math.max(maxCascadeDepth, cascadeDepth);
519
- }
520
- // Phase 2: Compute normalized composite scores for all files
521
- const projectMetrics = {
522
- maxFanIn,
523
- maxTransitiveFanIn,
524
- maxComplexity,
525
- maxCascadeDepth,
526
- fileMetrics: new Map(),
527
- };
528
- for (const [filePath, raw] of rawMetrics) {
529
- const normalizedFanIn = normalize(raw.coupling.transitiveFanIn, 0, maxTransitiveFanIn);
530
- const normalizedComplexity = normalize(raw.complexity, 0, maxComplexity);
531
- const normalizedCascadeDepth = normalize(raw.cascadeDepth, 0, maxCascadeDepth);
532
- // Retrieve PageRank data if available
533
- let pageRankScore;
534
- let pageRankPercentile;
535
- let normalizedPageRank = 0;
536
- let hasPageRank = false;
537
- if (graph.pageRank) {
538
- const prData = (0, pagerank_1.getFileRank)(filePath, graph.pageRank);
539
- if (prData) {
540
- pageRankScore = prData.score;
541
- pageRankPercentile = prData.percentile;
542
- normalizedPageRank = prData.percentile / 100;
543
- hasPageRank = true;
544
- }
545
- }
546
- let composite;
547
- if (hasPageRank) {
548
- composite =
549
- exports.RISK_WEIGHTS.fanIn * normalizedFanIn +
550
- exports.RISK_WEIGHTS.stability * (1 - raw.instability) +
551
- exports.RISK_WEIGHTS.complexity * normalizedComplexity +
552
- exports.RISK_WEIGHTS.cascadeDepth * normalizedCascadeDepth +
553
- exports.RISK_WEIGHTS.pageRank * normalizedPageRank;
554
- }
555
- else {
556
- const baseSum = exports.RISK_WEIGHTS.fanIn + exports.RISK_WEIGHTS.stability +
557
- exports.RISK_WEIGHTS.complexity + exports.RISK_WEIGHTS.cascadeDepth;
558
- composite =
559
- (exports.RISK_WEIGHTS.fanIn / baseSum) * normalizedFanIn +
560
- (exports.RISK_WEIGHTS.stability / baseSum) * (1 - raw.instability) +
561
- (exports.RISK_WEIGHTS.complexity / baseSum) * normalizedComplexity +
562
- (exports.RISK_WEIGHTS.cascadeDepth / baseSum) * normalizedCascadeDepth;
563
- }
564
- const clampedComposite = Math.min(1, Math.max(0, composite));
565
- projectMetrics.fileMetrics.set(filePath, {
566
- composite: Math.round(clampedComposite * 100) / 100,
567
- fanIn: raw.coupling.fanIn,
568
- fanOut: raw.coupling.fanOut,
569
- transitiveFanIn: raw.coupling.transitiveFanIn,
570
- instability: Math.round(raw.instability * 100) / 100,
571
- complexity: raw.complexity,
572
- normalizedComplexity: Math.round(normalizedComplexity * 100) / 100,
573
- cascadeDepth: raw.cascadeDepth,
574
- riskLevel: classifyCompositeRisk(clampedComposite),
575
- pageRank: pageRankScore,
576
- pageRankPercentile,
577
- });
578
- }
579
- // Cache the result
580
- cachedProjectMetrics = projectMetrics;
581
- cachedProjectRoot = graph.projectRoot;
582
- console.error(`[syke:scoring] Project metrics computed for ${graph.files.size} files ` +
583
- `(maxFanIn=${maxFanIn}, maxTransFanIn=${maxTransitiveFanIn}, ` +
584
- `maxComplexity=${maxComplexity}, maxCascadeDepth=${maxCascadeDepth})`);
585
- return projectMetrics;
586
- }
587
- /**
588
- * Get the cached risk score for a file, or compute it on the fly.
589
- * Uses project-wide normalization when available.
590
- */
591
- function getRiskScore(filePath, graph, fileContent) {
592
- // Try to use cached project metrics for accurate normalization
593
- if (cachedProjectMetrics && cachedProjectRoot === graph.projectRoot) {
594
- const cached = cachedProjectMetrics.fileMetrics.get(filePath);
595
- if (cached)
596
- return cached;
597
- // File not in cache (possibly new), compute with project bounds
598
- return computeRiskScore(filePath, graph, fileContent ?? null, cachedProjectMetrics);
599
- }
600
- // No project metrics available, compute without normalization
601
- return computeRiskScore(filePath, graph, fileContent ?? null);
602
- }
603
- /**
604
- * Format a risk score for display in MCP tool output.
605
- */
606
- function formatRiskScore(score) {
607
- const stabilityDesc = score.instability <= 0.2 ? "very stable -- dangerous to change" :
608
- score.instability <= 0.4 ? "stable -- be cautious" :
609
- score.instability <= 0.6 ? "balanced" :
610
- score.instability <= 0.8 ? "unstable -- relatively safe" :
611
- "very unstable -- safe to change";
612
- const lines = [
613
- `Risk Score: ${score.composite.toFixed(2)} (${score.riskLevel})`,
614
- ` Fan-in: ${score.transitiveFanIn} (direct: ${score.fanIn}, fan-out: ${score.fanOut})`,
615
- ` Stability: ${score.instability.toFixed(2)} (${stabilityDesc})`,
616
- ` Complexity: ${score.complexity} (normalized: ${score.normalizedComplexity.toFixed(2)})`,
617
- ` Cascade depth: ${score.cascadeDepth} level(s)`,
618
- ];
619
- if (score.pageRank !== undefined && score.pageRankPercentile !== undefined) {
620
- lines.push(` PageRank: ${score.pageRank.toFixed(6)} (${score.pageRankPercentile}th percentile)`);
621
- }
622
- return lines.join("\n");
623
- }
1
+ 'use strict';const _0x475ea7=_0x560d;(function(_0x4dcc62,_0x967959){const _0x59135a={_0x194729:0x96,_0x5d3fb0:0x101,_0x1e8289:0x8e},_0x12c00e=_0x560d,_0x3db09f=_0x4dcc62();while(!![]){try{const _0x8dd26d=parseInt(_0x12c00e(0xbf))/0x1*(-parseInt(_0x12c00e(0xb8))/0x2)+-parseInt(_0x12c00e(_0x59135a._0x194729))/0x3+parseInt(_0x12c00e(_0x59135a._0x5d3fb0))/0x4+-parseInt(_0x12c00e(0xc7))/0x5+-parseInt(_0x12c00e(0x99))/0x6*(parseInt(_0x12c00e(0x10a))/0x7)+parseInt(_0x12c00e(0xeb))/0x8*(parseInt(_0x12c00e(0xcb))/0x9)+parseInt(_0x12c00e(_0x59135a._0x1e8289))/0xa*(parseInt(_0x12c00e(0xb3))/0xb);if(_0x8dd26d===_0x967959)break;else _0x3db09f['push'](_0x3db09f['shift']());}catch(_0x37e48f){_0x3db09f['push'](_0x3db09f['shift']());}}}(_0x87c4,0x3b8d0));var __createBinding=this&&this['__createBinding']||(Object[_0x475ea7(0xad)]?function(_0x25665c,_0x4c0ac8,_0x2923cc,_0x138566){const _0x1fdab3={_0x1270ab:0xe8,_0x3ed129:0xec,_0x5b2af6:0x9e},_0x1973a5=_0x475ea7,_0x1e983e={};_0x1e983e['kUjYn']=function(_0x32f808,_0x5706d3){return _0x32f808 in _0x5706d3;},_0x1e983e[_0x1973a5(0xc2)]=_0x1973a5(_0x1fdab3._0x1270ab);const _0xa3441=_0x1e983e;if(_0x138566===undefined)_0x138566=_0x2923cc;var _0x3089b8=Object[_0x1973a5(_0x1fdab3._0x3ed129)](_0x4c0ac8,_0x2923cc);if(!_0x3089b8||(_0xa3441['kUjYn'](_0xa3441['jNlst'],_0x3089b8)?!_0x4c0ac8[_0x1973a5(0xd4)]:_0x3089b8[_0x1973a5(_0x1fdab3._0x5b2af6)]||_0x3089b8['configurable'])){const _0x16ec9f={};_0x16ec9f[_0x1973a5(0xa2)]=!![],_0x16ec9f['get']=function(){return _0x4c0ac8[_0x2923cc];},_0x3089b8=_0x16ec9f;}Object['defineProperty'](_0x25665c,_0x138566,_0x3089b8);}:function(_0x398c91,_0x18b547,_0x4ac225,_0x2ce929){const _0x3e9fc0={};_0x3e9fc0['qnZIS']=function(_0x5ee572,_0x2eb13a){return _0x5ee572===_0x2eb13a;};const _0x3e7559=_0x3e9fc0;if(_0x3e7559['qnZIS'](_0x2ce929,undefined))_0x2ce929=_0x4ac225;_0x398c91[_0x2ce929]=_0x18b547[_0x4ac225];}),__setModuleDefault=this&&this[_0x475ea7(0xdd)]||(Object[_0x475ea7(0xad)]?function(_0x2dbe9a,_0x579c95){const _0x588299={_0x373ab1:0xee},_0x1f61e0=_0x475ea7,_0x2bbc90={};_0x2bbc90['enumerable']=!![],_0x2bbc90[_0x1f61e0(_0x588299._0x373ab1)]=_0x579c95,Object['defineProperty'](_0x2dbe9a,'default',_0x2bbc90);}:function(_0xc5ab3f,_0x350067){const _0x1e8607={_0x5c04f7:0x108},_0x18799a=_0x475ea7,_0x43f329={};_0x43f329['EggGb']=_0x18799a(_0x1e8607._0x5c04f7);const _0x5f3377=_0x43f329;_0xc5ab3f[_0x5f3377[_0x18799a(0xb4)]]=_0x350067;}),__importStar=this&&this[_0x475ea7(0xcc)]||(function(){const _0x518535={_0x5ba9e5:0xcd,_0x43db63:0xed},_0x18a5c9=_0x475ea7,_0xa61a6d={'sUhsg':_0x18a5c9(0xaf),'mMmso':function(_0x19b0cf,_0x51fcdd){return _0x19b0cf!=_0x51fcdd;},'wBrsQ':function(_0x439df8,_0x3cf91b){return _0x439df8(_0x3cf91b);},'QeDOo':function(_0x54c5a6,_0x50fd97){return _0x54c5a6<_0x50fd97;},'eLCXz':_0x18a5c9(0x108),'mVuiK':function(_0x6df9ad,_0x31314d,_0x35b261,_0x113d9f){return _0x6df9ad(_0x31314d,_0x35b261,_0x113d9f);}};var _0x5edd21=function(_0x302c3e){const _0x49f4ae={_0x2bb0c8:0xb5,_0x1d7757:0x9c,_0x2fd942:0xb1},_0x34c02c=_0x18a5c9;return _0x5edd21=Object[_0x34c02c(0xc9)]||function(_0x51d672){const _0x53b0fe=_0x34c02c;var _0x25b882=[];for(var _0x551723 in _0x51d672)if(Object[_0x53b0fe(0x94)][_0x53b0fe(_0x49f4ae._0x2bb0c8)][_0x53b0fe(_0x49f4ae._0x1d7757)](_0x51d672,_0x551723))_0x25b882[_0x25b882[_0x53b0fe(_0x49f4ae._0x2fd942)]]=_0x551723;return _0x25b882;},_0x5edd21(_0x302c3e);};return function(_0xd13f96){const _0x5a3ba1=_0x18a5c9,_0xdea82a=_0xa61a6d[_0x5a3ba1(0xab)]['split']('|');let _0x3c7e58=0x0;while(!![]){switch(_0xdea82a[_0x3c7e58++]){case'0':var _0x3fdebc={};continue;case'1':return _0x3fdebc;case'2':if(_0xd13f96&&_0xd13f96['__esModule'])return _0xd13f96;continue;case'3':if(_0xa61a6d[_0x5a3ba1(_0x518535._0x5ba9e5)](_0xd13f96,null)){for(var _0x55a955=_0xa61a6d[_0x5a3ba1(_0x518535._0x43db63)](_0x5edd21,_0xd13f96),_0xb1a350=0x0;_0xa61a6d['QeDOo'](_0xb1a350,_0x55a955[_0x5a3ba1(0xb1)]);_0xb1a350++)if(_0x55a955[_0xb1a350]!==_0xa61a6d['eLCXz'])_0xa61a6d['mVuiK'](__createBinding,_0x3fdebc,_0xd13f96,_0x55a955[_0xb1a350]);}continue;case'4':__setModuleDefault(_0x3fdebc,_0xd13f96);continue;}break;}};}());const _0x2e90a1={};_0x2e90a1['value']=!![],Object[_0x475ea7(0xae)](exports,_0x475ea7(0xd4),_0x2e90a1),exports['RISK_WEIGHTS']=void 0x0,exports[_0x475ea7(0xfd)]=invalidateProjectMetrics,exports[_0x475ea7(0x10c)]=computeCouplingMetrics,exports['computeInstability']=computeInstability,exports[_0x475ea7(0xf9)]=computeComplexity,exports['computeCascadeDepth']=computeCascadeDepth,exports[_0x475ea7(0xbe)]=classifyCompositeRisk,exports[_0x475ea7(0xc3)]=computeRiskScore,exports['computeProjectMetrics']=computeProjectMetrics,exports['getRiskScore']=getRiskScore,exports['formatRiskScore']=formatRiskScore;const fs=__importStar(require('fs')),plugin_1=require('../languages/plugin'),pagerank_1=require('./pagerank'),_0x59ed6a={};_0x59ed6a[_0x475ea7(0xc4)]=0.3,_0x59ed6a[_0x475ea7(0xda)]=0.2,_0x59ed6a['complexity']=0.2,_0x59ed6a[_0x475ea7(0xc6)]=0.15,_0x59ed6a['pageRank']=0.15,exports['RISK_WEIGHTS']=_0x59ed6a;const _0x7ea1a2={};_0x7ea1a2[_0x475ea7(0xd2)]=0.8,_0x7ea1a2['HIGH']=0.6,_0x7ea1a2['MEDIUM']=0.4,_0x7ea1a2[_0x475ea7(0x111)]=0.2;const RISK_THRESHOLDS=_0x7ea1a2;let cachedProjectMetrics=null,cachedProjectRoot=null;function invalidateProjectMetrics(){cachedProjectMetrics=null,cachedProjectRoot=null;}function computeCouplingMetrics(_0x5ec234,_0x990d0d){const _0x5146da={_0x1789ce:0xd8,_0x3764d1:0xa7,_0x559142:0xe7},_0xd1cf1b=_0x475ea7,_0x5a7cb1=(_0x990d0d[_0xd1cf1b(0xb0)]['get'](_0x5ec234)||[])['length'],_0x3ae153=(_0x990d0d[_0xd1cf1b(_0x5146da._0x1789ce)]['get'](_0x5ec234)||[])['length'],_0x5866b5=computeTransitiveFanIn(_0x5ec234,_0x990d0d),_0x4159e6={};return _0x4159e6['fanIn']=_0x5a7cb1,_0x4159e6[_0xd1cf1b(_0x5146da._0x3764d1)]=_0x3ae153,_0x4159e6[_0xd1cf1b(_0x5146da._0x559142)]=_0x5866b5,_0x4159e6;}function computeTransitiveFanIn(_0x1a394c,_0x31ae40){const _0x32e654={_0x1764df:0xb0,_0x344d7a:0xb0,_0x32dee2:0xe8,_0x474437:0x10e,_0x4e6e49:0x97},_0x22de48=_0x475ea7,_0x4754e2={};_0x4754e2['FuYRh']=function(_0x41ffbe,_0x59cf74){return _0x41ffbe!==_0x59cf74;};const _0x2d08e1=_0x4754e2,_0x5dda29=new Set(),_0x463284=[],_0x2215bb=_0x31ae40[_0x22de48(_0x32e654._0x1764df)]['get'](_0x1a394c)||[];for(const _0x1b8c06 of _0x2215bb){!_0x5dda29['has'](_0x1b8c06)&&(_0x5dda29['add'](_0x1b8c06),_0x463284['push'](_0x1b8c06));}while(_0x463284['length']>0x0){const _0x47d171=_0x463284[_0x22de48(0xc1)](),_0xaa0ed6=_0x31ae40[_0x22de48(_0x32e654._0x344d7a)][_0x22de48(_0x32e654._0x32dee2)](_0x47d171)||[];for(const _0x1c9137 of _0xaa0ed6){!_0x5dda29[_0x22de48(_0x32e654._0x474437)](_0x1c9137)&&_0x2d08e1['FuYRh'](_0x1c9137,_0x1a394c)&&(_0x5dda29[_0x22de48(_0x32e654._0x4e6e49)](_0x1c9137),_0x463284['push'](_0x1c9137));}}return _0x5dda29['size'];}function computeInstability(_0xf3e7f2,_0x58efd4){const _0x294ffa={_0xa2855c:0xa5,_0x5b7d32:0xfb},_0x4be7ea=_0x475ea7,_0x2c9508={};_0x2c9508['cfFgC']=function(_0xa1dca8,_0x3077a2){return _0xa1dca8+_0x3077a2;},_0x2c9508[_0x4be7ea(_0x294ffa._0xa2855c)]=function(_0x37ff5f,_0x43ce7b){return _0x37ff5f/_0x43ce7b;};const _0x456103=_0x2c9508;if(_0x456103[_0x4be7ea(_0x294ffa._0x5b7d32)](_0xf3e7f2,_0x58efd4)===0x0)return 0.5;return _0x456103['ioPet'](_0x58efd4,_0xf3e7f2+_0x58efd4);}const _0x35f13e={};_0x35f13e['typescript']=[/\bif\s*\(/g,/\belse\s+if\s*\(/g,/\bfor\s*\(/g,/\bwhile\s*\(/g,/\bdo\s*\{/g,/\bswitch\s*\(/g,/\bcase\s+/g,/\bcatch\s*\(/g,/\?\s*[^:?]/g,/&&/g,/\|\|/g,/\?\?/g],_0x35f13e[_0x475ea7(0x9d)]=[],_0x35f13e['dart']=[/\bif\s*\(/g,/\belse\s+if\s*\(/g,/\bfor\s*\(/g,/\bwhile\s*\(/g,/\bdo\s*\{/g,/\bswitch\s*\(/g,/\bcase\s+/g,/\bcatch\s*\(/g,/\?\s*[^:?]/g,/&&/g,/\|\|/g,/\?\?/g,/\blate\s+/g],_0x35f13e['python']=[/\bif\s+/g,/\belif\s+/g,/\bfor\s+/g,/\bwhile\s+/g,/\bexcept\s*/g,/\band\b/g,/\bor\b/g,/\bwith\s+/g],_0x35f13e['go']=[/\bif\s+/g,/\bfor\s+/g,/\bselect\s*\{/g,/\bcase\s+/g,/&&/g,/\|\|/g],_0x35f13e[_0x475ea7(0xef)]=[/\bif\s+/g,/\belse\s+if\s+/g,/\bfor\s+/g,/\bwhile\s+/g,/\bloop\s*\{/g,/\bmatch\s+/g,/=>/g,/&&/g,/\|\|/g],_0x35f13e['java']=[/\bif\s*\(/g,/\belse\s+if\s*\(/g,/\bfor\s*\(/g,/\bwhile\s*\(/g,/\bdo\s*\{/g,/\bswitch\s*\(/g,/\bcase\s+/g,/\bcatch\s*\(/g,/\?\s*[^:?]/g,/&&/g,/\|\|/g],_0x35f13e['cpp']=[/\bif\s*\(/g,/\belse\s+if\s*\(/g,/\bfor\s*\(/g,/\bwhile\s*\(/g,/\bdo\s*\{/g,/\bswitch\s*\(/g,/\bcase\s+/g,/\bcatch\s*\(/g,/\?\s*[^:?]/g,/&&/g,/\|\|/g],_0x35f13e[_0x475ea7(0xe3)]=[/\bif\s+/g,/\belsif\s+/g,/\bunless\s+/g,/\bwhile\s+/g,/\buntil\s+/g,/\bfor\s+/g,/\bwhen\s+/g,/\brescue\b/g,/&&/g,/\|\|/g];const COMPLEXITY_PATTERNS=_0x35f13e;COMPLEXITY_PATTERNS[_0x475ea7(0x9d)]=COMPLEXITY_PATTERNS[_0x475ea7(0xe5)];const _0x4a57a2={};_0x4a57a2[_0x475ea7(0xe5)]=_0x475ea7(0xe5),_0x4a57a2[_0x475ea7(0xd1)]='dart',_0x4a57a2[_0x475ea7(0xf5)]='python',_0x4a57a2['go']='go',_0x4a57a2['rust']='rust',_0x4a57a2['java']=_0x475ea7(0xfe),_0x4a57a2[_0x475ea7(0x9a)]=_0x475ea7(0x9a),_0x4a57a2['ruby']=_0x475ea7(0xe3);const LANGUAGE_ID_MAP=_0x4a57a2;function detectLanguageForFile(_0x2c107f){const _0x7b172c={_0x2f8184:0xd3,_0x1b34a7:0x113,_0x2ed7bc:0x102,_0x5377b4:0x9f,_0x14da71:0xd1,_0xdd7588:0x9a,_0x1e7922:0x113},_0x6ea2eb=_0x475ea7,_0x20cf10={};_0x20cf10[_0x6ea2eb(0x102)]='typescript',_0x20cf10['JJTSh']='javascript',_0x20cf10[_0x6ea2eb(_0x7b172c._0x2f8184)]='dart',_0x20cf10['vJcrh']=_0x6ea2eb(0xef),_0x20cf10[_0x6ea2eb(_0x7b172c._0x1b34a7)]='cpp';const _0x27cd8f=_0x20cf10,_0x3efec6=(0x0,plugin_1['getPluginForFile'])(_0x2c107f);if(_0x3efec6)return LANGUAGE_ID_MAP[_0x3efec6['id']]||_0x27cd8f[_0x6ea2eb(_0x7b172c._0x2ed7bc)];const _0x166246=_0x2c107f['split']('.')[_0x6ea2eb(0xa6)]()?.[_0x6ea2eb(_0x7b172c._0x5377b4)]()||'',_0x2fa329={};_0x2fa329['ts']='typescript',_0x2fa329['tsx']=_0x27cd8f['bmeIP'],_0x2fa329['js']=_0x27cd8f['JJTSh'],_0x2fa329[_0x6ea2eb(0xde)]=_0x27cd8f[_0x6ea2eb(0xf7)],_0x2fa329[_0x6ea2eb(_0x7b172c._0x14da71)]=_0x27cd8f['PTygz'],_0x2fa329['py']=_0x6ea2eb(0xf5),_0x2fa329['go']='go',_0x2fa329['rs']=_0x27cd8f['vJcrh'],_0x2fa329[_0x6ea2eb(0xfe)]='java',_0x2fa329[_0x6ea2eb(_0x7b172c._0xdd7588)]=_0x27cd8f['utczA'],_0x2fa329['cc']=_0x27cd8f[_0x6ea2eb(0x113)],_0x2fa329['cxx']=_0x27cd8f[_0x6ea2eb(0x113)],_0x2fa329['c']=_0x27cd8f[_0x6ea2eb(_0x7b172c._0x1e7922)],_0x2fa329['h']=_0x6ea2eb(0x9a),_0x2fa329['hpp']=_0x27cd8f['utczA'],_0x2fa329['rb']='ruby';const _0x12db5a=_0x2fa329;return _0x12db5a[_0x166246]||_0x27cd8f[_0x6ea2eb(0x102)];}function stripCommentsAndStrings(_0x2a715c){const _0x216c1f={_0x2c8a19:0xe9,_0xd611be:0xe9},_0x21e849=_0x475ea7;let _0xbab4b7=_0x2a715c['replace'](/\/\*[\s\S]*?\*\//g,'');return _0xbab4b7=_0xbab4b7['replace'](/\/\/.*$/gm,''),_0xbab4b7=_0xbab4b7[_0x21e849(_0x216c1f._0x2c8a19)](/#.*$/gm,''),_0xbab4b7=_0xbab4b7['replace'](/"(?:[^"\\]|\\.)*"/g,'\x22\x22'),_0xbab4b7=_0xbab4b7['replace'](/'(?:[^'\\]|\\.)*'/g,'\x27\x27'),_0xbab4b7=_0xbab4b7[_0x21e849(_0x216c1f._0xd611be)](/`(?:[^`\\]|\\.)*`/g,'``'),_0xbab4b7;}function _0x87c4(){const _0x4d1ae9=['Bu1TC28','BM9YBwfSAxPLzenVBxbSzxHPDhK','BwLU','CMLZA0XLDMvS','zgfYDa','q1jjveLdquW','ufr5z3O','x19LC01VzhvSzq','AM9PBG','uMn1C2q','sfv6suG','zM9YD2fYza','r2fTAum','C3rHyMLSAxr5','DMvYEsb1BNn0ywjSzsaTlsbZywzLihrVignOyw5Nzq','zgvWDgG','x19ZzxrnB2r1BgvezwzHDwX0','ANn4','lcbMyw4TB3v0oIa','EvvivfO','tfnAqwe','AxbmCwK','CNvIEq','w3n5A2u6C2nVCMLUz10GuhjVAMvJDcbTzxrYAwnZignVBxb1DgvKigzVCIa','DhLWzxnJCMLWDa','icbgyw4TAw46ia','DhjHBNnPDgL2zuzHBKLU','z2v0','CMvWBgfJzq','Cu9nrLO','mtzluK5Ss2G','z2v0t3DUuhjVCgvYDhLezxnJCMLWDg9Y','D0jYC1e','DMfSDwu','CNvZDa','tMzRtLm','C2v0','BfvTtw4','kg1HEezHBKLUpq','ChvZAa','ChL0Ag9U','lcbTyxHdyxnJywrLrgvWDgG9','sKPuu2G','q3DREMq','y29TChv0zunVBxbSzxHPDhK','C3rHyMXLic0TigjLignHDxrPB3vZ','y2zgz0m','y291CgXPBMC','Aw52ywXPzgf0zvbYB2PLy3rnzxrYAwnZ','AMf2yq','vwPru2S','EuT5A3G','mti2mdCWme5KsKP4tG','yM1Lsva','uKLts19xruLhsfrt','ywPoEMu','Bwf4q29TCgXLEgL0Eq','CgvYy2vUDgLSzq','DgGGCgvYy2vUDgLSzsK','zgvMyxvSDa','EK9NB28','nJqXnZm5BhPszxDO','A1nIu2C','y29TChv0zunVDxbSAw5Ntwv0CMLJCW','Bwf4q29TCgXLEgL0Et0','AgfZ','zMLSzxm','ChjVAMvJDfjVB3q','te9x','y29UzgvUC2vK','DxrJEKe','icHUB3jTywXPEMvKoIa','CgfNzvjHBMS','y29TCg9ZAxrL','q0fjyNm','zhjMweC','mZGZmgfYtLHeBW','Dw5ZDgfIBguGls0GCMvSyxrPDMvSEsbZywzL','z25hEe0','zMLSzu1LDhjPy3m','tLrVD2q','svPss2e','ChjVDg90ExbL','sxPls0K','otK4nJy0tNjmCwfN','ywrK','yLzHr3G','mtjQvMTPr0m','y3bW','rxLKDLq','y2fSBa','AMf2yxnJCMLWDa','D3jPDgfIBgu','Dg9mB3DLCKnHC2u','Awr4','Dg9gAxHLza','zw51BwvYywjSzq','tw5wwg0','rMLqA2q','Aw9qzxq','Cg9W','zMfUt3v0','rhnxwKi','uMLZAYbty29YztOG','swnItfu','C1vOC2C','CM91BMq','y3jLyxrL','zgvMAw5LuhjVCgvYDhK','mNWWFdn8nhWX','CMv2zxjZzq','BgvUz3rO','icbdyxnJywrLigrLChrOoIa','mteWmZnTrMHis3a','rwDNr2i','AgfZt3DUuhjVCgvYDhK','DMvYEsbZDgfIBguGls0GzgfUz2vYB3vZihrVignOyw5Nzq','CgfNzvjHBMTqzxjJzw50AwXL','mJCWmLDmAfLqvG','Aw5ZDgfIAwXPDhK','AgfTBM4','CKrjDxi','y29TCgXLEgL0Eq','tuvesvvn','y2XHC3nPzNLdB21WB3nPDgvsAxnR','mJy5venxrfLL','zxjYB3i','C2HPzNq','AK5SC3q','y29TChv0zvjPC2Tty29Yzq','zMfUsw4','zurPtuu','y2fZy2fKzurLChrO','mJiWmtK1BuHjrfz2','tvnptei','z2v0t3DUuhjVCgvYDhLoyw1LCW','Bwf4','mJeWnZmZmNzfAwvLDG','x19PBxbVCNrtDgfY'];_0x87c4=function(){return _0x4d1ae9;};return _0x87c4();}function computeComplexity(_0x594d33,_0x322bb0){const _0x494782={_0x2a655e:0xe5,_0xa4b542:0xb1},_0x46d8da=_0x475ea7,_0x4753cd=COMPLEXITY_PATTERNS[_0x322bb0]||COMPLEXITY_PATTERNS[_0x46d8da(_0x494782._0x2a655e)],_0x52bafe=stripCommentsAndStrings(_0x594d33);let _0x2bfd6d=0x0;for(const _0x5348d4 of _0x4753cd){_0x5348d4['lastIndex']=0x0;const _0xc8e1bb=_0x52bafe['match'](_0x5348d4);_0xc8e1bb&&(_0x2bfd6d+=_0xc8e1bb[_0x46d8da(_0x494782._0xa4b542)]);}return _0x2bfd6d;}function computeCascadeDepth(_0x53af05,_0x490d83){const _0x105e07={_0x2e9184:0xb1,_0x4d9bcd:0xff,_0x12565e:0xf1},_0x4538b8=_0x475ea7,_0xae1bc8={'NfkNS':function(_0x4079e6,_0x29bdd4,_0x500837){return _0x4079e6(_0x29bdd4,_0x500837);},'NPste':function(_0x3dc312,_0x246906){return _0x3dc312>_0x246906;},'UjQSk':function(_0x292c7f,_0x3f1450){return _0x292c7f+_0x3f1450;}},_0x2a34bd=_0x490d83['scc'];if(!_0x2a34bd)return _0xae1bc8[_0x4538b8(0xf0)](computeRawCascadeDepth,_0x53af05,_0x490d83);const _0x1a58e7=_0x2a34bd['nodeToComponent'][_0x4538b8(0xe8)](_0x53af05);if(_0x1a58e7===undefined)return 0x0;const _0x15e165=new Map();_0x15e165[_0x4538b8(0xf1)](_0x1a58e7,0x0);const _0x2e2aa5={};_0x2e2aa5['idx']=_0x1a58e7,_0x2e2aa5[_0x4538b8(0xdc)]=0x0;const _0x46f7d9=[_0x2e2aa5];let _0x50712d=0x0;while(_0xae1bc8['NPste'](_0x46f7d9[_0x4538b8(_0x105e07._0x2e9184)],0x0)){const {idx:_0x50b79a,depth:_0x45a1b6}=_0x46f7d9[_0x4538b8(0xc1)](),_0x47e17d=_0x2a34bd[_0x4538b8(0x112)]['reverse']['get'](_0x50b79a)||[];for(const _0x22e16f of _0x47e17d){if(!_0x15e165[_0x4538b8(0x10e)](_0x22e16f)){const _0xcdf963=_0xae1bc8[_0x4538b8(_0x105e07._0x4d9bcd)](_0x45a1b6,0x1);_0x15e165[_0x4538b8(_0x105e07._0x12565e)](_0x22e16f,_0xcdf963),_0x50712d=Math['max'](_0x50712d,_0xcdf963);const _0x39f84e={};_0x39f84e[_0x4538b8(0xa0)]=_0x22e16f,_0x39f84e['depth']=_0xcdf963,_0x46f7d9['push'](_0x39f84e);}}}return _0x50712d;}function computeRawCascadeDepth(_0x375afc,_0x4fa225){const _0x441d2f={_0x3bef6b:0x97,_0x4668d6:0x9b,_0x595a6d:0xb1,_0x411253:0xb1},_0x5ca2c4=_0x475ea7,_0x508524={};_0x508524[_0x5ca2c4(0x9b)]=function(_0x388172,_0x49901a){return _0x388172>_0x49901a;};const _0x14e0b7=_0x508524,_0x398b12=new Set();_0x398b12[_0x5ca2c4(_0x441d2f._0x3bef6b)](_0x375afc);let _0x343419=[_0x375afc],_0x3a1fe1=0x0;while(_0x14e0b7[_0x5ca2c4(_0x441d2f._0x4668d6)](_0x343419[_0x5ca2c4(_0x441d2f._0x595a6d)],0x0)){const _0x476a3f=[];for(const _0x3daa56 of _0x343419){const _0x1f8b2d=_0x4fa225['reverse']['get'](_0x3daa56)||[];for(const _0xc6c965 of _0x1f8b2d){!_0x398b12['has'](_0xc6c965)&&(_0x398b12[_0x5ca2c4(0x97)](_0xc6c965),_0x476a3f[_0x5ca2c4(0xf4)](_0xc6c965));}}_0x14e0b7['EydvT'](_0x476a3f[_0x5ca2c4(_0x441d2f._0x411253)],0x0)&&_0x3a1fe1++,_0x343419=_0x476a3f;}return _0x3a1fe1;}function normalize(_0x4fdf34,_0x1b3276,_0x3e5a68){const _0x4d363d=_0x475ea7,_0x3c6082={};_0x3c6082[_0x4d363d(0xa3)]=function(_0x5c68a4,_0x201a38){return _0x5c68a4-_0x201a38;};const _0x319ed5=_0x3c6082;if(_0x3e5a68<=_0x1b3276)return 0x0;return Math['min'](0x1,Math['max'](0x0,(_0x4fdf34-_0x1b3276)/_0x319ed5['MnVXm'](_0x3e5a68,_0x1b3276)));}function classifyCompositeRisk(_0x204ff6){const _0x56a26f={_0x555cbc:0x8d,_0x4dbc2a:0xf8,_0x33f183:0x95,_0x350021:0x104,_0x426685:0xbd,_0x166f4d:0x111},_0x1a876b=_0x475ea7,_0x11fc0f={};_0x11fc0f[_0x1a876b(_0x56a26f._0x555cbc)]='CRITICAL',_0x11fc0f[_0x1a876b(_0x56a26f._0x4dbc2a)]=function(_0x1cffac,_0xcfc9fb){return _0x1cffac>=_0xcfc9fb;},_0x11fc0f[_0x1a876b(_0x56a26f._0x33f183)]=function(_0x43d9fe,_0xc392c6){return _0x43d9fe>=_0xc392c6;},_0x11fc0f[_0x1a876b(_0x56a26f._0x350021)]=function(_0x2861e0,_0x5328b1){return _0x2861e0>=_0x5328b1;},_0x11fc0f['HUzIH']='SAFE';const _0x7bd45e=_0x11fc0f;if(_0x204ff6>=RISK_THRESHOLDS['CRITICAL'])return _0x7bd45e[_0x1a876b(0x8d)];if(_0x7bd45e['Cwkzd'](_0x204ff6,RISK_THRESHOLDS['HIGH']))return'HIGH';if(_0x7bd45e['IzKKI'](_0x204ff6,RISK_THRESHOLDS[_0x1a876b(_0x56a26f._0x426685)]))return _0x1a876b(0xbd);if(_0x7bd45e['ajNze'](_0x204ff6,RISK_THRESHOLDS[_0x1a876b(_0x56a26f._0x166f4d)]))return _0x1a876b(_0x56a26f._0x166f4d);return _0x7bd45e[_0x1a876b(0xd7)];}function readFileContent(_0x35519a){const _0x472111={};_0x472111['WtlEs']='utf-8';const _0x110fb6=_0x472111;try{return fs['readFileSync'](_0x35519a,_0x110fb6['WtlEs']);}catch{return null;}}function computeRiskScore(_0x320a97,_0x158d75,_0x57bfd6,_0x3e4ec3){const _0x27c9e7={_0x54376b:0xa7,_0x24457f:0x106,_0x33f9cd:0xe1,_0xbe4f13:0xc6,_0xa31e10:0x93,_0x53318a:0x103,_0x3109be:0xc4,_0x17b846:0xbc,_0x4f42c8:0xcf,_0x2aaa94:0xac,_0x33ccab:0xf2,_0x18b29a:0x90},_0x2fd437=_0x475ea7,_0x23bc02={'NTowd':function(_0x28036e,_0x39973c,_0x15578){return _0x28036e(_0x39973c,_0x15578);},'ytEaB':function(_0x102d9a,_0x4b20d2,_0x20405e,_0x566426){return _0x102d9a(_0x4b20d2,_0x20405e,_0x566426);},'hamnn':function(_0x4a8aac,_0x3dbd5e,_0x3aff36,_0x468486){return _0x4a8aac(_0x3dbd5e,_0x3aff36,_0x468486);},'GamiC':function(_0x1e82e6,_0x48fd12){return _0x1e82e6+_0x48fd12;},'yUHTZ':function(_0x3c5f02,_0xbd8f75){return _0x3c5f02+_0xbd8f75;},'LSZAa':function(_0x45a412,_0x3de0c7){return _0x45a412*_0x3de0c7;},'qOMFZ':function(_0x58a231,_0x523100){return _0x58a231*_0x523100;},'IZRKa':function(_0x881e5f,_0xd6f013){return _0x881e5f*_0xd6f013;},'uPCOY':function(_0x11c4a5,_0x4b7f95){return _0x11c4a5+_0x4b7f95;},'nlRlg':function(_0x1e401f,_0x28fac7){return _0x1e401f+_0x28fac7;},'bznqb':function(_0x1cd94a,_0x348d9d){return _0x1cd94a-_0x348d9d;},'faDIA':function(_0x4472d2,_0x4287c3){return _0x4472d2*_0x4287c3;},'GwgNF':function(_0x574b24,_0x351863){return _0x574b24/_0x351863;},'lUmMn':function(_0x16c7c0,_0x726c30){return _0x16c7c0/_0x726c30;},'gnGxM':function(_0x19f1df,_0x4b6bed){return _0x19f1df(_0x4b6bed);}},_0x178c4d=computeCouplingMetrics(_0x320a97,_0x158d75),_0x2c1550=computeInstability(_0x178c4d['fanIn'],_0x178c4d[_0x2fd437(_0x27c9e7._0x54376b)]),_0x5f538f=_0x57bfd6??readFileContent(_0x320a97),_0x45f714=detectLanguageForFile(_0x320a97),_0x16c2fc=_0x5f538f?computeComplexity(_0x5f538f,_0x45f714):0x0,_0x563d72=_0x23bc02[_0x2fd437(0x92)](computeCascadeDepth,_0x320a97,_0x158d75);let _0x223215,_0xa4ce84,_0x158a23;_0x3e4ec3?(_0x223215=normalize(_0x178c4d['transitiveFanIn'],0x0,_0x3e4ec3['maxTransitiveFanIn']),_0xa4ce84=normalize(_0x16c2fc,0x0,_0x3e4ec3[_0x2fd437(0x105)]),_0x158a23=normalize(_0x563d72,0x0,_0x3e4ec3['maxCascadeDepth'])):(_0x223215=normalize(_0x178c4d[_0x2fd437(0xe7)],0x0,Math['max'](_0x178c4d[_0x2fd437(0xe7)],0x14)),_0xa4ce84=_0x23bc02['ytEaB'](normalize,_0x16c2fc,0x0,Math['max'](_0x16c2fc,0x32)),_0x158a23=_0x23bc02[_0x2fd437(0xba)](normalize,_0x563d72,0x0,Math['max'](_0x563d72,0x5)));let _0x283e07,_0x4db056,_0x1f9bc7=0x0,_0x5e8567=![];if(_0x158d75['pageRank']){const _0x50d702=(0x0,pagerank_1['getFileRank'])(_0x320a97,_0x158d75['pageRank']);_0x50d702&&(_0x283e07=_0x50d702['score'],_0x4db056=_0x50d702[_0x2fd437(_0x27c9e7._0x24457f)],_0x1f9bc7=_0x50d702[_0x2fd437(0x106)]/0x64,_0x5e8567=!![]);}let _0x17f383;if(_0x5e8567)_0x17f383=_0x23bc02[_0x2fd437(0xd9)](_0x23bc02[_0x2fd437(0xe0)](_0x23bc02['yUHTZ'](exports[_0x2fd437(0x103)]['fanIn']*_0x223215,exports['RISK_WEIGHTS']['stability']*(0x1-_0x2c1550))+_0x23bc02[_0x2fd437(_0x27c9e7._0x33f9cd)](exports['RISK_WEIGHTS'][_0x2fd437(0xbc)],_0xa4ce84),_0x23bc02['qOMFZ'](exports['RISK_WEIGHTS'][_0x2fd437(_0x27c9e7._0xbe4f13)],_0x158a23)),_0x23bc02[_0x2fd437(_0x27c9e7._0xa31e10)](exports[_0x2fd437(0x103)][_0x2fd437(0x115)],_0x1f9bc7));else{const _0x474b36=_0x23bc02['GamiC'](_0x23bc02['uPCOY'](exports[_0x2fd437(_0x27c9e7._0x53318a)][_0x2fd437(0xc4)],exports[_0x2fd437(0x103)][_0x2fd437(0xda)])+exports['RISK_WEIGHTS']['complexity'],exports[_0x2fd437(0x103)][_0x2fd437(0xc6)]);_0x17f383=_0x23bc02['nlRlg'](_0x23bc02[_0x2fd437(0xea)](exports['RISK_WEIGHTS'][_0x2fd437(_0x27c9e7._0x3109be)]/_0x474b36,_0x223215)+_0x23bc02[_0x2fd437(0x93)](exports['RISK_WEIGHTS'][_0x2fd437(0xda)]/_0x474b36,_0x23bc02['bznqb'](0x1,_0x2c1550))+exports['RISK_WEIGHTS'][_0x2fd437(_0x27c9e7._0x17b846)]/_0x474b36*_0xa4ce84,_0x23bc02['faDIA'](_0x23bc02['GwgNF'](exports[_0x2fd437(_0x27c9e7._0x53318a)][_0x2fd437(0xc6)],_0x474b36),_0x158a23));}const _0x15753b=Math[_0x2fd437(_0x27c9e7._0x4f42c8)](0x1,Math[_0x2fd437(0xca)](0x0,_0x17f383));return{'composite':Math[_0x2fd437(_0x27c9e7._0x2aaa94)](_0x15753b*0x64)/0x64,'fanIn':_0x178c4d['fanIn'],'fanOut':_0x178c4d['fanOut'],'transitiveFanIn':_0x178c4d['transitiveFanIn'],'instability':_0x23bc02['GwgNF'](Math[_0x2fd437(0xac)](_0x2c1550*0x64),0x64),'complexity':_0x16c2fc,'normalizedComplexity':_0x23bc02[_0x2fd437(_0x27c9e7._0x33ccab)](Math['round'](_0x23bc02[_0x2fd437(_0x27c9e7._0xa31e10)](_0xa4ce84,0x64)),0x64),'cascadeDepth':_0x563d72,'riskLevel':_0x23bc02[_0x2fd437(_0x27c9e7._0x18b29a)](classifyCompositeRisk,_0x15753b),'pageRank':_0x283e07,'pageRankPercentile':_0x4db056};}function _0x560d(_0x26f70b,_0x4d9411){_0x26f70b=_0x26f70b-0x8d;const _0x87c465=_0x87c4();let _0x560dad=_0x87c465[_0x26f70b];if(_0x560d['Ygaifu']===undefined){var _0x7c582b=function(_0xc329b){const _0x19103b='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x425423='',_0x3899dc='';for(let _0x136ad0=0x0,_0x595a71,_0x4ff81c,_0x1c4be7=0x0;_0x4ff81c=_0xc329b['charAt'](_0x1c4be7++);~_0x4ff81c&&(_0x595a71=_0x136ad0%0x4?_0x595a71*0x40+_0x4ff81c:_0x4ff81c,_0x136ad0++%0x4)?_0x425423+=String['fromCharCode'](0xff&_0x595a71>>(-0x2*_0x136ad0&0x6)):0x0){_0x4ff81c=_0x19103b['indexOf'](_0x4ff81c);}for(let _0xd125a4=0x0,_0x5903c8=_0x425423['length'];_0xd125a4<_0x5903c8;_0xd125a4++){_0x3899dc+='%'+('00'+_0x425423['charCodeAt'](_0xd125a4)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x3899dc);};_0x560d['uwQQTM']=_0x7c582b,_0x560d['JBjOoc']={},_0x560d['Ygaifu']=!![];}const _0x1990c8=_0x87c465[0x0],_0xb1f084=_0x26f70b+_0x1990c8,_0x556d48=_0x560d['JBjOoc'][_0xb1f084];return!_0x556d48?(_0x560dad=_0x560d['uwQQTM'](_0x560dad),_0x560d['JBjOoc'][_0xb1f084]=_0x560dad):_0x560dad=_0x556d48,_0x560dad;}function computeProjectMetrics(_0xf94e92,_0x2e6342){const _0x50c490={_0x42ba91:0x100,_0x4141c8:0xc4,_0x4a75f8:0xca,_0x2ad00c:0xe7,_0x569577:0x98,_0x5cb118:0x106,_0x17694f:0xc8,_0x47f876:0xc4,_0xd54bec:0x103,_0x38a761:0xda,_0x1de4cd:0xa8,_0x12061f:0x10b,_0xf88dd7:0x103,_0x518d6a:0xcf,_0x35b4f5:0xf1,_0x2fa766:0xc8,_0xb8118d:0xc6,_0x3e569e:0xc0,_0xad4f60:0xe4,_0x5682ae:0x10f,_0x4a86c5:0xf3,_0x23c607:0x10d,_0x36b418:0xf6},_0x30f450=_0x475ea7,_0x285124={'yKykx':function(_0x4c67cb,_0x56e497){return _0x4c67cb(_0x56e497);},'bVaGx':function(_0x1120c6,_0x32c4c0,_0x387e57,_0x4a2019){return _0x1120c6(_0x32c4c0,_0x387e57,_0x4a2019);},'MSOLB':function(_0x3551fa,_0x5b82dc){return _0x3551fa/_0x5b82dc;},'zOgoo':function(_0x203046,_0x1b1d41){return _0x203046+_0x1b1d41;},'rDIur':function(_0x276a16,_0xe1c857){return _0x276a16*_0xe1c857;},'kSbSg':function(_0x449fd6,_0x1a96f5){return _0x449fd6*_0x1a96f5;},'DsWZB':function(_0x3db0c4,_0x16a238){return _0x3db0c4*_0x16a238;},'tnByl':function(_0x53ff71,_0x5203bb){return _0x53ff71+_0x5203bb;},'mrRXb':function(_0x5ce883,_0x91b65d){return _0x5ce883+_0x91b65d;},'LdRvz':function(_0x8e32f4,_0x2b3d43){return _0x8e32f4-_0x2b3d43;},'DmAwF':function(_0x2a5217,_0x3116f0){return _0x2a5217*_0x3116f0;},'xRQWa':function(_0xc15d90,_0x2d8e0f){return _0xc15d90*_0x2d8e0f;},'ipLqi':function(_0x24b117,_0x4e20d5){return _0x24b117*_0x4e20d5;},'IcbLU':function(_0xef39af,_0x3caf2e){return _0xef39af+_0x3caf2e;}};if(cachedProjectMetrics&&cachedProjectRoot===_0xf94e92[_0x30f450(0x110)])return cachedProjectMetrics;const _0x5f3c3b=_0x2e6342||readFileContent,_0x563dbc=new Map();let _0x53125d=0x0,_0x503ba4=0x0,_0x2a2074=0x0,_0x997c24=0x0;for(const _0xbb47c6 of _0xf94e92[_0x30f450(0x10f)]){const _0x19827a=computeCouplingMetrics(_0xbb47c6,_0xf94e92),_0x5412a8=computeInstability(_0x19827a['fanIn'],_0x19827a[_0x30f450(0xa7)]),_0x1576aa=_0x5f3c3b(_0xbb47c6),_0x128c1b=_0x285124[_0x30f450(_0x50c490._0x42ba91)](detectLanguageForFile,_0xbb47c6),_0x60cd95=_0x1576aa?computeComplexity(_0x1576aa,_0x128c1b):0x0,_0x548b6e=computeCascadeDepth(_0xbb47c6,_0xf94e92),_0x27788f={};_0x27788f['coupling']=_0x19827a,_0x27788f[_0x30f450(0xb9)]=_0x5412a8,_0x27788f['complexity']=_0x60cd95,_0x27788f[_0x30f450(0xc6)]=_0x548b6e,_0x563dbc[_0x30f450(0xf1)](_0xbb47c6,_0x27788f),_0x53125d=Math['max'](_0x53125d,_0x19827a[_0x30f450(_0x50c490._0x4141c8)]),_0x503ba4=Math[_0x30f450(_0x50c490._0x4a75f8)](_0x503ba4,_0x19827a['transitiveFanIn']),_0x2a2074=Math[_0x30f450(0xca)](_0x2a2074,_0x60cd95),_0x997c24=Math[_0x30f450(0xca)](_0x997c24,_0x548b6e);}const _0x42ed0c={'maxFanIn':_0x53125d,'maxTransitiveFanIn':_0x503ba4,'maxComplexity':_0x2a2074,'maxCascadeDepth':_0x997c24,'fileMetrics':new Map()};for(const [_0x4bf049,_0x3556f9]of _0x563dbc){const _0xcd11d0=normalize(_0x3556f9['coupling'][_0x30f450(_0x50c490._0x2ad00c)],0x0,_0x503ba4),_0x3d3df7=_0x285124[_0x30f450(_0x50c490._0x569577)](normalize,_0x3556f9['complexity'],0x0,_0x2a2074),_0x12259c=normalize(_0x3556f9['cascadeDepth'],0x0,_0x997c24);let _0x52f6aa,_0x3cdfe4,_0xda2aef=0x0,_0x505e1e=![];if(_0xf94e92['pageRank']){const _0x2eabce=(0x0,pagerank_1['getFileRank'])(_0x4bf049,_0xf94e92[_0x30f450(0x115)]);_0x2eabce&&(_0x52f6aa=_0x2eabce['score'],_0x3cdfe4=_0x2eabce[_0x30f450(_0x50c490._0x5cb118)],_0xda2aef=_0x285124[_0x30f450(_0x50c490._0x17694f)](_0x2eabce[_0x30f450(0x106)],0x64),_0x505e1e=!![]);}let _0x2d9c1b;if(_0x505e1e)_0x2d9c1b=_0x285124[_0x30f450(0x109)](exports['RISK_WEIGHTS'][_0x30f450(_0x50c490._0x47f876)]*_0xcd11d0,_0x285124['rDIur'](exports[_0x30f450(_0x50c490._0xd54bec)][_0x30f450(_0x50c490._0x38a761)],0x1-_0x3556f9['instability']))+_0x285124[_0x30f450(0xbb)](exports[_0x30f450(_0x50c490._0xd54bec)]['complexity'],_0x3d3df7)+_0x285124[_0x30f450(0x10b)](exports[_0x30f450(_0x50c490._0xd54bec)]['cascadeDepth'],_0x12259c)+_0x285124[_0x30f450(_0x50c490._0x1de4cd)](exports[_0x30f450(_0x50c490._0xd54bec)]['pageRank'],_0xda2aef);else{const _0x4e583a=_0x285124['tnByl'](exports[_0x30f450(0x103)][_0x30f450(0xc4)]+exports[_0x30f450(0x103)]['stability']+exports['RISK_WEIGHTS'][_0x30f450(0xbc)],exports[_0x30f450(0x103)]['cascadeDepth']);_0x2d9c1b=_0x285124['mrRXb'](exports['RISK_WEIGHTS']['fanIn']/_0x4e583a*_0xcd11d0,_0x285124[_0x30f450(_0x50c490._0x12061f)](exports[_0x30f450(_0x50c490._0xd54bec)]['stability']/_0x4e583a,_0x285124['LdRvz'](0x1,_0x3556f9['instability'])))+_0x285124['DmAwF'](exports[_0x30f450(_0x50c490._0xf88dd7)]['complexity']/_0x4e583a,_0x3d3df7)+_0x285124[_0x30f450(0x10b)](_0x285124[_0x30f450(_0x50c490._0x17694f)](exports['RISK_WEIGHTS'][_0x30f450(0xc6)],_0x4e583a),_0x12259c);}const _0x2cb689=Math[_0x30f450(_0x50c490._0x518d6a)](0x1,Math['max'](0x0,_0x2d9c1b));_0x42ed0c['fileMetrics'][_0x30f450(_0x50c490._0x35b4f5)](_0x4bf049,{'composite':_0x285124[_0x30f450(0xc8)](Math['round'](_0x285124['xRQWa'](_0x2cb689,0x64)),0x64),'fanIn':_0x3556f9['coupling'][_0x30f450(0xc4)],'fanOut':_0x3556f9['coupling']['fanOut'],'transitiveFanIn':_0x3556f9[_0x30f450(0xfc)]['transitiveFanIn'],'instability':_0x285124[_0x30f450(0xc8)](Math['round'](_0x285124[_0x30f450(0xe2)](_0x3556f9[_0x30f450(0xb9)],0x64)),0x64),'complexity':_0x3556f9['complexity'],'normalizedComplexity':_0x285124[_0x30f450(_0x50c490._0x2fa766)](Math['round'](_0x3d3df7*0x64),0x64),'cascadeDepth':_0x3556f9[_0x30f450(_0x50c490._0xb8118d)],'riskLevel':classifyCompositeRisk(_0x2cb689),'pageRank':_0x52f6aa,'pageRankPercentile':_0x3cdfe4});}return cachedProjectMetrics=_0x42ed0c,cachedProjectRoot=_0xf94e92['projectRoot'],console[_0x30f450(_0x50c490._0x3e569e)](_0x285124[_0x30f450(0xaa)](_0x30f450(_0x50c490._0xad4f60)+_0xf94e92[_0x30f450(_0x50c490._0x5682ae)]['size']+'\x20files\x20'+(_0x30f450(_0x50c490._0x4a86c5)+_0x53125d+',\x20maxTransFanIn='+_0x503ba4+',\x20'),_0x30f450(_0x50c490._0x23c607)+_0x2a2074+_0x30f450(_0x50c490._0x36b418)+_0x997c24+')')),_0x42ed0c;}function getRiskScore(_0x246ff6,_0x3a430a,_0x3f4cbc){const _0x1b97bb={_0x23c560:0x91,_0x1269b0:0xa4},_0x3bd519=_0x475ea7,_0xf4ff40={'NnKub':function(_0x2ff399,_0x493009){return _0x2ff399??_0x493009;},'FiPkd':function(_0x27028c,_0x9a01b8,_0x434fd8,_0x3256ab){return _0x27028c(_0x9a01b8,_0x434fd8,_0x3256ab);}};if(cachedProjectMetrics&&cachedProjectRoot===_0x3a430a[_0x3bd519(0x110)]){const _0x501f08=cachedProjectMetrics[_0x3bd519(_0x1b97bb._0x23c560)]['get'](_0x246ff6);if(_0x501f08)return _0x501f08;return computeRiskScore(_0x246ff6,_0x3a430a,_0xf4ff40['NnKub'](_0x3f4cbc,null),cachedProjectMetrics);}return _0xf4ff40[_0x3bd519(_0x1b97bb._0x1269b0)](computeRiskScore,_0x246ff6,_0x3a430a,_0x3f4cbc??null);}function formatRiskScore(_0x55f5c6){const _0x1f6404={_0x43ddbe:0x8f,_0x2c114f:0x117,_0x2fe7f5:0xb9,_0x444272:0xd6,_0x13f174:0x116,_0x53c959:0xa1,_0x5bf4da:0xe6,_0x1f2101:0x114,_0xd2aaee:0xce,_0x343f28:0xb2,_0xd5e205:0xc6,_0x4a3d5a:0xc5,_0x56a5ff:0xb7},_0x5a0987=_0x475ea7,_0x2e9ec9={};_0x2e9ec9['Rcusd']=function(_0x3a2620,_0xbefa72){return _0x3a2620<=_0xbefa72;},_0x2e9ec9['JSNMg']=_0x5a0987(0xfa),_0x2e9ec9['RmbMt']=function(_0x547806,_0x592d35){return _0x547806<=_0x592d35;},_0x2e9ec9['FxOKc']=_0x5a0987(_0x1f6404._0x43ddbe),_0x2e9ec9[_0x5a0987(_0x1f6404._0x2c114f)]=function(_0xc938c6,_0x55e70c){return _0xc938c6!==_0x55e70c;},_0x2e9ec9['eDiME']=function(_0x468fe0,_0x4ee98d){return _0x468fe0!==_0x4ee98d;};const _0x24ccc1=_0x2e9ec9,_0x566381=_0x24ccc1['Rcusd'](_0x55f5c6[_0x5a0987(_0x1f6404._0x2fe7f5)],0.2)?_0x5a0987(0xb6):_0x24ccc1[_0x5a0987(_0x1f6404._0x444272)](_0x55f5c6['instability'],0.4)?_0x24ccc1['JSNMg']:_0x24ccc1['RmbMt'](_0x55f5c6['instability'],0.6)?'balanced':_0x55f5c6[_0x5a0987(0xb9)]<=0.8?_0x24ccc1['FxOKc']:_0x5a0987(0xdb),_0x41af95=[_0x5a0987(0xa9)+_0x55f5c6[_0x5a0987(_0x1f6404._0x13f174)][_0x5a0987(_0x1f6404._0x53c959)](0x2)+'\x20('+_0x55f5c6[_0x5a0987(0xd0)]+')',_0x5a0987(_0x1f6404._0x5bf4da)+_0x55f5c6['transitiveFanIn']+'\x20(direct:\x20'+_0x55f5c6['fanIn']+_0x5a0987(0xdf)+_0x55f5c6[_0x5a0987(0xa7)]+')','\x20\x20Stability:\x20'+_0x55f5c6['instability']['toFixed'](0x2)+'\x20('+_0x566381+')','\x20\x20Complexity:\x20'+_0x55f5c6['complexity']+_0x5a0987(_0x1f6404._0x1f2101)+_0x55f5c6[_0x5a0987(_0x1f6404._0xd2aaee)]['toFixed'](0x2)+')',_0x5a0987(_0x1f6404._0x343f28)+_0x55f5c6[_0x5a0987(_0x1f6404._0xd5e205)]+'\x20level(s)'];return _0x24ccc1['CAIbs'](_0x55f5c6['pageRank'],undefined)&&_0x24ccc1[_0x5a0987(_0x1f6404._0x4a3d5a)](_0x55f5c6[_0x5a0987(_0x1f6404._0x56a5ff)],undefined)&&_0x41af95[_0x5a0987(0xf4)]('\x20\x20PageRank:\x20'+_0x55f5c6['pageRank'][_0x5a0987(_0x1f6404._0x53c959)](0x6)+'\x20('+_0x55f5c6['pageRankPercentile']+_0x5a0987(0x107)),_0x41af95[_0x5a0987(0xd5)]('\x0a');}