@syke1/mcp-server 1.5.6 → 1.6.1

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 _0x15e495=_0x11fd;(function(_0x5133a3,_0x4aa94a){const _0x49c731={_0x50b98e:0x82,_0x3a18f8:0xbb,_0x18e395:0x97,_0x111e56:0xcc},_0x1601e9=_0x11fd,_0x4cf4c8=_0x5133a3();while(!![]){try{const _0x123fdb=-parseInt(_0x1601e9(0xc2))/0x1*(parseInt(_0x1601e9(0x91))/0x2)+parseInt(_0x1601e9(0xd4))/0x3*(parseInt(_0x1601e9(_0x49c731._0x50b98e))/0x4)+-parseInt(_0x1601e9(0x71))/0x5+-parseInt(_0x1601e9(_0x49c731._0x3a18f8))/0x6*(parseInt(_0x1601e9(0x88))/0x7)+parseInt(_0x1601e9(0xc1))/0x8*(-parseInt(_0x1601e9(0x7a))/0x9)+-parseInt(_0x1601e9(0xf4))/0xa*(-parseInt(_0x1601e9(0xf2))/0xb)+-parseInt(_0x1601e9(_0x49c731._0x18e395))/0xc*(-parseInt(_0x1601e9(_0x49c731._0x111e56))/0xd);if(_0x123fdb===_0x4aa94a)break;else _0x4cf4c8['push'](_0x4cf4c8['shift']());}catch(_0x545343){_0x4cf4c8['push'](_0x4cf4c8['shift']());}}}(_0x1ce9,0x89b2f));function _0x11fd(_0x399c73,_0xf8eb5c){_0x399c73=_0x399c73-0x6f;const _0x1ce9b0=_0x1ce9();let _0x11fd0e=_0x1ce9b0[_0x399c73];if(_0x11fd['RxfKou']===undefined){var _0x17852e=function(_0x4bc2a3){const _0x311917='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x25bdbf='',_0x99235d='';for(let _0x531292=0x0,_0x275d34,_0x4393fb,_0x435d78=0x0;_0x4393fb=_0x4bc2a3['charAt'](_0x435d78++);~_0x4393fb&&(_0x275d34=_0x531292%0x4?_0x275d34*0x40+_0x4393fb:_0x4393fb,_0x531292++%0x4)?_0x25bdbf+=String['fromCharCode'](0xff&_0x275d34>>(-0x2*_0x531292&0x6)):0x0){_0x4393fb=_0x311917['indexOf'](_0x4393fb);}for(let _0x1bdc75=0x0,_0x431778=_0x25bdbf['length'];_0x1bdc75<_0x431778;_0x1bdc75++){_0x99235d+='%'+('00'+_0x25bdbf['charCodeAt'](_0x1bdc75)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x99235d);};_0x11fd['oimZDe']=_0x17852e,_0x11fd['LknJXT']={},_0x11fd['RxfKou']=!![];}const _0x1d0042=_0x1ce9b0[0x0],_0x261f86=_0x399c73+_0x1d0042,_0x24cc71=_0x11fd['LknJXT'][_0x261f86];return!_0x24cc71?(_0x11fd0e=_0x11fd['oimZDe'](_0x11fd0e),_0x11fd['LknJXT'][_0x261f86]=_0x11fd0e):_0x11fd0e=_0x24cc71,_0x11fd0e;}var __createBinding=this&&this[_0x15e495(0x98)]||(Object['create']?function(_0x4b1c90,_0x22d015,_0x415976,_0x141b58){const _0x2b4431={_0x441569:0x8e,_0x1857b4:0x94,_0x3aec41:0x96,_0x1c0580:0x94,_0xc7222c:0x8f},_0x52d729=_0x15e495,_0x4479fe={};_0x4479fe[_0x52d729(_0x2b4431._0x441569)]=function(_0xfdb73e,_0x2c6a1d){return _0xfdb73e in _0x2c6a1d;};const _0x385f0d=_0x4479fe;if(_0x141b58===undefined)_0x141b58=_0x415976;var _0x234222=Object['getOwnPropertyDescriptor'](_0x22d015,_0x415976);if(!_0x234222||(_0x385f0d['NJfEM'](_0x52d729(_0x2b4431._0x1857b4),_0x234222)?!_0x22d015['__esModule']:_0x234222['writable']||_0x234222['configurable'])){const _0x102d67={};_0x102d67[_0x52d729(_0x2b4431._0x3aec41)]=!![],_0x102d67[_0x52d729(_0x2b4431._0x1c0580)]=function(){return _0x22d015[_0x415976];},_0x234222=_0x102d67;}Object[_0x52d729(_0x2b4431._0xc7222c)](_0x4b1c90,_0x141b58,_0x234222);}:function(_0x4cc546,_0x3abce7,_0x5c061d,_0x560425){const _0x2fcef6={_0x4be856:0xca},_0x3636cd=_0x15e495,_0x5d82f6={};_0x5d82f6[_0x3636cd(_0x2fcef6._0x4be856)]=function(_0x1d96ff,_0x51b5bb){return _0x1d96ff===_0x51b5bb;};const _0x1578ef=_0x5d82f6;if(_0x1578ef['LGJur'](_0x560425,undefined))_0x560425=_0x5c061d;_0x4cc546[_0x560425]=_0x3abce7[_0x5c061d];}),__setModuleDefault=this&&this[_0x15e495(0x70)]||(Object['create']?function(_0xb582ad,_0x1bea11){const _0x2e7662={_0x3ab290:0xec},_0x4a253f=_0x15e495,_0x4f9c8d={};_0x4f9c8d['soEiB']=_0x4a253f(_0x2e7662._0x3ab290);const _0x14a7c9=_0x4f9c8d,_0x14b2d1={};_0x14b2d1[_0x4a253f(0x96)]=!![],_0x14b2d1['value']=_0x1bea11,Object['defineProperty'](_0xb582ad,_0x14a7c9['soEiB'],_0x14b2d1);}:function(_0x2c71e6,_0x2e813f){const _0x543da7={_0x1a73a1:0xec},_0x42af06=_0x15e495;_0x2c71e6[_0x42af06(_0x543da7._0x1a73a1)]=_0x2e813f;}),__importStar=this&&this['__importStar']||(function(){const _0x48e169={_0x558b5e:0xbc},_0x493600={'GsKqz':function(_0x6f58df,_0x1dcc77){return _0x6f58df(_0x1dcc77);},'jDUuD':function(_0x5efbf4,_0x2ec28f){return _0x5efbf4<_0x2ec28f;},'ePKvb':function(_0x1f9f47,_0x461bf6){return _0x1f9f47!==_0x461bf6;},'REhvl':function(_0x16f465,_0x45bc7a,_0x42fecc,_0x33d293){return _0x16f465(_0x45bc7a,_0x42fecc,_0x33d293);}};var _0x1e29f3=function(_0x1cd25a){return _0x1e29f3=Object['getOwnPropertyNames']||function(_0x98a0bc){const _0x1f917e=_0x11fd;var _0x48a401=[];for(var _0x5d5a28 in _0x98a0bc)if(Object[_0x1f917e(0x7e)][_0x1f917e(0x76)][_0x1f917e(0x89)](_0x98a0bc,_0x5d5a28))_0x48a401[_0x48a401[_0x1f917e(_0x48e169._0x558b5e)]]=_0x5d5a28;return _0x48a401;},_0x1e29f3(_0x1cd25a);};return function(_0x171e34){const _0x1ddd04=_0x11fd,_0x5ae959=_0x1ddd04(0xd2)['split']('|');let _0x3fc56e=0x0;while(!![]){switch(_0x5ae959[_0x3fc56e++]){case'0':if(_0x171e34&&_0x171e34['__esModule'])return _0x171e34;continue;case'1':if(_0x171e34!=null){for(var _0x6ad3d4=_0x493600['GsKqz'](_0x1e29f3,_0x171e34),_0x579dde=0x0;_0x493600['jDUuD'](_0x579dde,_0x6ad3d4['length']);_0x579dde++)if(_0x493600[_0x1ddd04(0x87)](_0x6ad3d4[_0x579dde],_0x1ddd04(0xec)))_0x493600['REhvl'](__createBinding,_0x24eb6a,_0x171e34,_0x6ad3d4[_0x579dde]);}continue;case'2':return _0x24eb6a;case'3':__setModuleDefault(_0x24eb6a,_0x171e34);continue;case'4':var _0x24eb6a={};continue;}break;}};}());const _0x316e5b={};_0x316e5b[_0x15e495(0xe9)]=!![],Object[_0x15e495(0x8f)](exports,_0x15e495(0xee),_0x316e5b),exports['RISK_WEIGHTS']=void 0x0,exports[_0x15e495(0xa4)]=invalidateProjectMetrics,exports['computeCouplingMetrics']=computeCouplingMetrics,exports[_0x15e495(0xeb)]=computeInstability,exports['computeComplexity']=computeComplexity,exports[_0x15e495(0xa7)]=computeCascadeDepth,exports[_0x15e495(0xbe)]=classifyCompositeRisk,exports['computeRiskScore']=computeRiskScore,exports[_0x15e495(0xf1)]=computeProjectMetrics,exports['getRiskScore']=getRiskScore,exports['formatRiskScore']=formatRiskScore;const fs=__importStar(require('fs')),plugin_1=require('../languages/plugin'),pagerank_1=require('./pagerank'),_0x4c9059={};_0x4c9059['fanIn']=0.3,_0x4c9059[_0x15e495(0xb5)]=0.2,_0x4c9059[_0x15e495(0xdc)]=0.2,_0x4c9059['cascadeDepth']=0.15,_0x4c9059[_0x15e495(0xbd)]=0.15,exports[_0x15e495(0xd0)]=_0x4c9059;const _0x564b85={};_0x564b85['CRITICAL']=0.8,_0x564b85[_0x15e495(0xcd)]=0.6,_0x564b85[_0x15e495(0x78)]=0.4,_0x564b85[_0x15e495(0xb0)]=0.2;const RISK_THRESHOLDS=_0x564b85;let cachedProjectMetrics=null,cachedProjectRoot=null;function invalidateProjectMetrics(){cachedProjectMetrics=null,cachedProjectRoot=null;}function computeCouplingMetrics(_0x161224,_0x16a950){const _0x2cd987={_0x5cbc15:0x94,_0x7f00a6:0xbc,_0x35a9ba:0x94},_0x4db239=_0x15e495,_0x43b125={'iTCLO':function(_0x52d633,_0x2ba61a,_0x412bbf){return _0x52d633(_0x2ba61a,_0x412bbf);}},_0xb8e3b=(_0x16a950[_0x4db239(0xc7)][_0x4db239(_0x2cd987._0x5cbc15)](_0x161224)||[])[_0x4db239(_0x2cd987._0x7f00a6)],_0x548448=(_0x16a950['forward'][_0x4db239(_0x2cd987._0x35a9ba)](_0x161224)||[])['length'],_0x36881e=_0x43b125[_0x4db239(0x79)](computeTransitiveFanIn,_0x161224,_0x16a950),_0x5311b7={};return _0x5311b7['fanIn']=_0xb8e3b,_0x5311b7[_0x4db239(0x9e)]=_0x548448,_0x5311b7[_0x4db239(0xab)]=_0x36881e,_0x5311b7;}function computeTransitiveFanIn(_0x562cdb,_0x176c06){const _0x5ef54b={_0x4f7167:0x74,_0x290514:0xbf,_0x32d99c:0xdd,_0x35b07d:0x8d},_0x2d6760=_0x15e495,_0x5750cd={};_0x5750cd['BoWwz']=function(_0x292c09,_0x300de1){return _0x292c09>_0x300de1;},_0x5750cd[_0x2d6760(0xdd)]=function(_0x6667ea,_0x32723c){return _0x6667ea!==_0x32723c;};const _0x2e6f0b=_0x5750cd,_0x4460b4=new Set(),_0x4dd930=[],_0x15a393=_0x176c06[_0x2d6760(0xc7)]['get'](_0x562cdb)||[];for(const _0x1eefa8 of _0x15a393){!_0x4460b4[_0x2d6760(_0x5ef54b._0x4f7167)](_0x1eefa8)&&(_0x4460b4['add'](_0x1eefa8),_0x4dd930[_0x2d6760(0xdb)](_0x1eefa8));}while(_0x2e6f0b['BoWwz'](_0x4dd930[_0x2d6760(0xbc)],0x0)){const _0x2ff188=_0x4dd930[_0x2d6760(_0x5ef54b._0x290514)](),_0x4c5ecd=_0x176c06['reverse'][_0x2d6760(0x94)](_0x2ff188)||[];for(const _0x591847 of _0x4c5ecd){!_0x4460b4['has'](_0x591847)&&_0x2e6f0b[_0x2d6760(_0x5ef54b._0x32d99c)](_0x591847,_0x562cdb)&&(_0x4460b4[_0x2d6760(_0x5ef54b._0x35b07d)](_0x591847),_0x4dd930[_0x2d6760(0xdb)](_0x591847));}}return _0x4460b4['size'];}function computeInstability(_0x3ab75c,_0x13398e){const _0x48bf2d={_0x1d328c:0x8c},_0x1fc7e3=_0x15e495,_0x28da1e={};_0x28da1e[_0x1fc7e3(0x92)]=function(_0x44d5a0,_0x3b80ca){return _0x44d5a0===_0x3b80ca;},_0x28da1e[_0x1fc7e3(0xcb)]=function(_0x48bda5,_0x2b661a){return _0x48bda5+_0x2b661a;},_0x28da1e['RYdlj']=function(_0x1cda4f,_0xe176de){return _0x1cda4f/_0xe176de;},_0x28da1e[_0x1fc7e3(_0x48bf2d._0x1d328c)]=function(_0x1aebb7,_0x4562b4){return _0x1aebb7+_0x4562b4;};const _0x64b2b8=_0x28da1e;if(_0x64b2b8['CZYnj'](_0x64b2b8[_0x1fc7e3(0xcb)](_0x3ab75c,_0x13398e),0x0))return 0.5;return _0x64b2b8[_0x1fc7e3(0x7f)](_0x13398e,_0x64b2b8[_0x1fc7e3(0x8c)](_0x3ab75c,_0x13398e));}const _0x3bbef1={};_0x3bbef1[_0x15e495(0x73)]=[/\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],_0x3bbef1[_0x15e495(0xcf)]=[],_0x3bbef1['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],_0x3bbef1['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],_0x3bbef1['go']=[/\bif\s+/g,/\bfor\s+/g,/\bselect\s*\{/g,/\bcase\s+/g,/&&/g,/\|\|/g],_0x3bbef1['rust']=[/\bif\s+/g,/\belse\s+if\s+/g,/\bfor\s+/g,/\bwhile\s+/g,/\bloop\s*\{/g,/\bmatch\s+/g,/=>/g,/&&/g,/\|\|/g],_0x3bbef1[_0x15e495(0x9d)]=[/\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],_0x3bbef1['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],_0x3bbef1[_0x15e495(0xc8)]=[/\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=_0x3bbef1;COMPLEXITY_PATTERNS['javascript']=COMPLEXITY_PATTERNS[_0x15e495(0x73)];const _0x19547a={};_0x19547a[_0x15e495(0x73)]='typescript',_0x19547a['dart']='dart',_0x19547a[_0x15e495(0xef)]=_0x15e495(0xef),_0x19547a['go']='go',_0x19547a[_0x15e495(0x84)]=_0x15e495(0x84),_0x19547a['java']='java',_0x19547a['cpp']='cpp',_0x19547a[_0x15e495(0xc8)]='ruby';const LANGUAGE_ID_MAP=_0x19547a;function detectLanguageForFile(_0x6df76b){const _0x47648a={_0x39048a:0x80,_0x227dd7:0xa1,_0xe1e342:0xb8,_0x1a0210:0xf7,_0x19944c:0xf3,_0x5678ec:0x84,_0xd1256d:0xf5,_0x3ff55f:0xe8},_0x55c57e=_0x15e495,_0x446b5f={};_0x446b5f[_0x55c57e(0xe8)]='typescript',_0x446b5f[_0x55c57e(_0x47648a._0x39048a)]='javascript',_0x446b5f[_0x55c57e(_0x47648a._0x227dd7)]=_0x55c57e(0xef),_0x446b5f['MWjNB']=_0x55c57e(_0x47648a._0xe1e342);const _0x31d6db=_0x446b5f,_0x562267=(0x0,plugin_1[_0x55c57e(0xae)])(_0x6df76b);if(_0x562267)return LANGUAGE_ID_MAP[_0x562267['id']]||_0x31d6db[_0x55c57e(0xe8)];const _0x396d89=_0x6df76b[_0x55c57e(_0x47648a._0x1a0210)]('.')['pop']()?.['toLowerCase']()||'',_0x18499a={};_0x18499a['ts']='typescript',_0x18499a[_0x55c57e(_0x47648a._0x19944c)]=_0x31d6db['tFaFP'],_0x18499a['js']=_0x31d6db['jZVHH'],_0x18499a['jsx']=_0x31d6db['jZVHH'],_0x18499a['dart']='dart',_0x18499a['py']=_0x31d6db[_0x55c57e(0xa1)],_0x18499a['go']='go',_0x18499a['rs']=_0x55c57e(_0x47648a._0x5678ec),_0x18499a['java']=_0x55c57e(0x9d),_0x18499a[_0x55c57e(_0x47648a._0xe1e342)]=_0x31d6db['MWjNB'],_0x18499a['cc']=_0x31d6db['MWjNB'],_0x18499a[_0x55c57e(0xd9)]=_0x31d6db[_0x55c57e(_0x47648a._0xd1256d)],_0x18499a['c']=_0x31d6db[_0x55c57e(0xf5)],_0x18499a['h']=_0x31d6db[_0x55c57e(0xf5)],_0x18499a[_0x55c57e(0xaa)]=_0x31d6db['MWjNB'],_0x18499a['rb']='ruby';const _0x240b0a=_0x18499a;return _0x240b0a[_0x396d89]||_0x31d6db[_0x55c57e(_0x47648a._0x3ff55f)];}function stripCommentsAndStrings(_0x1ba67e){const _0x3c56b4={_0x224d21:0xc5,_0xe6dd91:0xc5,_0x403c58:0xc5},_0x57b104=_0x15e495;let _0x129b25=_0x1ba67e[_0x57b104(_0x3c56b4._0x224d21)](/\/\*[\s\S]*?\*\//g,'');return _0x129b25=_0x129b25[_0x57b104(_0x3c56b4._0xe6dd91)](/\/\/.*$/gm,''),_0x129b25=_0x129b25[_0x57b104(0xc5)](/#.*$/gm,''),_0x129b25=_0x129b25[_0x57b104(_0x3c56b4._0x403c58)](/"(?:[^"\\]|\\.)*"/g,'\x22\x22'),_0x129b25=_0x129b25['replace'](/'(?:[^'\\]|\\.)*'/g,'\x27\x27'),_0x129b25=_0x129b25[_0x57b104(0xc5)](/`(?:[^`\\]|\\.)*`/g,'``'),_0x129b25;}function _0x1ce9(){const _0x45704d=['C2HPzNq','uhvHBNG','mtq1mJmYCNnXtLjP','ote5wK9mz2vm','u0fgrq','sKrJr0m','CMvWBgfJzq','lcbMyw4TB3v0oIa','CMv2zxjZzq','CNvIEq','AvLNyKm','teDkDxi','rxvbrg4','mJyWmeDwv2jOtW','seLhsa','BgfZDeLUzgv4','AMf2yxnJCMLWDa','uKLts19xruLhsfrt','Aw5ZDgfIAwXPDhK','mhW0Fdf8m3WY','t0HtEu4','nJKWCMvqA3be','CgvYy2vUDgLSzq','wfDwAxa','sw9KAKy','vuPRvfa','y3H4','C2nVCMu','ChvZAa','y29TCgXLEgL0Eq','uhbVzwu','D0DvC1O','BwLU','AM9PBG','Dg9gAxHLza','q2rjrfu','A1Pczfu','CvnruK0','zxjYB3i','yu93y2q','Bwf4','DezHrLa','DMfSDwu','tML5yue','y29TChv0zuLUC3rHyMLSAxr5','zgvMyxvSDa','zurSzuK','x19LC01VzhvSzq','ChL0Ag9U','C2L6zq','y29TChv0zvbYB2PLy3rnzxrYAwnZ','ndyWnZLUrK9cDeG','Dhn4','mJe5mfzVyLHNsG','tvDQtKi','DgGGCgvYy2vUDgLSzsK','C3bSAxq','zMLSzxm','x19ZzxrnB2r1BgvezwzHDwX0','mJC2nZq5nur5ENrPyG','C2nJ','DhLWzxnJCMLWDa','AgfZ','icbqywDLuMfUAZOG','AgfZt3DUuhjVCgvYDhK','y1jLA0e','tuvesvvn','Avrdte8','mtGWugn0wvP2','ChjVAMvJDfjVB3q','qM9WDwq','icbdB21WBgv4Axr5oIa','ChjVDg90ExbL','uLLKBgO','ALPwseG','uMLZAYbty29YztOG','mtm4mJHMCfrizuG','icbdyxnJywrLigrLChrOoIa','CNvZDa','zMfUsw4','kg1HEezHBKLUpq','zvblDMi','ntztDwXhzxm','y2fSBa','y291CgXPBMC','seHVqvy','vKjSzue','ywrK','tKPMru0','zgvMAw5LuhjVCgvYDhK','t3vrrMK','mtCWvKvQuhz0','q1PzBMO','igXLDMvSkhmP','z2v0','zfrgtMe','zw51BwvYywjSzq','nduXmJbXufzevve','x19JCMvHDgvcAw5KAw5N','zvbgANq','yMfSyw5Jzwq','uxjiuMO','rgPgBeS','AMf2yq','zMfUt3v0','y29UzgvUC2vK','C3rHyMXLic0TigjLignHDxrPB3vZ','qwzvsLq','Bwf0y2G','qNzAzgu','Aw52ywXPzgf0zvbYB2PLy3rnzxrYAwnZ','y0LgAw4','C2v0','y29TChv0zunHC2nHzgvezxb0Aa','zK5qreK','veLWEuK','AhbW','DhjHBNnPDgL2zuzHBKLU','CM91BMq','Bwf4vhjHBNnPDgL2zuzHBKLU','z2v0ugX1z2LUrM9YrMLSzq','mxW0Fdn8mNWW','te9x','BM9YBwfSAxPLzenVBxbSzxHPDhK','tuXtv3e','zMLSzu1LDhjPy3m','tLbfteS','C3rHyMLSAxr5','z2v0rMLSzvjHBMS','q1rxv0m','y3bW','AuLesKS','y2fZy2fKzurLChrO','nJC5mZq0rvvUtuv5','BgvUz3rO','CgfNzvjHBMS','y2XHC3nPzNLdB21WB3nPDgvsAxnR'];_0x1ce9=function(){return _0x45704d;};return _0x1ce9();}function computeComplexity(_0x296879,_0x2b4dc6){const _0x570b80={_0x2d6bc5:0x73,_0x40f963:0xa2,_0x45a35d:0xbc},_0x47d482=_0x15e495,_0x4db785=COMPLEXITY_PATTERNS[_0x2b4dc6]||COMPLEXITY_PATTERNS[_0x47d482(_0x570b80._0x2d6bc5)],_0xfe2313=stripCommentsAndStrings(_0x296879);let _0x32a463=0x0;for(const _0x5a17f7 of _0x4db785){_0x5a17f7[_0x47d482(0xce)]=0x0;const _0x4f8cf0=_0xfe2313[_0x47d482(_0x570b80._0x40f963)](_0x5a17f7);_0x4f8cf0&&(_0x32a463+=_0x4f8cf0[_0x47d482(_0x570b80._0x45a35d)]);}return _0x32a463;}function computeCascadeDepth(_0x35387c,_0x5e55d2){const _0x276c65={_0x1785a1:0x72,_0x4f4254:0xa6},_0x4fcc27=_0x15e495,_0xd11f4e={};_0xd11f4e[_0x4fcc27(0xe4)]=function(_0x287632,_0x36285b){return _0x287632+_0x36285b;};const _0x59cffc=_0xd11f4e,_0x232bcc=_0x5e55d2[_0x4fcc27(_0x276c65._0x1785a1)];if(!_0x232bcc)return computeRawCascadeDepth(_0x35387c,_0x5e55d2);const _0x35f92f=_0x232bcc['nodeToComponent']['get'](_0x35387c);if(_0x35f92f===undefined)return 0x0;const _0x59e7e2=new Map();_0x59e7e2[_0x4fcc27(_0x276c65._0x4f4254)](_0x35f92f,0x0);const _0x291cc2={};_0x291cc2['idx']=_0x35f92f,_0x291cc2['depth']=0x0;const _0x419171=[_0x291cc2];let _0x1c51a0=0x0;while(_0x419171['length']>0x0){const {idx:_0x187df3,depth:_0x2781ec}=_0x419171['shift'](),_0xda06b2=_0x232bcc[_0x4fcc27(0x9f)]['reverse'][_0x4fcc27(0x94)](_0x187df3)||[];for(const _0x2058c8 of _0xda06b2){if(!_0x59e7e2['has'](_0x2058c8)){const _0x165c01=_0x59cffc['qSQRM'](_0x2781ec,0x1);_0x59e7e2[_0x4fcc27(_0x276c65._0x4f4254)](_0x2058c8,_0x165c01),_0x1c51a0=Math[_0x4fcc27(0xe7)](_0x1c51a0,_0x165c01);const _0x2415ef={};_0x2415ef['idx']=_0x2058c8,_0x2415ef['depth']=_0x165c01,_0x419171['push'](_0x2415ef);}}}return _0x1c51a0;}function computeRawCascadeDepth(_0x487814,_0x20f77a){const _0x2dee1d={_0x400d4a:0xea},_0x142a21=_0x15e495,_0xf85667={};_0xf85667['NiyaA']=function(_0x1a74b0,_0x395a1f){return _0x1a74b0>_0x395a1f;};const _0x545fcb=_0xf85667,_0x305fa1=new Set();_0x305fa1[_0x142a21(0x8d)](_0x487814);let _0x1c2b0c=[_0x487814],_0x1d57ee=0x0;while(_0x1c2b0c[_0x142a21(0xbc)]>0x0){const _0x4bfd90=[];for(const _0x289d2c of _0x1c2b0c){const _0x52622e=_0x20f77a['reverse']['get'](_0x289d2c)||[];for(const _0xa899e0 of _0x52622e){!_0x305fa1['has'](_0xa899e0)&&(_0x305fa1['add'](_0xa899e0),_0x4bfd90[_0x142a21(0xdb)](_0xa899e0));}}_0x545fcb[_0x142a21(_0x2dee1d._0x400d4a)](_0x4bfd90['length'],0x0)&&_0x1d57ee++,_0x1c2b0c=_0x4bfd90;}return _0x1d57ee;}function normalize(_0x1395ca,_0x5d3f39,_0x39d42b){if(_0x39d42b<=_0x5d3f39)return 0x0;return Math['min'](0x1,Math['max'](0x0,(_0x1395ca-_0x5d3f39)/(_0x39d42b-_0x5d3f39)));}function classifyCompositeRisk(_0x518f29){const _0x22c651={_0x3ce590:0xa5,_0x58f54e:0xc9},_0x23807b=_0x15e495,_0xe7628a={};_0xe7628a['OPGtx']=_0x23807b(0xaf),_0xe7628a[_0x23807b(0xb4)]=_0x23807b(0xc3),_0xe7628a['Bopud']=function(_0x3fa2f0,_0x346ca9){return _0x3fa2f0>=_0x346ca9;},_0xe7628a['BRKtb']='CRITICAL',_0xe7628a['cIFin']=function(_0x3bf355,_0x2f9856){return _0x3bf355>=_0x2f9856;},_0xe7628a['iYgbC']='HIGH';const _0x4c7045=_0xe7628a,_0x1564de=_0x4c7045['OPGtx']['split']('|');let _0x2b1bd3=0x0;while(!![]){switch(_0x1564de[_0x2b1bd3++]){case'0':return _0x4c7045[_0x23807b(0xb4)];case'1':if(_0x4c7045[_0x23807b(0x7c)](_0x518f29,RISK_THRESHOLDS['CRITICAL']))return _0x4c7045['BRKtb'];continue;case'2':if(_0x4c7045[_0x23807b(_0x22c651._0x3ce590)](_0x518f29,RISK_THRESHOLDS['LOW']))return'LOW';continue;case'3':if(_0x518f29>=RISK_THRESHOLDS['MEDIUM'])return'MEDIUM';continue;case'4':if(_0x4c7045['Bopud'](_0x518f29,RISK_THRESHOLDS['HIGH']))return _0x4c7045[_0x23807b(_0x22c651._0x58f54e)];continue;}break;}}function readFileContent(_0x5dea57){try{return fs['readFileSync'](_0x5dea57,'utf-8');}catch{return null;}}function computeRiskScore(_0x24f9fe,_0x53d50e,_0x5f41db,_0x164bc0){const _0x28139e={_0x3238a7:0x85,_0x3a0b8f:0xad,_0xd3227b:0xd6,_0x74950c:0xe7,_0x3b0d13:0xbd,_0x31603b:0xd5,_0x57794f:0xd0,_0x3c4cc9:0xd0,_0x49588a:0xb2,_0x56f7ea:0xb2,_0xc04608:0x85,_0xfecdc6:0xb5,_0x591d38:0xe6,_0x5ac520:0x85,_0x239d8b:0xd0,_0x492b22:0xdc,_0x533b6f:0x99,_0x5543ce:0x90,_0x197a85:0xac,_0x4e6b38:0x90,_0x523c6c:0x90},_0x311caf=_0x15e495,_0x1b1384={'DjFlK':function(_0x530c83,_0x21f2c5,_0x401ba4){return _0x530c83(_0x21f2c5,_0x401ba4);},'bczUE':function(_0x1c1672,_0x5dbaa7){return _0x1c1672(_0x5dbaa7);},'UJkTP':function(_0x3cc867,_0x359ee6,_0x14604a,_0x390c19){return _0x3cc867(_0x359ee6,_0x14604a,_0x390c19);},'XWVip':function(_0x850879,_0x1e7e4f,_0x51c444,_0x22d3b6){return _0x850879(_0x1e7e4f,_0x51c444,_0x22d3b6);},'JDcGC':function(_0x5bc7e4,_0x579200){return _0x5bc7e4+_0x579200;},'aOwcd':function(_0x2f6937,_0x121701){return _0x2f6937*_0x121701;},'MLSWq':function(_0x504303,_0x24f7d0){return _0x504303+_0x24f7d0;},'OuQFi':function(_0x5a3f4a,_0x491d46){return _0x5a3f4a/_0x491d46;},'wGUsZ':function(_0x2bed30,_0x49db71){return _0x2bed30-_0x49db71;},'Puanx':function(_0x5b9d94,_0x3d1de8){return _0x5b9d94*_0x3d1de8;},'ePFjt':function(_0x45b5ec,_0x74ec2d){return _0x45b5ec/_0x74ec2d;},'MQwGY':function(_0x914698,_0x528c3f){return _0x914698*_0x528c3f;},'fNPDI':function(_0x284d15,_0x27884a){return _0x284d15*_0x27884a;}},_0x1c176c=_0x1b1384[_0x311caf(0x9c)](computeCouplingMetrics,_0x24f9fe,_0x53d50e),_0x3e26df=_0x1b1384['DjFlK'](computeInstability,_0x1c176c[_0x311caf(_0x28139e._0x3238a7)],_0x1c176c['fanOut']),_0xef3358=_0x5f41db??readFileContent(_0x24f9fe),_0x52cc77=_0x1b1384['bczUE'](detectLanguageForFile,_0x24f9fe),_0x34b0e2=_0xef3358?_0x1b1384[_0x311caf(0x9c)](computeComplexity,_0xef3358,_0x52cc77):0x0,_0x53a5d2=computeCascadeDepth(_0x24f9fe,_0x53d50e);let _0x41548d,_0x34a455,_0x520a3a;_0x164bc0?(_0x41548d=normalize(_0x1c176c[_0x311caf(0xab)],0x0,_0x164bc0[_0x311caf(_0x28139e._0x3a0b8f)]),_0x34a455=_0x1b1384[_0x311caf(0xd8)](normalize,_0x34b0e2,0x0,_0x164bc0['maxComplexity']),_0x520a3a=_0x1b1384[_0x311caf(_0x28139e._0xd3227b)](normalize,_0x53a5d2,0x0,_0x164bc0['maxCascadeDepth'])):(_0x41548d=normalize(_0x1c176c[_0x311caf(0xab)],0x0,Math[_0x311caf(_0x28139e._0x74950c)](_0x1c176c['transitiveFanIn'],0x14)),_0x34a455=normalize(_0x34b0e2,0x0,Math[_0x311caf(_0x28139e._0x74950c)](_0x34b0e2,0x32)),_0x520a3a=normalize(_0x53a5d2,0x0,Math['max'](_0x53a5d2,0x5)));let _0x2fecbd,_0x464e95,_0x573a9b=0x0,_0x59a35f=![];if(_0x53d50e[_0x311caf(_0x28139e._0x3b0d13)]){const _0x297c1a=(0x0,pagerank_1['getFileRank'])(_0x24f9fe,_0x53d50e['pageRank']);_0x297c1a&&(_0x2fecbd=_0x297c1a[_0x311caf(0xda)],_0x464e95=_0x297c1a[_0x311caf(_0x28139e._0x31603b)],_0x573a9b=_0x297c1a['percentile']/0x64,_0x59a35f=!![]);}let _0x9bf456;if(_0x59a35f)_0x9bf456=_0x1b1384['JDcGC'](exports['RISK_WEIGHTS'][_0x311caf(0x85)]*_0x41548d+_0x1b1384[_0x311caf(0xe6)](exports[_0x311caf(0xd0)]['stability'],0x1-_0x3e26df),_0x1b1384['aOwcd'](exports[_0x311caf(_0x28139e._0x57794f)]['complexity'],_0x34a455))+_0x1b1384['aOwcd'](exports[_0x311caf(_0x28139e._0x3c4cc9)][_0x311caf(0xba)],_0x520a3a)+_0x1b1384['aOwcd'](exports[_0x311caf(0xd0)][_0x311caf(_0x28139e._0x3b0d13)],_0x573a9b);else{const _0x533afd=_0x1b1384[_0x311caf(_0x28139e._0x49588a)](_0x1b1384[_0x311caf(_0x28139e._0x56f7ea)](exports[_0x311caf(0xd0)][_0x311caf(_0x28139e._0xc04608)],exports['RISK_WEIGHTS'][_0x311caf(_0x28139e._0xfecdc6)])+exports[_0x311caf(0xd0)][_0x311caf(0xdc)],exports['RISK_WEIGHTS']['cascadeDepth']);_0x9bf456=_0x1b1384[_0x311caf(0xc4)](_0x1b1384[_0x311caf(0xc4)](_0x1b1384[_0x311caf(_0x28139e._0x591d38)](exports[_0x311caf(0xd0)][_0x311caf(_0x28139e._0x5ac520)]/_0x533afd,_0x41548d),_0x1b1384['OuQFi'](exports[_0x311caf(0xd0)]['stability'],_0x533afd)*_0x1b1384[_0x311caf(0xde)](0x1,_0x3e26df)),_0x1b1384[_0x311caf(0xe6)](_0x1b1384['OuQFi'](exports[_0x311caf(_0x28139e._0x239d8b)][_0x311caf(_0x28139e._0x492b22)],_0x533afd),_0x34a455))+_0x1b1384[_0x311caf(0xc0)](_0x1b1384[_0x311caf(_0x28139e._0x533b6f)](exports['RISK_WEIGHTS']['cascadeDepth'],_0x533afd),_0x520a3a);}const _0x20cb7a=Math['min'](0x1,Math['max'](0x0,_0x9bf456));return{'composite':_0x1b1384[_0x311caf(_0x28139e._0x5543ce)](Math[_0x311caf(_0x28139e._0x197a85)](_0x1b1384['MQwGY'](_0x20cb7a,0x64)),0x64),'fanIn':_0x1c176c['fanIn'],'fanOut':_0x1c176c['fanOut'],'transitiveFanIn':_0x1c176c['transitiveFanIn'],'instability':_0x1b1384[_0x311caf(_0x28139e._0x4e6b38)](Math['round'](_0x3e26df*0x64),0x64),'complexity':_0x34b0e2,'normalizedComplexity':_0x1b1384[_0x311caf(_0x28139e._0x523c6c)](Math['round'](_0x1b1384[_0x311caf(0xa8)](_0x34a455,0x64)),0x64),'cascadeDepth':_0x53a5d2,'riskLevel':classifyCompositeRisk(_0x20cb7a),'pageRank':_0x2fecbd,'pageRankPercentile':_0x464e95};}function computeProjectMetrics(_0x36ef96,_0x4a38b7){const _0x5e37f4={_0x5542e6:0xd7,_0xa46873:0xba,_0x270356:0xe7,_0x492ce4:0xab,_0x4be6c5:0xb6,_0x579882:0xe3,_0x4d028e:0xd0,_0x1db927:0x85,_0x3682bc:0xd0,_0x293a7c:0xdc,_0x4ed688:0xba,_0x61536:0xd3,_0x3f2011:0xd0,_0xd06a4d:0xd0,_0x48b448:0xb9,_0x159643:0x8b,_0x2ed2eb:0xdf,_0x3f6566:0xac,_0x31f511:0x8a,_0xcad54f:0x6f,_0x4df0d4:0xf0},_0x140408=_0x15e495,_0x8fd44c={'dTFNa':function(_0x5d6596,_0x2d148d,_0x5e0328){return _0x5d6596(_0x2d148d,_0x5e0328);},'QrHRj':function(_0x26de6a,_0x21d53b,_0x3438bb){return _0x26de6a(_0x21d53b,_0x3438bb);},'CeReq':function(_0x2f7a6e,_0x538d6d){return _0x2f7a6e(_0x538d6d);},'IodjF':function(_0x5bc9f9,_0x45a432,_0x37408a){return _0x5bc9f9(_0x45a432,_0x37408a);},'eDleI':function(_0x36de58,_0x2b02e7,_0xad76e2,_0xeba512){return _0x36de58(_0x2b02e7,_0xad76e2,_0xeba512);},'gzopf':function(_0x2b9b9a,_0x25ceff,_0x2ff40d,_0x52e3fe){return _0x2b9b9a(_0x25ceff,_0x2ff40d,_0x52e3fe);},'Jiwqt':function(_0x39c10f,_0x5a60e1){return _0x39c10f/_0x5a60e1;},'OHSyN':function(_0x4a4f72,_0x1325af){return _0x4a4f72+_0x1325af;},'kZBdU':function(_0x221d25,_0x3d5809){return _0x221d25*_0x3d5809;},'GEnFd':function(_0x4f18a5,_0x485a23){return _0x4f18a5*_0x485a23;},'AARHw':function(_0x5400bb,_0x232d03){return _0x5400bb*_0x232d03;},'iIDJK':function(_0xde1354,_0x156f0c){return _0xde1354*_0x156f0c;},'HHoAV':function(_0x59555c,_0xc89a){return _0x59555c*_0xc89a;},'TIpyI':function(_0x24f3f1,_0x140bef){return _0x24f3f1*_0x140bef;},'RrMwn':function(_0x331e31,_0xc1a3c){return _0x331e31/_0xc1a3c;},'jRSkx':function(_0x364965,_0x3c36f6){return _0x364965(_0x3c36f6);},'rpArK':function(_0x4a72a7,_0x37eed3){return _0x4a72a7+_0x37eed3;}};if(cachedProjectMetrics&&cachedProjectRoot===_0x36ef96['projectRoot'])return cachedProjectMetrics;const _0x155925=_0x4a38b7||readFileContent,_0x3b4dd0=new Map();let _0x461c59=0x0,_0x434e4e=0x0,_0x4e299f=0x0,_0x4e8536=0x0;for(const _0x311836 of _0x36ef96['files']){const _0x489a09=_0x8fd44c[_0x140408(0x95)](computeCouplingMetrics,_0x311836,_0x36ef96),_0x22e74d=_0x8fd44c[_0x140408(0x9b)](computeInstability,_0x489a09['fanIn'],_0x489a09['fanOut']),_0x322e44=_0x8fd44c['CeReq'](_0x155925,_0x311836),_0xcff547=detectLanguageForFile(_0x311836),_0x5528f6=_0x322e44?_0x8fd44c[_0x140408(_0x5e37f4._0x5542e6)](computeComplexity,_0x322e44,_0xcff547):0x0,_0x368912=_0x8fd44c['dTFNa'](computeCascadeDepth,_0x311836,_0x36ef96),_0xe88bce={};_0xe88bce[_0x140408(0x8a)]=_0x489a09,_0xe88bce['instability']=_0x22e74d,_0xe88bce['complexity']=_0x5528f6,_0xe88bce[_0x140408(_0x5e37f4._0xa46873)]=_0x368912,_0x3b4dd0['set'](_0x311836,_0xe88bce),_0x461c59=Math[_0x140408(0xe7)](_0x461c59,_0x489a09['fanIn']),_0x434e4e=Math['max'](_0x434e4e,_0x489a09['transitiveFanIn']),_0x4e299f=Math['max'](_0x4e299f,_0x5528f6),_0x4e8536=Math[_0x140408(_0x5e37f4._0x270356)](_0x4e8536,_0x368912);}const _0x1bf5fe={'maxFanIn':_0x461c59,'maxTransitiveFanIn':_0x434e4e,'maxComplexity':_0x4e299f,'maxCascadeDepth':_0x4e8536,'fileMetrics':new Map()};for(const [_0x4ff053,_0x5609c2]of _0x3b4dd0){const _0x4f88da=_0x8fd44c[_0x140408(0xed)](normalize,_0x5609c2['coupling'][_0x140408(_0x5e37f4._0x492ce4)],0x0,_0x434e4e),_0x1c2293=_0x8fd44c['eDleI'](normalize,_0x5609c2[_0x140408(0xdc)],0x0,_0x4e299f),_0x1d7b84=_0x8fd44c['gzopf'](normalize,_0x5609c2[_0x140408(_0x5e37f4._0xa46873)],0x0,_0x4e8536);let _0x33f88b,_0x3a2169,_0x5d6924=0x0,_0x2aac55=![];if(_0x36ef96['pageRank']){const _0x2e26c7=(0x0,pagerank_1[_0x140408(_0x5e37f4._0x4be6c5)])(_0x4ff053,_0x36ef96['pageRank']);_0x2e26c7&&(_0x33f88b=_0x2e26c7['score'],_0x3a2169=_0x2e26c7['percentile'],_0x5d6924=_0x8fd44c['Jiwqt'](_0x2e26c7['percentile'],0x64),_0x2aac55=!![]);}let _0x2380ea;if(_0x2aac55)_0x2380ea=_0x8fd44c['OHSyN'](_0x8fd44c[_0x140408(_0x5e37f4._0x579882)](exports[_0x140408(_0x5e37f4._0x4d028e)][_0x140408(_0x5e37f4._0x1db927)],_0x4f88da)+exports[_0x140408(_0x5e37f4._0x3682bc)]['stability']*(0x1-_0x5609c2[_0x140408(0xd1)])+exports['RISK_WEIGHTS'][_0x140408(_0x5e37f4._0x293a7c)]*_0x1c2293+_0x8fd44c['GEnFd'](exports[_0x140408(0xd0)][_0x140408(_0x5e37f4._0x4ed688)],_0x1d7b84),_0x8fd44c['kZBdU'](exports[_0x140408(_0x5e37f4._0x4d028e)]['pageRank'],_0x5d6924));else{const _0x4d50a6=_0x8fd44c[_0x140408(_0x5e37f4._0x61536)](_0x8fd44c[_0x140408(0xd3)](exports[_0x140408(0xd0)][_0x140408(_0x5e37f4._0x1db927)],exports['RISK_WEIGHTS']['stability'])+exports[_0x140408(_0x5e37f4._0x3f2011)][_0x140408(0xdc)],exports['RISK_WEIGHTS'][_0x140408(_0x5e37f4._0x4ed688)]);_0x2380ea=_0x8fd44c[_0x140408(0xd3)](_0x8fd44c['OHSyN'](_0x8fd44c[_0x140408(0xd3)](_0x8fd44c['AARHw'](exports[_0x140408(_0x5e37f4._0xd06a4d)]['fanIn']/_0x4d50a6,_0x4f88da),_0x8fd44c[_0x140408(_0x5e37f4._0x48b448)](exports['RISK_WEIGHTS'][_0x140408(0xb5)]/_0x4d50a6,0x1-_0x5609c2[_0x140408(0xd1)])),_0x8fd44c[_0x140408(0xe3)](exports[_0x140408(0xd0)][_0x140408(0xdc)]/_0x4d50a6,_0x1c2293)),_0x8fd44c[_0x140408(_0x5e37f4._0x159643)](_0x8fd44c['Jiwqt'](exports['RISK_WEIGHTS']['cascadeDepth'],_0x4d50a6),_0x1d7b84));}const _0x1cd26a=Math[_0x140408(_0x5e37f4._0x2ed2eb)](0x1,Math[_0x140408(0xe7)](0x0,_0x2380ea));_0x1bf5fe[_0x140408(0xb3)]['set'](_0x4ff053,{'composite':Math[_0x140408(_0x5e37f4._0x3f6566)](_0x8fd44c[_0x140408(0xa9)](_0x1cd26a,0x64))/0x64,'fanIn':_0x5609c2[_0x140408(_0x5e37f4._0x31f511)]['fanIn'],'fanOut':_0x5609c2[_0x140408(0x8a)]['fanOut'],'transitiveFanIn':_0x5609c2[_0x140408(0x8a)][_0x140408(0xab)],'instability':_0x8fd44c['RrMwn'](Math[_0x140408(0xac)](_0x5609c2['instability']*0x64),0x64),'complexity':_0x5609c2[_0x140408(0xdc)],'normalizedComplexity':Math['round'](_0x1c2293*0x64)/0x64,'cascadeDepth':_0x5609c2[_0x140408(_0x5e37f4._0x4ed688)],'riskLevel':_0x8fd44c['jRSkx'](classifyCompositeRisk,_0x1cd26a),'pageRank':_0x33f88b,'pageRankPercentile':_0x3a2169});}return cachedProjectMetrics=_0x1bf5fe,cachedProjectRoot=_0x36ef96[_0x140408(0x7b)],console[_0x140408(0xe5)](_0x8fd44c['OHSyN'](_0x8fd44c['rpArK']('[syke:scoring]\x20Project\x20metrics\x20computed\x20for\x20'+_0x36ef96[_0x140408(_0x5e37f4._0xcad54f)][_0x140408(_0x5e37f4._0x4df0d4)]+'\x20files\x20',_0x140408(0x86)+_0x461c59+',\x20maxTransFanIn='+_0x434e4e+',\x20'),'maxComplexity='+_0x4e299f+',\x20maxCascadeDepth='+_0x4e8536+')')),_0x1bf5fe;}function getRiskScore(_0x4fa7fc,_0x548004,_0x1e51ed){const _0x52b01d={_0x52b0b5:0xb3},_0x363cfa=_0x15e495,_0x22c49d={'qkjna':function(_0x10583c,_0x34e77d){return _0x10583c===_0x34e77d;},'qGFZn':function(_0x304ccf,_0x3c1be3,_0x3c7cff,_0x8974fb,_0x4ddcd6){return _0x304ccf(_0x3c1be3,_0x3c7cff,_0x8974fb,_0x4ddcd6);},'KgvNY':function(_0x5c41e0,_0x42f15c,_0x40b0bc,_0x169c68){return _0x5c41e0(_0x42f15c,_0x40b0bc,_0x169c68);},'tFnyQ':function(_0x2838e7,_0x45c653){return _0x2838e7??_0x45c653;}};if(cachedProjectMetrics&&_0x22c49d['qkjna'](cachedProjectRoot,_0x548004['projectRoot'])){const _0x2174bc=cachedProjectMetrics[_0x363cfa(_0x52b01d._0x52b0b5)]['get'](_0x4fa7fc);if(_0x2174bc)return _0x2174bc;return _0x22c49d['qGFZn'](computeRiskScore,_0x4fa7fc,_0x548004,_0x1e51ed??null,cachedProjectMetrics);}return _0x22c49d['KgvNY'](computeRiskScore,_0x4fa7fc,_0x548004,_0x22c49d['tFnyQ'](_0x1e51ed,null));}function formatRiskScore(_0x4764f7){const _0x249f5e={_0x26bbc1:0xa3,_0x26f2a4:0xa0,_0x580fb9:0xd1,_0x509f5b:0x9a,_0x2533b2:0x77,_0x46e688:0xe1,_0x3fb957:0x7d,_0x23ca5e:0xb1,_0x3e604f:0x93,_0x4a01c6:0xe2,_0xb4aac5:0xe2,_0x582fe6:0x75,_0x35b4e8:0xbd,_0x43bc82:0xe0},_0x551c17=_0x15e495,_0x5d56e5={};_0x5d56e5[_0x551c17(_0x249f5e._0x26bbc1)]='very\x20stable\x20--\x20dangerous\x20to\x20change',_0x5d56e5['cRekA']=function(_0x50d625,_0x107c05){return _0x50d625<=_0x107c05;},_0x5d56e5[_0x551c17(0xb7)]='very\x20unstable\x20--\x20safe\x20to\x20change',_0x5d56e5['CdIDU']=function(_0x325134,_0x4047aa){return _0x325134!==_0x4047aa;};const _0x245857=_0x5d56e5,_0x1446e9=_0x4764f7[_0x551c17(0xd1)]<=0.2?_0x245857[_0x551c17(_0x249f5e._0x26bbc1)]:_0x4764f7['instability']<=0.4?_0x551c17(_0x249f5e._0x26f2a4):_0x4764f7[_0x551c17(_0x249f5e._0x580fb9)]<=0.6?_0x551c17(_0x249f5e._0x509f5b):_0x245857[_0x551c17(_0x249f5e._0x2533b2)](_0x4764f7[_0x551c17(0xd1)],0.8)?'unstable\x20--\x20relatively\x20safe':_0x245857['CTWWC'],_0x4c2387=[_0x551c17(0x81)+_0x4764f7['composite'][_0x551c17(_0x249f5e._0x46e688)](0x2)+'\x20('+_0x4764f7['riskLevel']+')','\x20\x20Fan-in:\x20'+_0x4764f7[_0x551c17(0xab)]+'\x20(direct:\x20'+_0x4764f7[_0x551c17(0x85)]+_0x551c17(0xc6)+_0x4764f7['fanOut']+')','\x20\x20Stability:\x20'+_0x4764f7[_0x551c17(_0x249f5e._0x580fb9)]['toFixed'](0x2)+'\x20('+_0x1446e9+')',_0x551c17(_0x249f5e._0x3fb957)+_0x4764f7[_0x551c17(0xdc)]+'\x20(normalized:\x20'+_0x4764f7[_0x551c17(_0x249f5e._0x23ca5e)]['toFixed'](0x2)+')',_0x551c17(0x83)+_0x4764f7[_0x551c17(0xba)]+_0x551c17(_0x249f5e._0x3e604f)];return _0x245857[_0x551c17(_0x249f5e._0x4a01c6)](_0x4764f7['pageRank'],undefined)&&_0x245857[_0x551c17(_0x249f5e._0xb4aac5)](_0x4764f7['pageRankPercentile'],undefined)&&_0x4c2387['push'](_0x551c17(_0x249f5e._0x582fe6)+_0x4764f7[_0x551c17(_0x249f5e._0x35b4e8)][_0x551c17(_0x249f5e._0x46e688)](0x6)+'\x20('+_0x4764f7['pageRankPercentile']+_0x551c17(0xf6)),_0x4c2387[_0x551c17(_0x249f5e._0x43bc82)]('\x0a');}