{"version":3,"file":"flag-impact-analyzer.mjs","sources":["../../../../src/lib/flags/analytics/flag-impact-analyzer.ts"],"sourcesContent":["/**\n * @fileoverview Feature flag impact analysis for measuring flag effects.\n *\n * Provides impact analysis capabilities:\n * - Metric correlation with flag states\n * - A/B test results analysis\n * - Statistical significance testing\n * - Impact scoring and reporting\n *\n * @module flags/analytics/flag-impact-analyzer\n *\n * @example\n * ```typescript\n * const analyzer = new FlagImpactAnalyzer();\n *\n * // Record metrics\n * analyzer.recordMetric('conversion_rate', 0.15, {\n *   flagKey: 'new-checkout',\n *   variantId: 'variant-b',\n *   userId: 'user-123',\n * });\n *\n * // Analyze impact\n * const impact = analyzer.analyzeImpact('new-checkout');\n * console.log(impact.metrics);\n * ```\n */\n\nimport type { JsonValue, UserId, VariantId, } from '../advanced/types';\n// import type { Mutable } from '../../utils/types';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Metric data point.\n */\nexport interface MetricDataPoint {\n  /** Metric name */\n  readonly name: string;\n  /** Metric value */\n  readonly value: number;\n  /** Associated flag key */\n  readonly flagKey?: string;\n  /** Associated variant */\n  readonly variantId?: VariantId;\n  /** User ID */\n  readonly userId?: UserId;\n  /** Session ID */\n  readonly sessionId?: string;\n  /** Timestamp */\n  readonly timestamp: Date;\n  /** Additional dimensions */\n  readonly dimensions?: Record<string, JsonValue>;\n}\n\n/**\n * Metric statistics.\n */\nexport interface MetricStats {\n  /** Metric name */\n  readonly name: string;\n  /** Number of data points */\n  readonly count: number;\n  /** Sum of values */\n  readonly sum: number;\n  /** Mean value */\n  readonly mean: number;\n  /** Median value */\n  readonly median: number;\n  /** Standard deviation */\n  readonly stdDev: number;\n  /** Minimum value */\n  readonly min: number;\n  /** Maximum value */\n  readonly max: number;\n  /** 25th percentile */\n  readonly p25: number;\n  /** 75th percentile */\n  readonly p75: number;\n  /** 95th percentile */\n  readonly p95: number;\n  /** 99th percentile */\n  readonly p99: number;\n}\n\n/**\n * Variant comparison results.\n */\nexport interface VariantComparison {\n  /** Control variant */\n  readonly control: VariantId;\n  /** Treatment variant */\n  readonly treatment: VariantId;\n  /** Metric name */\n  readonly metric: string;\n  /** Control stats */\n  readonly controlStats: MetricStats;\n  /** Treatment stats */\n  readonly treatmentStats: MetricStats;\n  /** Absolute difference */\n  readonly absoluteDiff: number;\n  /** Relative difference (lift) */\n  readonly relativeDiff: number;\n  /** P-value from statistical test */\n  readonly pValue: number;\n  /** Confidence interval */\n  readonly confidenceInterval: {\n    readonly lower: number;\n    readonly upper: number;\n    readonly level: number;\n  };\n  /** Is statistically significant */\n  readonly isSignificant: boolean;\n  /** Recommended action */\n  readonly recommendation: 'winner' | 'loser' | 'inconclusive' | 'more_data_needed';\n}\n\n/**\n * Flag impact analysis result.\n */\nexport interface FlagImpactAnalysis {\n  /** Flag key */\n  readonly flagKey: string;\n  /** Analysis timestamp */\n  readonly analyzedAt: Date;\n  /** Analysis period start */\n  readonly periodStart: Date;\n  /** Analysis period end */\n  readonly periodEnd: Date;\n  /** Total users in analysis */\n  readonly totalUsers: number;\n  /** Users per variant */\n  readonly variantUsers: Record<VariantId, number>;\n  /** Metrics analyzed */\n  readonly metrics: string[];\n  /** Metric comparisons */\n  readonly comparisons: VariantComparison[];\n  /** Overall impact score (-100 to 100) */\n  readonly impactScore: number;\n  /** Confidence in results */\n  readonly confidence: 'low' | 'medium' | 'high';\n  /** Summary */\n  readonly summary: string;\n}\n\n/**\n * Impact analyzer configuration.\n */\nexport interface ImpactAnalyzerConfig {\n  /** Enable analysis */\n  readonly enabled?: boolean;\n  /** Default control variant */\n  readonly defaultControl?: VariantId;\n  /** Significance threshold (p-value) */\n  readonly significanceThreshold?: number;\n  /** Minimum sample size for analysis */\n  readonly minSampleSize?: number;\n  /** Confidence level for intervals */\n  readonly confidenceLevel?: number;\n  /** Enable debug logging */\n  readonly debug?: boolean;\n  /** Maximum data points to store per metric */\n  readonly maxDataPoints?: number;\n}\n\n/**\n * Input for recording a metric.\n */\nexport interface RecordMetricInput {\n  /** Flag key */\n  readonly flagKey?: string;\n  /** Variant ID */\n  readonly variantId?: VariantId;\n  /** User ID */\n  readonly userId?: UserId;\n  /** Session ID */\n  readonly sessionId?: string;\n  /** Additional dimensions */\n  readonly dimensions?: Record<string, JsonValue>;\n}\n\n// ============================================================================\n// Statistical Utilities\n// ============================================================================\n\n/**\n * Calculate mean of values.\n */\nfunction mean(values: number[]): number {\n  if (values.length === 0) return 0;\n  return values.reduce((sum, v) => sum + v, 0) / values.length;\n}\n\n/**\n * Calculate standard deviation.\n */\nfunction standardDeviation(values: number[]): number {\n  if (values.length < 2) return 0;\n  const avg = mean(values);\n  const squareDiffs = values.map((v) => Math.pow(v - avg, 2));\n  return Math.sqrt(mean(squareDiffs));\n}\n\n/**\n * Calculate percentile.\n */\nfunction percentile(values: number[], p: number): number {\n  if (values.length === 0) return 0;\n  const sorted = [...values].sort((a, b) => a - b);\n  const index = (p / 100) * (sorted.length - 1);\n  const lower = Math.floor(index);\n  const upper = Math.ceil(index);\n  if (lower === upper) return sorted[lower] ?? 0;\n  return (sorted[lower] ?? 0) * (upper - index) + (sorted[upper] ?? 0) * (index - lower);\n}\n\n/**\n * Two-sample t-test for means comparison.\n */\nfunction tTest(\n  sample1: number[],\n  sample2: number[]\n): { tStatistic: number; pValue: number } {\n  const n1 = sample1.length;\n  const n2 = sample2.length;\n\n  if (n1 < 2 || n2 < 2) {\n    return { tStatistic: 0, pValue: 1 };\n  }\n\n  const mean1 = mean(sample1);\n  const mean2 = mean(sample2);\n  const var1 = Math.pow(standardDeviation(sample1), 2);\n  const var2 = Math.pow(standardDeviation(sample2), 2);\n\n  // Pooled standard error\n  const se = Math.sqrt(var1 / n1 + var2 / n2);\n\n  if (se === 0) {\n    return { tStatistic: 0, pValue: 1 };\n  }\n\n  const tStatistic = (mean1 - mean2) / se;\n\n  // Degrees of freedom (Welch-Satterthwaite)\n  const df =\n    Math.pow(var1 / n1 + var2 / n2, 2) /\n    (Math.pow(var1 / n1, 2) / (n1 - 1) + Math.pow(var2 / n2, 2) / (n2 - 1));\n\n  // Approximate p-value using t-distribution\n  // Using a simplified approximation for two-tailed test\n  const pValue = approximateTDistribution(Math.abs(tStatistic), df);\n\n  return { tStatistic, pValue };\n}\n\n/**\n * Approximate p-value from t-distribution.\n * Using a simplified approximation for the cumulative distribution.\n */\nfunction approximateTDistribution(t: number, df: number): number {\n  // Simple approximation for large df\n  if (df > 100) {\n    // Use normal approximation\n\n    // Approximate using error function\n\n    return 2 * (1 - normalCDF(Math.abs(t)));\n  }\n\n  // For smaller df, use a simple approximation\n  const a = df / (df + t * t);\n  const b = Math.pow(a, df / 2);\n  const p = 1 - b;\n  return Math.min(1, Math.max(0, p));\n}\n\n/**\n * Standard normal CDF approximation.\n */\nfunction normalCDF(z: number): number {\n  const a1 = 0.254829592;\n  const a2 = -0.284496736;\n  const a3 = 1.421413741;\n  const a4 = -1.453152027;\n  const a5 = 1.061405429;\n  const p = 0.3275911;\n\n  const sign = z < 0 ? -1 : 1;\n  z = Math.abs(z) / Math.sqrt(2);\n\n  const t = 1.0 / (1.0 + p * z);\n  const y =\n    1.0 -\n    ((((a5 * t + a4) * t + a3) * t + a2) * t + a1) * t * Math.exp(-z * z);\n\n  return 0.5 * (1.0 + sign * y);\n}\n\n/**\n * Calculate confidence interval for difference of means.\n */\nfunction confidenceInterval(\n  sample1: number[],\n  sample2: number[],\n  level: number\n): { lower: number; upper: number } {\n  const n1 = sample1.length;\n  const n2 = sample2.length;\n\n  if (n1 < 2 || n2 < 2) {\n    return { lower: 0, upper: 0 };\n  }\n\n  const mean1 = mean(sample1);\n  const mean2 = mean(sample2);\n  const var1 = Math.pow(standardDeviation(sample1), 2);\n  const var2 = Math.pow(standardDeviation(sample2), 2);\n\n  const se = Math.sqrt(var1 / n1 + var2 / n2);\n  const diff = mean1 - mean2;\n\n  // Z-score for confidence level (approximate)\n  const zScores: Record<number, number> = {\n    0.9: 1.645,\n    0.95: 1.96,\n    0.99: 2.576,\n  };\n  const z = zScores[level] ?? 1.96;\n\n  return {\n    lower: diff - z * se,\n    upper: diff + z * se,\n  };\n}\n\n// ============================================================================\n// Impact Analyzer\n// ============================================================================\n\n/**\n * Analyzes the impact of feature flags on metrics.\n */\nexport class FlagImpactAnalyzer {\n  private config: Required<ImpactAnalyzerConfig>;\n  private metrics = new Map<string, MetricDataPoint[]>();\n  private flagMetrics = new Map<string, Map<string, MetricDataPoint[]>>();\n\n  constructor(config: ImpactAnalyzerConfig = {}) {\n    this.config = {\n      enabled: config.enabled ?? true,\n      defaultControl: config.defaultControl ?? 'control',\n      significanceThreshold: config.significanceThreshold ?? 0.05,\n      minSampleSize: config.minSampleSize ?? 30,\n      confidenceLevel: config.confidenceLevel ?? 0.95,\n      debug: config.debug ?? false,\n      maxDataPoints: config.maxDataPoints ?? 10000,\n    };\n  }\n\n  // ==========================================================================\n  // Metric Recording\n  // ==========================================================================\n\n  /**\n   * Record a metric value.\n   */\n  recordMetric(name: string, value: number, input: RecordMetricInput = {}): void {\n    if (!this.config.enabled) {\n      return;\n    }\n\n    const dataPoint: MetricDataPoint = {\n      name,\n      value,\n      flagKey: input.flagKey,\n      variantId: input.variantId,\n      userId: input.userId,\n      sessionId: input.sessionId,\n      timestamp: new Date(),\n      dimensions: input.dimensions,\n    };\n\n    // Store in general metrics\n    if (!this.metrics.has(name)) {\n      this.metrics.set(name, []);\n    }\n    const metricList = this.metrics.get(name);\n    if (metricList) {\n      metricList.push(dataPoint);\n      this.enforceMaxDataPoints(metricList);\n    }\n\n    // Store in flag-specific metrics\n    if (input.flagKey !== undefined && input.flagKey !== '' && input.variantId !== undefined && input.variantId !== '') {\n      const {flagKey} = input;\n      if (!this.flagMetrics.has(flagKey)) {\n        this.flagMetrics.set(flagKey, new Map());\n      }\n      const flagMap = this.flagMetrics.get(flagKey);\n\n      if (flagMap) {\n        const key = `${name}:${input.variantId}`;\n        if (!flagMap.has(key)) {\n          flagMap.set(key, []);\n        }\n        const flagMetricList = flagMap.get(key);\n        if (flagMetricList) {\n          flagMetricList.push(dataPoint);\n          this.enforceMaxDataPoints(flagMetricList);\n        }\n      }\n    }\n\n    this.log(`Recorded metric: ${name} = ${value}`);\n  }\n\n  /**\n   * Record multiple metrics at once.\n   */\n  recordMetrics(\n    metrics: Array<{ name: string; value: number }>,\n    input: RecordMetricInput = {}\n  ): void {\n    for (const { name, value } of metrics) {\n      this.recordMetric(name, value, input);\n    }\n  }\n\n  /**\n   * Calculate statistics for a metric.\n   */\n  getMetricStats(name: string, filter?: (dp: MetricDataPoint) => boolean): MetricStats | null {\n    const dataPoints = this.metrics.get(name);\n    if (!dataPoints || dataPoints.length === 0) {\n      return null;\n    }\n\n    const filtered = filter ? dataPoints.filter(filter) : dataPoints;\n    if (filtered.length === 0) {\n      return null;\n    }\n\n    const values = filtered.map((dp) => dp.value);\n    return this.calculateStats(name, values);\n  }\n\n  // ==========================================================================\n  // Metric Statistics\n  // ==========================================================================\n\n  /**\n   * Calculate statistics for a metric by variant.\n   */\n  getVariantStats(\n    flagKey: string,\n    metric: string,\n    variantId: VariantId\n  ): MetricStats | null {\n    const flagMap = this.flagMetrics.get(flagKey);\n    if (!flagMap) {\n      return null;\n    }\n\n    const key = `${metric}:${variantId}`;\n    const dataPoints = flagMap.get(key);\n    if (!dataPoints || dataPoints.length === 0) {\n      return null;\n    }\n\n    const values = dataPoints.map((dp) => dp.value);\n    return this.calculateStats(metric, values);\n  }\n\n  /**\n   * Compare two variants for a metric.\n   */\n  compareVariants(\n    flagKey: string,\n    metric: string,\n    controlVariant: VariantId,\n    treatmentVariant: VariantId\n  ): VariantComparison | null {\n    const controlStats = this.getVariantStats(flagKey, metric, controlVariant);\n    const treatmentStats = this.getVariantStats(flagKey, metric, treatmentVariant);\n\n    if (!controlStats || !treatmentStats) {\n      return null;\n    }\n\n    // Get raw values for statistical tests\n    const controlValues = this.getVariantValues(flagKey, metric, controlVariant);\n    const treatmentValues = this.getVariantValues(flagKey, metric, treatmentVariant);\n\n    // Perform t-test\n    const { pValue } = tTest(treatmentValues, controlValues);\n\n    // Calculate confidence interval\n    const ci = confidenceInterval(\n      treatmentValues,\n      controlValues,\n      this.config.confidenceLevel\n    );\n\n    const absoluteDiff = treatmentStats.mean - controlStats.mean;\n    const relativeDiff =\n      controlStats.mean !== 0\n        ? ((treatmentStats.mean - controlStats.mean) / controlStats.mean) * 100\n        : 0;\n\n    const isSignificant = pValue < this.config.significanceThreshold;\n\n    // Determine recommendation\n    let recommendation: VariantComparison['recommendation'] = 'inconclusive';\n    if (controlStats.count < this.config.minSampleSize ||\n        treatmentStats.count < this.config.minSampleSize) {\n      recommendation = 'more_data_needed';\n    } else if (isSignificant) {\n      recommendation = absoluteDiff > 0 ? 'winner' : 'loser';\n    }\n\n    return {\n      control: controlVariant,\n      treatment: treatmentVariant,\n      metric,\n      controlStats,\n      treatmentStats,\n      absoluteDiff,\n      relativeDiff,\n      pValue,\n      confidenceInterval: {\n        lower: ci.lower,\n        upper: ci.upper,\n        level: this.config.confidenceLevel,\n      },\n      isSignificant,\n      recommendation,\n    };\n  }\n\n  /**\n   * Analyze impact of a flag across all metrics.\n   */\n  analyzeImpact(\n    flagKey: string,\n    controlVariant?: VariantId\n  ): FlagImpactAnalysis | null {\n    const flagMap = this.flagMetrics.get(flagKey);\n    if (!flagMap) {\n      return null;\n    }\n\n    const control = controlVariant ?? this.config.defaultControl;\n    const now = new Date();\n\n    // Find all metrics and variants\n    const metricsSet = new Set<string>();\n    const variantsSet = new Set<VariantId>();\n    let periodStart = now;\n    let periodEnd = new Date(0);\n    const userSet = new Set<string>();\n\n    for (const [key, dataPoints] of flagMap.entries()) {\n      const [metric, variant] = key.split(':');\n      if (metric !== undefined && metric !== '') metricsSet.add(metric);\n      if (variant !== undefined && variant !== '') variantsSet.add(variant);\n\n      for (const dp of dataPoints) {\n        if (dp.timestamp < periodStart) {\n          periodStart = dp.timestamp;\n        }\n        if (dp.timestamp > periodEnd) {\n          periodEnd = dp.timestamp;\n        }\n        if (dp.userId !== undefined && dp.userId !== '') {\n          userSet.add(dp.userId);\n        }\n      }\n    }\n\n    const metrics = Array.from(metricsSet);\n    const variants = Array.from(variantsSet);\n    const treatmentVariants = variants.filter((v) => v !== control);\n\n    // Run comparisons\n    const comparisons: VariantComparison[] = [];\n    for (const metric of metrics) {\n      for (const treatment of treatmentVariants) {\n        const comparison = this.compareVariants(flagKey, metric, control, treatment);\n        if (comparison) {\n          comparisons.push(comparison);\n        }\n      }\n    }\n\n    // Calculate variant users\n    const variantUsers: Record<VariantId, number> = {};\n    for (const variant of variants) {\n      const userIds = new Set<string>();\n      for (const [key, dataPoints] of flagMap.entries()) {\n        if (key.endsWith(`:${variant}`)) {\n          for (const dp of dataPoints) {\n            if (dp.userId !== undefined && dp.userId !== '') {\n              userIds.add(dp.userId);\n            }\n          }\n        }\n      }\n      variantUsers[variant] = userIds.size;\n    }\n\n    // Calculate overall impact score\n    const impactScore = this.calculateImpactScore(comparisons);\n    const confidence = this.determineConfidence(comparisons, variantUsers);\n\n    // Generate summary\n    const summary = this.generateSummary(comparisons, impactScore);\n\n    return {\n      flagKey,\n      analyzedAt: now,\n      periodStart,\n      periodEnd,\n      totalUsers: userSet.size,\n      variantUsers,\n      metrics,\n      comparisons,\n      impactScore,\n      confidence,\n      summary,\n    };\n  }\n\n  // ==========================================================================\n  // Impact Analysis\n  // ==========================================================================\n\n  /**\n   * Get all recorded metrics.\n   */\n  getMetricNames(): string[] {\n    return Array.from(this.metrics.keys());\n  }\n\n  /**\n   * Get all flags with metrics.\n   */\n  getFlagKeys(): string[] {\n    return Array.from(this.flagMetrics.keys());\n  }\n\n  /**\n   * Get metrics for a flag.\n   */\n  getFlagMetrics(flagKey: string): string[] {\n    const flagMap = this.flagMetrics.get(flagKey);\n    if (!flagMap) {\n      return [];\n    }\n\n    const metrics = new Set<string>();\n    for (const key of flagMap.keys()) {\n      const [metric] = key.split(':');\n      if (metric !== undefined && metric !== '') metrics.add(metric);\n    }\n\n    return Array.from(metrics);\n  }\n\n  /**\n   * Get variants for a flag.\n   */\n  getFlagVariants(flagKey: string): VariantId[] {\n    const flagMap = this.flagMetrics.get(flagKey);\n    if (!flagMap) {\n      return [];\n    }\n\n    const variants = new Set<VariantId>();\n    for (const key of flagMap.keys()) {\n      const parts = key.split(':');\n      if (parts.length > 1 && parts[1] !== undefined && parts[1] !== '') {\n        variants.add(parts[1]);\n      }\n    }\n\n    return Array.from(variants);\n  }\n\n  /**\n   * Clear all data.\n   */\n  clear(): void {\n    this.metrics.clear();\n    this.flagMetrics.clear();\n    this.log('All data cleared');\n  }\n\n  /**\n   * Clear data for a specific flag.\n   */\n  clearFlag(flagKey: string): void {\n    this.flagMetrics.delete(flagKey);\n    this.log(`Data cleared for flag: ${flagKey}`);\n  }\n\n  // ==========================================================================\n  // Queries\n  // ==========================================================================\n\n  /**\n   * Enable or disable analysis.\n   */\n  setEnabled(enabled: boolean): void {\n    (this.config as { enabled: boolean }).enabled = enabled;\n  }\n\n  /**\n   * Export all data as JSON.\n   */\n  exportData(): {\n    metrics: Record<string, MetricDataPoint[]>;\n    flagMetrics: Record<string, Record<string, MetricDataPoint[]>>;\n  } {\n    const metrics: Record<string, MetricDataPoint[]> = {};\n    for (const [name, dataPoints] of this.metrics.entries()) {\n      metrics[name] = dataPoints;\n    }\n\n    const flagMetrics: Record<string, Record<string, MetricDataPoint[]>> = {};\n    for (const [flagKey, flagMap] of this.flagMetrics.entries()) {\n      const flagEntry: Record<string, MetricDataPoint[]> = {};\n      for (const [key, dataPoints] of flagMap.entries()) {\n        flagEntry[key] = dataPoints;\n      }\n      flagMetrics[flagKey] = flagEntry;\n    }\n\n    return { metrics, flagMetrics };\n  }\n\n  private enforceMaxDataPoints(list: MetricDataPoint[]): void {\n    while (list.length > this.config.maxDataPoints) {\n      list.shift();\n    }\n  }\n\n  private calculateStats(name: string, values: number[]): MetricStats {\n    const sorted = [...values].sort((a, b) => a - b);\n\n    return {\n      name,\n      count: values.length,\n      sum: values.reduce((sum, v) => sum + v, 0),\n      mean: mean(values),\n      median: percentile(values, 50),\n      stdDev: standardDeviation(values),\n      min: sorted[0] ?? 0,\n      max: sorted[sorted.length - 1] ?? 0,\n      p25: percentile(values, 25),\n      p75: percentile(values, 75),\n      p95: percentile(values, 95),\n      p99: percentile(values, 99),\n    };\n  }\n\n  // ==========================================================================\n  // Lifecycle\n  // ==========================================================================\n\n  private getVariantValues(\n    flagKey: string,\n    metric: string,\n    variantId: VariantId\n  ): number[] {\n    const flagMap = this.flagMetrics.get(flagKey);\n    if (!flagMap) {\n      return [];\n    }\n\n    const key = `${metric}:${variantId}`;\n    const dataPoints = flagMap.get(key);\n    if (!dataPoints) {\n      return [];\n    }\n\n    return dataPoints.map((dp) => dp.value);\n  }\n\n  private calculateImpactScore(comparisons: VariantComparison[]): number {\n    if (comparisons.length === 0) {\n      return 0;\n    }\n\n    let totalScore = 0;\n    let significantCount = 0;\n\n    for (const comparison of comparisons) {\n      if (comparison.isSignificant) {\n        significantCount++;\n        // Score based on relative difference (capped at -100 to 100)\n        const score = Math.max(-100, Math.min(100, comparison.relativeDiff));\n        totalScore += score;\n      }\n    }\n\n    if (significantCount === 0) {\n      return 0;\n    }\n\n    return Math.round(totalScore / significantCount);\n  }\n\n  private determineConfidence(\n    comparisons: VariantComparison[],\n    variantUsers: Record<VariantId, number>\n  ): 'low' | 'medium' | 'high' {\n    // Check sample sizes\n    const totalUsers = Object.values(variantUsers).reduce((sum, n) => sum + n, 0);\n    if (totalUsers < this.config.minSampleSize * 2) {\n      return 'low';\n    }\n\n    // Check significance\n    const significantCount = comparisons.filter((c) => c.isSignificant).length;\n    const significanceRatio = significantCount / comparisons.length;\n\n    if (significanceRatio >= 0.7 && totalUsers >= this.config.minSampleSize * 10) {\n      return 'high';\n    }\n\n    if (significanceRatio >= 0.3) {\n      return 'medium';\n    }\n\n    return 'low';\n  }\n\n  // ==========================================================================\n  // Export\n  // ==========================================================================\n\n  private generateSummary(\n    comparisons: VariantComparison[],\n    impactScore: number\n  ): string {\n    if (comparisons.length === 0) {\n      return 'No data available for analysis.';\n    }\n\n    const winners = comparisons.filter((c) => c.recommendation === 'winner');\n    const losers = comparisons.filter((c) => c.recommendation === 'loser');\n    const needsData = comparisons.filter(\n      (c) => c.recommendation === 'more_data_needed'\n    );\n\n    const parts: string[] = [];\n\n    if (winners.length > 0) {\n      parts.push(\n        `${winners.length} metric(s) show significant positive impact`\n      );\n    }\n\n    if (losers.length > 0) {\n      parts.push(`${losers.length} metric(s) show significant negative impact`);\n    }\n\n    if (needsData.length > 0) {\n      parts.push(`${needsData.length} metric(s) need more data`);\n    }\n\n    if (parts.length === 0) {\n      parts.push('No significant impact detected');\n    }\n\n    let impactDirection: string;\n    if (impactScore > 0) {\n      impactDirection = 'positive';\n    } else if (impactScore < 0) {\n      impactDirection = 'negative';\n    } else {\n      impactDirection = 'neutral';\n    }\n    parts.push(`Overall impact: ${impactDirection} (score: ${impactScore})`);\n\n    return `${parts.join('. ')  }.`;\n  }\n\n  // ==========================================================================\n  // Utilities\n  // ==========================================================================\n\n  private log(message: string, ...args: unknown[]): void {\n    if (this.config.debug) {\n      // eslint-disable-next-line no-console\n      console.log(`[FlagImpactAnalyzer] ${message}`, ...args);\n    }\n  }\n}\n\n// ============================================================================\n// Singleton Instance\n// ============================================================================\n\nlet instance: FlagImpactAnalyzer | null = null;\n\n/**\n * Get the singleton impact analyzer instance.\n */\nexport function getImpactAnalyzer(): FlagImpactAnalyzer {\n  instance ??= new FlagImpactAnalyzer();\n  return instance;\n}\n\n/**\n * Initialize the singleton with configuration.\n */\nexport function initImpactAnalyzer(config: ImpactAnalyzerConfig): FlagImpactAnalyzer {\n  instance = new FlagImpactAnalyzer(config);\n  return instance;\n}\n\n/**\n * Reset the singleton instance.\n */\nexport function resetImpactAnalyzer(): void {\n  instance = null;\n}\n"],"names":["mean","values","sum","v","standardDeviation","avg","squareDiffs","percentile","p","sorted","a","b","index","lower","upper","tTest","sample1","sample2","n1","n2","mean1","mean2","var1","var2","se","tStatistic","df","pValue","approximateTDistribution","t","normalCDF","z","a1","a2","a3","a4","a5","sign","y","confidenceInterval","level","diff","FlagImpactAnalyzer","config","name","value","input","dataPoint","metricList","flagKey","flagMap","key","flagMetricList","metrics","filter","dataPoints","filtered","dp","metric","variantId","controlVariant","treatmentVariant","controlStats","treatmentStats","controlValues","treatmentValues","ci","absoluteDiff","relativeDiff","isSignificant","recommendation","control","now","metricsSet","variantsSet","periodStart","periodEnd","userSet","variant","variants","treatmentVariants","comparisons","treatment","comparison","variantUsers","userIds","impactScore","confidence","summary","parts","enabled","flagMetrics","flagEntry","list","totalScore","significantCount","score","totalUsers","n","significanceRatio","c","winners","losers","needsData","impactDirection","message","args","instance","getImpactAnalyzer","initImpactAnalyzer","resetImpactAnalyzer"],"mappings":"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"}