@yipe/dice 0.2.21 → 0.2.22

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 +1 @@
1
- {"version":3,"sources":["../src/common/lru-cache.ts","../src/common/types.ts","../src/pmf/query.ts","../src/pmf/pmf.ts","../src/parser/dice.ts","../src/parser/parser.ts","../src/pmf/mixture.ts"],"names":["cumulativeSum","rec","result"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Simple LRU cache implementation\n */\n\nexport class LRUCache<K, V> {\n private cache = new Map<K, V>();\n\n constructor(private readonly maxSize = 1000) {}\n\n get(key: K): V | undefined {\n const value = this.cache.get(key);\n if (value === undefined) return undefined;\n\n this.cache.delete(key);\n this.cache.set(key, value);\n return value;\n }\n\n delete(key: K): void {\n this.cache.delete(key);\n }\n\n set(key: K, value: V): this {\n if (this.cache.size >= this.maxSize && !this.cache.has(key)) {\n const oldestKey = this.cache.keys().next().value;\n this.cache.delete(oldestKey as K);\n }\n this.cache.delete(key);\n this.cache.set(key, value);\n return this;\n }\n\n clear(): void {\n this.cache.clear();\n }\n\n get size(): number {\n return this.cache.size;\n }\n\n has(key: K): boolean {\n return this.cache.has(key);\n }\n\n keys(): IterableIterator<K> {\n return this.cache.keys();\n }\n\n values(): IterableIterator<V> {\n return this.cache.values();\n }\n}\n","/** Mapping from outcome label to probability mass or damage attribution. */\nexport type OutcomeLabelMap = Partial<Record<string, number>>;\n\n/** Computational epsilon for pruning negligible probabilities. */\nexport const EPS = 1e-12;\n\n/** A probability bin for a specific damage value. */\nexport interface Bin {\n /** Total probability mass at this damage value. */\n p: number;\n /** Per-outcome probability mass contributions at this damage. */\n count: OutcomeLabelMap;\n /** Optional per-outcome damage attribution at this damage. */\n attr?: OutcomeLabelMap;\n}\n\nexport interface CritConfig {\n critThreshold: number;\n}\n\n/** Simple mapping from damage value to probability. */\nexport type DamageDistribution = Record<number, number>;\n/** Canonical outcome labels supported by the query helpers. */\nexport type OutcomeType =\n | \"crit\"\n | \"hit\"\n | \"missNone\"\n | \"missDamage\"\n | \"saveHalf\"\n | \"saveFail\"\n | \"pc\";\n\nexport type Rounding = \"none\" | \"floor\" | \"round\" | \"ceil\";\n\nexport const onAnyHit: OutcomeType[] = [\"hit\", \"crit\"];\nexport const onCritOnly: OutcomeType[] = [\"crit\"];\nexport const onHitOnly: OutcomeType[] = [\"hit\"];\nexport const onMissOnly: OutcomeType[] = [\"missNone\", \"missDamage\"];\nexport const onMissDamageOnly: OutcomeType[] = [\"missDamage\"];\nexport const onSaveHalfOnly: OutcomeType[] = [\"saveHalf\"];\nexport const onSaveFailOnly: OutcomeType[] = [\"saveFail\"];\nexport const onPotentCantripOnly: OutcomeType[] = [\"pc\"];\n","import type { OutcomeType } from \"../common/types\";\nimport { EPS } from \"../common/types\";\nimport { PMF } from \"./pmf\";\n\n/**\n * Query interface for analyzing dice roll probability distributions.\n *\n * Combines multiple attack PMFs and provides statistical analysis methods for:\n * - Basic statistics (mean, variance, min/max, percentiles)\n * - Probability queries (hit chances, success rates, exact counts)\n * - Damage analysis (ranges by outcome type, expected values)\n * - Data export (charts, tables, visualizations)\n *\n */\n\nexport class DiceQuery {\n public readonly singles: PMF[];\n public readonly combined: PMF;\n private _combinedWithAttr?: PMF;\n\n constructor(singles: PMF | PMF[], combined?: PMF, eps = EPS) {\n this.singles = Array.isArray(singles) ? singles : [singles];\n if (this.singles.some((s) => s === undefined)) {\n throw new Error(\"DiceQuery contains undefined singles\");\n }\n const c = combined ?? PMF.convolveMany(this.singles);\n this.combined = Math.abs(c.mass() - 1) <= eps ? c : c.normalize();\n }\n\n private static readonly DEFAULT_OUTCOMES: readonly OutcomeType[] = [\n \"hit\",\n \"crit\",\n \"missNone\",\n ] as const;\n\n /**\n * Returns a new PMF with damage attribution metadata populated.\n *\n * This method computes attribution on-demand for builder-generated PMFs,\n * enabling them to work with damage attribution charts. The `attr` field\n * tracks how much damage each outcome type contributes at each damage value.\n *\n * For each bin at damage D: sum(attr.values()) ≈ D × P(damage = D)\n *\n * Performance: Cached after first call. Adds minimal overhead vs `combined`.\n *\n * @returns PMF with attr field populated for damage attribution charts\n *\n * @example\n * const attack = d20.plus(5).ac(15).onHit(d(2,6).plus(3)).onCrit(d(2,6))\n * const query = attack.toQuery()\n * const pmf = query.combinedWithAttribution()\n * // Now pmf can be used with toDamageAttributionChartSeries()\n */\n combinedWithAttribution(): PMF {\n if (this._combinedWithAttr) {\n return this._combinedWithAttr;\n }\n\n // Add attribution to each single PMF, then convolve\n // The existing convolution logic will preserve attribution correctly\n const singlesWithAttr = this.singles.map((pmf) => pmf.withAttribution());\n const combined = PMF.convolveMany(singlesWithAttr, this.combined.epsilon);\n\n // Normalize if needed\n const normalized =\n Math.abs(combined.mass() - 1) <= this.combined.epsilon\n ? combined\n : combined.normalize();\n\n this._combinedWithAttr = normalized;\n return normalized;\n }\n\n /**\n * Returns the expected damage across all possible outcomes.\n *\n * Example: `query.mean()` → 12.5\n * Use case: \"What's my average damage per round?\"\n */\n mean(): number {\n let totalSum = 0;\n for (const [damageValue, probabilityBin] of this.combined) {\n totalSum += damageValue * probabilityBin.p;\n }\n return totalSum;\n }\n\n /**\n * Returns the variance of the damage distribution.\n *\n * Example: `query.variance()` → 45.2\n * Use case: \"How much does my damage vary from the average?\"\n * High variance means higher risk/reward. Lower variance means more consistent damage.\n */\n variance(): number {\n const meanValue = this.mean();\n let varianceSum = 0;\n for (const [damageValue, probabilityBin] of this.combined) {\n const deviationFromMean = damageValue - meanValue;\n varianceSum += deviationFromMean * deviationFromMean * probabilityBin.p;\n }\n return varianceSum;\n }\n\n /**\n * Returns the standard deviation of the damage distribution.\n *\n * Example: `query.stdev()` → 6.7\n * Use case: \"What's the typical spread around my average damage?\"\n * Used to determine how consistent the damage is.\n */\n stddev(): number {\n return Math.sqrt(this.variance());\n }\n\n /**\n * Returns the Cumulative Distribution Function.\n */\n cdf(x: number): number {\n return this.probTotalAtMost(x);\n }\n\n /**\n * Returns the probability of dealing X damage or less.\n * In statistics, this is called the cumulative distribution function (CDF).\n * Example: `query.cdf(20)` → 0.75\n * Use case: \"What's the chance I deal 20 damage or less?\"\n */\n probTotalAtMost(x: number): number {\n let cumulativeProbability = 0;\n for (const [damageValue, probabilityBin] of this.combined) {\n if (damageValue <= x) {\n cumulativeProbability += probabilityBin.p;\n }\n }\n return cumulativeProbability;\n }\n\n /**\n * Returns the Complementary Cumulative Distribution Function.\n */\n ccdf(x: number): number {\n return this.probTotalAtLeast(x);\n }\n\n /**\n * Returns the probability of dealing at least X damage.\n *\n * Example: `query.probTotalAtLeast(25)` → 0.35\n * Use case: \"What's the chance I deal at least 25 damage to finish the enemy?\"\n */\n probTotalAtLeast(threshold: number): number {\n let probabilitySum = 0;\n for (const [damageValue, probabilityBin] of this.combined) {\n if (damageValue >= threshold) {\n probabilitySum += probabilityBin.p;\n }\n }\n return probabilitySum;\n }\n\n /**\n * Returns damage values at specific percentiles.\n *\n * Example: `query.percentiles([0.25, 0.5, 0.75])` → [8, 12, 18]\n * Use case: \"What are my 25th, 50th, and 75th percentile damage values?\"\n */\n percentiles(percentileValues: number[]): number[] {\n const sortedDamageValues = this.combined.support();\n if (sortedDamageValues.length === 0) return percentileValues.map(() => 0);\n\n const cumulativeProbabilities: number[] = [];\n let runningProbabilitySum = 0;\n for (const damageValue of sortedDamageValues) {\n runningProbabilitySum += this.combined.map.get(damageValue)!.p;\n cumulativeProbabilities.push(runningProbabilitySum);\n }\n\n return percentileValues.map((targetPercentile) => {\n // Binary search for efficiency\n let leftBound = 0;\n let rightBound = cumulativeProbabilities.length - 1;\n\n while (leftBound <= rightBound) {\n const middleIndex = Math.floor((leftBound + rightBound) / 2);\n if (cumulativeProbabilities[middleIndex] >= targetPercentile) {\n rightBound = middleIndex - 1;\n } else {\n leftBound = middleIndex + 1;\n }\n }\n\n return leftBound < sortedDamageValues.length\n ? sortedDamageValues[leftBound]\n : sortedDamageValues[sortedDamageValues.length - 1];\n });\n }\n\n /**\n * Returns the minimum possible damage.\n *\n * Example: `query.min()` → 0\n * Use case: \"What's the worst-case damage if everything misses?\"\n */\n min(): number {\n return this.combined.min();\n }\n\n /**\n * Returns the maximum possible damage.\n *\n * Example: `query.max()` → 56\n * Use case: \"What's the best-case damage if everything crits and rolls max?\"\n */\n max(): number {\n return this.combined.max();\n }\n\n private singleProb(diceIndex: number, label: OutcomeType): number {\n let probabilitySum = 0;\n for (const [, probabilityBin] of this.singles[diceIndex]) {\n probabilitySum += probabilityBin.count[label] || 0;\n }\n return probabilitySum;\n }\n\n probAtLeastK(labels: OutcomeType | OutcomeType[], k: number): number {\n const L = Array.isArray(labels) ? [...new Set(labels)] : [labels];\n const n = this.singles.length;\n\n if (k <= 0) return 1;\n if (k > n) return 0;\n\n let tail = 0;\n for (let i = k; i <= n; i++) {\n tail += this.probExactlyK(L, i);\n }\n\n if (tail < 0) return 0;\n if (tail > 1) return 1;\n return tail;\n }\n\n /**\n * Returns the probability that at least one attack has the specified outcome(s).\n * - This is the complement of probAtMostK(labels, 0)\n *\n * Examples:\n * - `query.probAtLeastOne('hit')` → 0.88 (88% chance at least one attack hits)\n * - `query.probAtLeastOne(['hit', 'crit'])` → 0.96 (96% chance at least one succeeds)\n *\n * Use cases:\n * - \"What's the chance at least one of my attacks connects?\"\n *\n * Note:\n *\n * - You have to pass in an array of labels to avoid double-counting if you are\n * using multiple labels. You cannot just add them.\n */\n probAtLeastOne(labels: OutcomeType | OutcomeType[]): number {\n // Handle single label case (backward compatibility)\n if (typeof labels === \"string\") {\n labels = [labels];\n }\n\n let productOfNonOccurrence = 1;\n for (let diceIndex = 0; diceIndex < this.singles.length; diceIndex++) {\n // Calculate total probability of any of the specified labels occurring\n let combinedProbability = 0;\n for (const label of labels) {\n combinedProbability += this.singleProb(diceIndex, label);\n }\n productOfNonOccurrence *= 1 - combinedProbability;\n }\n return 1 - productOfNonOccurrence;\n }\n\n /**\n * Computes binomial probabilities for exactly 0, 1, 2, ..., maxK occurrences of a label.\n *\n * Uses dynamic programming to efficiently calculate the probability distribution\n * of how many attacks will have the specified outcome, accounting for different\n * success probabilities across individual attacks.\n *\n * Example: For 3 attacks with 50% hit chance each, returns:\n * [0.125, 0.375, 0.375, 0.125] = [P(0 hits), P(1 hit), P(2 hits), P(3 hits)]\n *\n * @param label - The outcome type to count\n * @param maxK - Maximum number of occurrences to calculate (usually number of attacks)\n * @returns Array where index K contains P(exactly K attacks have the label)\n */\n private computeBinomialProbabilities(\n label: OutcomeType,\n maxK: number\n ): number[] {\n const individualProbabilities = this.singles.map((_, diceIndex) =>\n this.singleProb(diceIndex, label)\n );\n const binomialProbs = new Array(maxK + 1).fill(0);\n binomialProbs[0] = 1;\n\n for (const singleProbability of individualProbabilities) {\n for (let outcomeCount = maxK; outcomeCount >= 1; outcomeCount--) {\n binomialProbs[outcomeCount] =\n binomialProbs[outcomeCount] * (1 - singleProbability) +\n binomialProbs[outcomeCount - 1] * singleProbability;\n }\n binomialProbs[0] *= 1 - singleProbability;\n }\n\n return binomialProbs;\n }\n\n /**\n * Returns the probability that exactly K attacks result in the specified outcome(s).\n *\n * Single label examples:\n * - probExactlyK('hit', 2) = probability exactly 2 attacks hit\n * - probExactlyK('crit', 1) = probability exactly 1 attack crits\n * - probExactlyK('crit', 0) = probability no attacks crit\n *\n * Array examples:\n * - probExactlyK(['hit', 'crit'], 2) = probability exactly 2 attacks succeed\n * - probExactlyK(['hit', 'crit'], 1) = probability exactly 1 attack succeeds\n * - probExactlyK(['miss', 'missNone'], 0) = probability no attacks miss\n *\n * Use cases:\n * - \"What's the chance exactly one of my attacks hits?\"\n * - \"How likely am I to get exactly 2 successes out of 3 attacks?\"\n * - \"What's the probability that exactly half my attacks succeed?\"\n *\n * Note: For arrays, an attack counts as a \"success\" if it has any of the specified labels.\n * This is different from probAtMostK, which counts an attack as a \"success\" if it has ALL of the specified labels.\n */\n probExactlyK(labels: OutcomeType | OutcomeType[], k: number): number {\n // Handle single label case (backward compatibility)\n if (typeof labels === \"string\") {\n const probabilityArray = this.computeBinomialProbabilities(labels, k);\n return probabilityArray[k];\n }\n\n // For multiple labels, we need to compute success probability for each single attack\n const successProbabilities = this.singles.map((single) => {\n const singleQuery = new DiceQuery([single]);\n return singleQuery.probabilityOf(labels);\n });\n\n // Use binomial distribution with combined success probability\n const binomialProbs = new Array(k + 1).fill(0);\n binomialProbs[0] = 1;\n\n for (const successProb of successProbabilities) {\n for (let outcomeCount = k; outcomeCount >= 1; outcomeCount--) {\n binomialProbs[outcomeCount] =\n binomialProbs[outcomeCount] * (1 - successProb) +\n binomialProbs[outcomeCount - 1] * successProb;\n }\n binomialProbs[0] *= 1 - successProb;\n }\n\n return binomialProbs[k];\n }\n\n /**\n * Returns the probability that AT MOST K attacks result in the specified outcome(s).\n *\n * Single label examples:\n * - probAtMostK('hit', 1) = probability 0 or 1 attacks hit (at most 1)\n * - probAtMostK('crit', 0) = probability no attacks crit\n * - probAtMostK('miss', 2) = probability at most 2 attacks miss\n *\n * Array examples:\n * - probAtMostK(['hit', 'crit'], 1) = probability at most 1 attack succeeds\n * - probAtMostK(['hit', 'crit'], 0) = probability no attacks succeed (all miss)\n *\n * Use cases:\n * - \"What's the chance that at most one attack hits?\" (rest miss)\n * - \"How likely am I to have mostly failures?\" (at most 1 success)\n * - \"What's the probability of a really bad turn?\" (at most 0 successes)\n *\n */\n probAtMostK(labels: OutcomeType | OutcomeType[], k: number): number {\n // Handle single label case (backward compatibility)\n if (typeof labels === \"string\") {\n const probabilityArray = this.computeBinomialProbabilities(labels, k);\n let cumulativeSum = 0;\n for (let outcomeCount = 0; outcomeCount <= k; outcomeCount++) {\n cumulativeSum += probabilityArray[outcomeCount];\n }\n return cumulativeSum;\n }\n\n // For multiple labels, compute probabilities for 0 to k\n let cumulativeSum = 0;\n for (let outcomeCount = 0; outcomeCount <= k; outcomeCount++) {\n cumulativeSum += this.probExactlyK(labels, outcomeCount);\n }\n return cumulativeSum;\n }\n\n /**\n * Returns the expected damage attributed to specific outcome types.\n *\n * Single label examples:\n * - expectedDamageFrom('hit') = expected damage from hit components\n * - expectedDamageFrom('crit') = expected damage from crit components\n *\n * Array examples:\n * - expectedDamageFrom(['hit', 'crit']) = expected damage from any success\n * - expectedDamageFrom(['missDamage', 'missNone']) = expected damage from misses\n *\n * Use cases:\n * - \"How much damage do I expect from successful attacks?\"\n * - \"What's the damage contribution from critical hits specifically?\"\n * - \"How much damage comes from miss effects (like save-for-half spells)?\"\n */\n expectedDamageFrom(labels: OutcomeType | OutcomeType[]): number {\n const wanted = Array.isArray(labels) ? labels : [labels];\n\n let total = 0;\n // By linearity of expectation, we can sum the expected damages from each individual PMF. This avoids issues with the `count` aggregation during\n for (const single of this.singles) {\n for (const [dmg, bin] of single) {\n let p = 0;\n for (const label of wanted) p += bin.count[label] ?? 0;\n total += dmg * p;\n }\n }\n return total;\n }\n\n /**\n * Returns damage statistics for scenarios where AT LEAST ONE attack results in\n * the specified outcome(s).\n *\n * This method answers \"What happens when things go reasonably well?\" rather than\n * \"What's the theoretical maximum?\" It includes mixed scenarios which are more\n * common and tactically relevant than pure scenarios.\n *\n * Single label examples:\n * - damageStatsFrom('hit') = damage range when at least one attack hits\n * - damageStatsFrom('crit') = damage range when at least one attack crits\n *\n * Array examples:\n * - damageStatsFrom(['hit', 'crit']) = damage range when at least one attack succeeds\n * - damageStatsFrom(['miss', 'missNone']) = damage range when at least one attack misses\n *\n * Tactical Use Cases:\n * - \"Given that I don't completely whiff (99% of turns), what damage should I expect?\"\n * - \"When planning to kill a 60 HP enemy, what's my damage range on successful turns?\"\n * - \"Should I use this risky spell if it has good damage when it works?\"\n * - \"What's my damage potential when something goes right?\" (vs pure failure)\n *\n * Combat Planning Examples:\n * - 4 attacks with 90% hit chance: \"96% of the time you'll do 25-150 damage, avg 52\"\n * (Much more useful than \"You average 50 damage including complete misses\")\n * - Risk assessment: \"80% of successful turns do 40-80 damage, but 20% do 80-150\"\n * - Resource management: \"If I hit anything, I'll likely finish this enemy\"\n *\n * Statistical Note:\n * This includes mixed scenarios (2 hits + 1 crit, 3 hits + 1 miss, etc.) which\n * occur far more frequently than pure scenarios. For pure scenarios, use combinedDamageStats.\n *\n * @example\n * // High-level tactical planning\n * const successStats = query.damageStatsFrom('hit')\n * const successChance = query.probAtLeastOne('hit')\n * console.log(`${(successChance*100).toFixed(1)}% chance to do ${successStats.min}-${successStats.max} damage`)\n */\n damageStatsFrom(labels: OutcomeType | OutcomeType[]): {\n min: number;\n max: number;\n avg: number;\n count: number;\n } {\n // Normalize input to array for uniform handling\n const labelArray = typeof labels === \"string\" ? [labels] : labels;\n\n let minDamage = Infinity;\n let maxDamage = -Infinity;\n let totalDamage = 0;\n let totalCount = 0;\n\n for (const [damage, probabilityBin] of this.combined) {\n // Check if this bin has any of the specified labels\n let binHasAnyLabel = false;\n let binContribution = 0;\n\n for (const label of labelArray) {\n const count = probabilityBin.count[label] as number;\n if (count && count > 0) {\n binHasAnyLabel = true;\n binContribution += count;\n }\n }\n\n if (damage > 0 && binHasAnyLabel) {\n minDamage = Math.min(minDamage, damage);\n maxDamage = Math.max(maxDamage, damage);\n\n // For single labels, use the specific count; for multiple labels, use total probability\n const weightToUse =\n labelArray.length === 1 ? binContribution : probabilityBin.p;\n totalDamage += damage * weightToUse;\n totalCount += weightToUse;\n }\n }\n\n return {\n min: minDamage === Infinity ? 0 : minDamage,\n max: maxDamage === -Infinity ? 0 : maxDamage,\n avg: totalCount > 0 ? totalDamage / totalCount : 0,\n count: totalCount,\n };\n }\n\n /**\n * Returns damage statistics for scenarios where ALL attacks result in the specified\n * outcome, calculated by leveraging the pure partition of singles.\n *\n * This method answers \"What's the theoretical best/worst case?\" and \"What are the\n * clean mathematical boundaries?\" It provides pure scenarios without mixing outcomes.\n *\n * Examples:\n * - combinedDamageStats('hit') = damage range when all attacks hit (none crit, none miss)\n * - combinedDamageStats('crit') = damage range when all attacks crit (none just hit)\n *\n * UI and Display Use Cases:\n * - Statistics panels showing \"MAX Hit Damage\" (users expect pure hits, not mixed)\n * - \"Best case scenario\" vs \"worst case scenario\" analysis\n * - Mathematical verification: \"Does our hit damage calculation match manual math?\"\n * - Clean damage type attribution: \"How much comes from base hits vs crits?\"\n *\n * Design and Balance Use Cases:\n * - Game designers: \"What's the damage ceiling if someone gets lucky?\"\n * - Character optimization: \"What's my absolute maximum potential?\"\n * - Ability comparison: \"Which build has higher crit ceiling?\"\n * - Minimum guaranteed damage: \"What's the worst I can do if everything hits?\"\n *\n * Mathematical Use Cases:\n * - Validating complex calculations against simple manual math\n * - Understanding damage component contributions in isolation\n * - Separating luck (crit variance) from consistency (hit variance)\n * - Building intuition about damage sources\n *\n * When to Use This vs damageStatsFrom():\n * - Use THIS for: UI max/min displays, theoretical limits, clean comparisons\n * - Use damageStatsFrom() for: tactical planning, realistic expectations, mixed scenarios\n *\n * Statistical Note:\n * Pure scenarios (all hits, all crits) are rare but represent clear mathematical\n * boundaries. These stats help understand the \"shape\" of your damage potential.\n *\n * @example\n * // UI display logic\n * const pureHitMax = query.combinedDamageStats('hit').max // Clean \"MAX Hit Damage: 90\"\n * const pureCritMax = query.combinedDamageStats('crit').max // Clean \"MAX Crit Damage: 168\"\n *\n * // vs tactical planning (use damageStatsFrom instead)\n * const realisticRange = query.damageStatsFrom('hit') // Includes mixed scenarios\n */\n combinedDamageStats(targetLabel: OutcomeType): {\n min: number;\n max: number;\n avg: number;\n count: number;\n } {\n // Get pure statistics from each single attack (singles are already pure partitions)\n const singleStats = this.singles.map((single) =>\n new DiceQuery([single]).damageStatsFrom(targetLabel)\n );\n\n // If any single attack has no outcomes of this type, return zeros\n if (singleStats.some((stats) => stats.count === 0)) {\n return { min: 0, max: 0, avg: 0, count: 0 };\n }\n\n // Calculate combined statistics for N attacks all of target type\n const combinedMin = singleStats.reduce((sum, stats) => sum + stats.min, 0);\n const combinedMax = singleStats.reduce((sum, stats) => sum + stats.max, 0);\n const combinedAvg = singleStats.reduce((sum, stats) => sum + stats.avg, 0);\n const combinedProb = singleStats.reduce(\n (product, stats) => product * stats.count,\n 1\n );\n\n return {\n min: combinedMin,\n max: combinedMax,\n avg: combinedAvg,\n count: combinedProb,\n };\n }\n\n /**\n * Returns the probability that a result includes ANY of the specified labels.\n *\n * Examples:\n * - `query.probabilityOf('hit')` → 0.88 (probability at least one hit occurs)\n * - `query.probabilityOf(['hit', 'crit'])` → 0.96 (probability of any success)\n *\n * Use cases:\n * - \"What's the chance my resolution includes a success label?\"\n * - \"How likely am I to get any hits or crits across all attacks?\"\n */\n probabilityOf(labels: OutcomeType | OutcomeType[]): number {\n // Handle single label case (backward compatibility)\n if (typeof labels === \"string\") {\n labels = [labels];\n }\n\n let totalProbability = 0;\n for (const [, probabilityBin] of this.combined) {\n // Calculate probability that this bin contains ANY of the specified labels\n // Use inclusion-exclusion principle to avoid double-counting overlaps\n let binHasAnyLabel = false;\n for (const label of labels) {\n if (\n probabilityBin.count[label] &&\n (probabilityBin.count[label] as number) > 0\n ) {\n binHasAnyLabel = true;\n break;\n }\n }\n if (binHasAnyLabel) {\n totalProbability += probabilityBin.p;\n }\n }\n return totalProbability;\n }\n\n /**\n * Returns the probability of missing (any type of miss).\n *\n * Example: `query.missChance()` → 0.04\n * Use case: \"What's the chance I miss completely this turn?\"\n */\n missChance(): number {\n // Miss can be either explicit misses with damage or zero-damage misses\n return this.probabilityOf([\"missDamage\", \"missNone\"]);\n }\n\n /**\n * Returns data formatted for plotting damage probability distribution.\n *\n * Example: `query.toChartSeries()` → [{x: 0, y: 0.04}, {x: 6, y: 0.1}, ...]\n * Use case: \"I want to visualize my damage distribution in a chart.\"\n */\n toChartSeries(): Array<{ x: number; y: number }> {\n return this.combined.support().map((damageValue) => ({\n x: damageValue,\n y: this.combined.map.get(damageValue)!.p,\n }));\n }\n\n /**\n * Returns tabular data showing damage values and their probability breakdowns.\n *\n * Example: `query.toLabeledTable(['hit', 'crit'])` →\n * [{damage: 6, total: 0.01, hit: 0.008, crit: 0}, ...]\n *\n * Use case: \"I want to see exactly how hit/crit probabilities contribute to each damage value.\"\n */\n toLabeledTable(\n labels: OutcomeType[] = []\n ): Array<{ damage: number; total: number } & Record<string, number>> {\n return this.combined.support().map((damageValue) => {\n const probabilityBin = this.combined.map.get(damageValue)!;\n const tableRow: { damage: number; total: number } & Record<\n string,\n number\n > = {\n damage: damageValue,\n total: probabilityBin.p,\n };\n for (const outcomeLabel of labels) {\n tableRow[outcomeLabel] = probabilityBin.count[outcomeLabel] || 0;\n }\n return tableRow;\n });\n }\n\n /**\n * Returns data for stacked charts with unconditional per-label probability mass per damage.\n *\n * - Each dataset value equals the unconditional probability mass for that label at that damage\n * (i.e., `bin.count[label]`).\n * - Column sums may be less than the total probability `bin.p` when you omit labels or when\n * there is unlabeled mass. Include all relevant outcome labels if you need the sum to match.\n * - This behavior matches tests that expect raw per-label mass (not proportional scaling).\n * - NOTE: This implementation may break dprcalc.com chart binning at large n, need to test it more.\n *\n * @example\n * query.toStackedChartData(['hit', 'crit'])\n * // → {labels: [0, 6, 12, ...], datasets: [{label: 'hit', data: [0, 0.03, ...]}, ...]}\n */\n toStackedChartData(\n labels: OutcomeType[] = [],\n epsilon = EPS\n ): { labels: number[]; datasets: Array<{ label: string; data: number[] }> } {\n const damageValues = this.combined.support();\n\n // Precompute totalCount per bin for the labels you intend to stack for efficiency.\n damageValues.map((dmg) => {\n const bin = this.combined.map.get(dmg)!;\n return labels.reduce((sum, lab) => sum + (bin.count[lab] || 0), 0);\n });\n\n const datasets = labels.map((outcomeLabel) => ({\n label: outcomeLabel,\n data: damageValues.map((dmg) => {\n const bin = this.combined.map.get(dmg);\n const v = bin ? (bin.count[outcomeLabel] as number) || 0 : 0;\n return v <= epsilon ? 0 : v;\n }),\n }));\n\n return { labels: damageValues, datasets };\n }\n\n /**\n * Returns pure mathematical data for attribution charts showing outcome contributions.\n *\n * Automatically discovers all outcome types present in the PMF, applies filtering rules,\n * and returns proportional data suitable for stacked visualization.\n *\n * @param options Configuration options\n * @param options.stackOrder Preferred order for outcome types (unknowns placed at end)\n * @param options.filterRules Function to determine if outcome should be included for a given damage value\n * @param options.asPercentages Whether to return percentages (0-100) or probabilities (0-1)\n * @returns Pure data structure with support, outcomes, and proportional data\n *\n * @example\n * query.toAttributionChartSeries()\n * // → {support: [0, 6, 12], outcomes: ['hit', 'crit'], data: {hit: [5.2, 8.1, ...], crit: [0, 2.3, ...]}}\n */\n toAttributionChartSeries(\n options: {\n stackOrder?: string[];\n filterRules?: (outcome: string, damage: number) => boolean;\n asPercentages?: boolean;\n } = {}\n ): {\n support: number[];\n outcomes: string[];\n data: { [outcome: string]: number[] };\n } {\n const {\n stackOrder = [\n \"missNone\",\n \"missDamage\",\n \"saveFail\",\n \"saveHalf\",\n \"pc\",\n \"hit\",\n \"crit\",\n ],\n filterRules = (outcome: string, damage: number) =>\n !(outcome === \"missNone\" && damage !== 0),\n asPercentages = true,\n } = options;\n\n const originalSupport = this.combined.support();\n if (originalSupport.length === 0) {\n return { support: [], outcomes: [], data: {} };\n }\n\n // Create complete integer range from min to max\n const minDamage = Math.min(...originalSupport);\n const maxDamage = Math.max(...originalSupport);\n const support = Array.from(\n { length: maxDamage - minDamage + 1 },\n (_, i) => minDamage + i\n );\n\n // Find ALL outcome types that exist in the PMF\n const allOutcomeTypes = new Set<string>();\n for (const [, bin] of this.combined.map) {\n for (const outcomeType in bin.count) {\n if (bin.count[outcomeType] && (bin.count[outcomeType] as number) > 0) {\n allOutcomeTypes.add(outcomeType);\n }\n }\n }\n\n // Sort existing outcomes by preferred stack order, with unknowns at end\n const existingOutcomes = Array.from(allOutcomeTypes).sort((a, b) => {\n const indexA = stackOrder.indexOf(a);\n const indexB = stackOrder.indexOf(b);\n\n // If both are in stackOrder, use that order\n if (indexA >= 0 && indexB >= 0) return indexA - indexB;\n\n // Put unknowns at the end\n if (indexA >= 0) return -1;\n if (indexB >= 0) return 1;\n\n // Both unknown, alphabetical\n return a.localeCompare(b);\n });\n\n if (existingOutcomes.length === 0) {\n return { support, outcomes: [], data: {} };\n }\n\n // Calculate data for each outcome type\n const data: { [outcome: string]: number[] } = {};\n\n for (const outcome of existingOutcomes) {\n data[outcome] = support.map((damage) => {\n const bin = this.combined.map.get(damage);\n if (!bin) return 0;\n\n // Apply filter rules\n if (!filterRules(outcome, damage)) {\n return 0;\n }\n\n // Calculate proportion only among outcomes that will actually be charted\n const outcomeCount = (bin.count[outcome] as number) || 0;\n\n // Calculate total count excluding outcomes that will be filtered out\n let totalChartableCount = 0;\n for (const [outcomeName, count] of Object.entries(bin.count)) {\n if (filterRules(outcomeName, damage)) {\n totalChartableCount += (count as number) || 0;\n }\n }\n\n if (totalChartableCount === 0) return 0;\n\n // Calculate what fraction of chartable probability comes from this outcome\n const outcomeFraction = outcomeCount / totalChartableCount;\n const outcomeProbability = bin.p * outcomeFraction;\n\n return asPercentages ? outcomeProbability * 100 : outcomeProbability;\n });\n }\n\n return {\n support,\n outcomes: existingOutcomes,\n data,\n };\n }\n\n /**\n * Returns pure mathematical data for damage attribution charts showing damage contribution\n * from each outcome type at each damage value.\n *\n * Similar to toAttributionChartSeries() but uses bin.attr (damage attribution) instead of\n * bin.count (probability attribution).\n *\n * @param options Configuration options\n * @param options.stackOrder Preferred order for outcome types (unknowns placed at end)\n * @param options.filterRules Function to determine if outcome should be included for a given damage value\n * @param options.asPercentages Whether to return percentages (0-100) or raw damage values (0+)\n * @returns Pure data structure with support, outcomes, and damage attribution data\n *\n * @example\n * query.toDamageAttributionChartSeries()\n * // → {support: [0, 6, 12], outcomes: ['hit', 'crit'], data: {hit: [3.2, 5.1, ...], crit: [0, 1.8, ...]}}\n */\n toDamageAttributionChartSeries(\n options: {\n stackOrder?: string[];\n filterRules?: (outcome: string, damage: number) => boolean;\n asPercentages?: boolean;\n } = {}\n ): {\n support: number[];\n outcomes: string[];\n data: { [outcome: string]: number[] };\n } {\n const {\n stackOrder = [\n \"missNone\",\n \"missDamage\",\n \"saveFail\",\n \"saveHalf\",\n \"pc\",\n \"hit\",\n \"crit\",\n ],\n filterRules = (outcome: string, damage: number) =>\n !(outcome === \"missNone\" && damage !== 0),\n asPercentages = true,\n } = options;\n\n const originalSupport = this.combined.support();\n if (originalSupport.length === 0) {\n return { support: [], outcomes: [], data: {} };\n }\n\n // Create complete integer range from min to max\n const minDamage = Math.min(...originalSupport);\n const maxDamage = Math.max(...originalSupport);\n const support = Array.from(\n { length: maxDamage - minDamage + 1 },\n (_, i) => minDamage + i\n );\n\n // Find ALL outcome types that exist in the PMF (from attr, not count)\n const allOutcomeTypes = new Set<string>();\n for (const [, bin] of this.combined.map) {\n if (bin.attr) {\n for (const outcomeType in bin.attr) {\n if (bin.attr[outcomeType] && (bin.attr[outcomeType] as number) > 0) {\n allOutcomeTypes.add(outcomeType);\n }\n }\n }\n }\n\n // Sort existing outcomes by preferred stack order, with unknowns at end\n const existingOutcomes = Array.from(allOutcomeTypes).sort((a, b) => {\n const indexA = stackOrder.indexOf(a);\n const indexB = stackOrder.indexOf(b);\n\n // If both are in stackOrder, use that order\n if (indexA >= 0 && indexB >= 0) return indexA - indexB;\n\n // Put unknowns at the end\n if (indexA >= 0) return -1;\n if (indexB >= 0) return 1;\n\n // Both unknown, alphabetical\n return a.localeCompare(b);\n });\n\n if (existingOutcomes.length === 0) {\n return { support, outcomes: [], data: {} };\n }\n\n // Calculate data for each outcome type\n const data: { [outcome: string]: number[] } = {};\n\n for (const outcome of existingOutcomes) {\n data[outcome] = support.map((damage) => {\n const bin = this.combined.map.get(damage);\n if (!bin || !bin.attr) return 0;\n\n // Apply filter rules\n if (!filterRules(outcome, damage)) {\n return 0;\n }\n\n // Get the damage attribution for this outcome at this damage value\n const outcomeDamageAttribution = (bin.attr[outcome] as number) || 0;\n\n if (asPercentages) {\n // Calculate total damage attribution at this damage value (for percentage calculation)\n let totalDamageAttribution = 0;\n for (const [outcomeName, damageAttr] of Object.entries(bin.attr)) {\n if (filterRules(outcomeName, damage)) {\n totalDamageAttribution += (damageAttr as number) || 0;\n }\n }\n\n if (totalDamageAttribution === 0) return 0;\n\n // Calculate the damage attribution percentage\n const damagePercentage =\n (outcomeDamageAttribution / totalDamageAttribution) * 100;\n\n // Scale by the probability of this damage value occurring\n // This makes bar height proportional to P(damage = x) while preserving attribution percentages\n return damagePercentage * bin.p * 100; // Scale by probability, *100 to make visible\n } else {\n return outcomeDamageAttribution;\n }\n });\n }\n\n return {\n support,\n outcomes: existingOutcomes,\n data,\n };\n }\n\n /**\n * Returns pure mathematical data for outcome attribution charts showing which\n * attack outcome combinations can produce each damage value.\n *\n * Unlike toDamageAttributionChartSeries() which tracks damage sources, this tracks\n * outcome combinations - answering \"what attack outcomes produced this damage?\"\n *\n * @param options Configuration options\n * @param options.stackOrder Preferred order for outcome types (unknowns placed at end)\n * @param options.filterRules Function to determine if outcome should be included for a given damage value\n * @param options.asPercentages Whether to return percentages (0-100) or probabilities (0-1)\n * @returns Pure data structure with support, outcomes, and outcome combination probabilities\n *\n * @example\n * query.toOutcomeAttributionChartSeries()\n * // → {support: [0, 6, 12], outcomes: ['all_miss', 'mixed', 'all_hit'], data: {all_miss: [15, 0, 0], mixed: [60, 80, 20], all_hit: [25, 20, 80]}}\n */\n toOutcomeAttributionChartSeries(\n options: {\n stackOrder?: string[];\n filterRules?: (outcome: string, damage: number) => boolean;\n asPercentages?: boolean;\n } = {}\n ): {\n support: number[];\n outcomes: string[];\n data: { [outcome: string]: number[] };\n } {\n const {\n stackOrder = [\n \"missNone\",\n \"missDamage\",\n \"saveFail\",\n \"saveHalf\",\n \"pc\",\n \"hit\",\n \"crit\",\n ],\n filterRules = (outcome: string, damage: number) =>\n !(outcome === \"missNone\" && damage !== 0),\n asPercentages = true,\n } = options;\n\n const originalSupport = this.combined.support();\n if (originalSupport.length === 0) {\n return { support: [], outcomes: [], data: {} };\n }\n\n // Create complete integer range from min to max\n const minDamage = Math.min(...originalSupport);\n const maxDamage = Math.max(...originalSupport);\n const support = Array.from(\n { length: maxDamage - minDamage + 1 },\n (_, i) => minDamage + i\n );\n\n // Find ALL outcome types that exist in the PMF (from count, for outcome tracking)\n const allOutcomeTypes = new Set<string>();\n for (const [, bin] of this.combined.map) {\n for (const outcomeType in bin.count) {\n if (bin.count[outcomeType] && (bin.count[outcomeType] as number) > 0) {\n allOutcomeTypes.add(outcomeType);\n }\n }\n }\n\n // Sort existing outcomes by preferred stack order, with unknowns at end\n const existingOutcomes = Array.from(allOutcomeTypes).sort((a, b) => {\n const indexA = stackOrder.indexOf(a);\n const indexB = stackOrder.indexOf(b);\n\n if (indexA >= 0 && indexB >= 0) return indexA - indexB;\n if (indexA >= 0) return -1;\n if (indexB >= 0) return 1;\n return a.localeCompare(b);\n });\n\n if (existingOutcomes.length === 0) {\n return { support, outcomes: [], data: {} };\n }\n\n // Calculate data for each outcome type\n const data: { [outcome: string]: number[] } = {};\n\n for (const outcome of existingOutcomes) {\n data[outcome] = support.map((damage) => {\n const bin = this.combined.map.get(damage);\n if (!bin) return 0;\n\n // Apply filter rules\n if (!filterRules(outcome, damage)) {\n return 0;\n }\n\n // Handle missNone specially since it doesn't appear in bin.attr (0 damage)\n if (outcome === \"missNone\") {\n // For missNone, use bin.count since it contributes 0 damage\n const outcomeCount = (bin.count[outcome] as number) || 0;\n if (outcomeCount === 0) return 0;\n\n if (asPercentages) {\n // For missNone, show probability proportion since damage attribution would be 0\n let totalChartableCount = 0;\n for (const [outcomeName, count] of Object.entries(bin.count)) {\n if (filterRules(outcomeName, damage)) {\n totalChartableCount += (count as number) || 0;\n }\n }\n if (totalChartableCount === 0) return 0;\n const outcomeFraction = outcomeCount / totalChartableCount;\n return outcomeFraction * bin.p * 100;\n } else {\n return outcomeCount;\n }\n }\n\n // Use damage attribution to calculate proportional contribution for non-missNone outcomes\n if (!bin.attr) return 0;\n\n const outcomeDamageContribution = (bin.attr[outcome] as number) || 0;\n\n if (asPercentages) {\n // Calculate total damage attribution at this damage value\n let totalDamageAttribution = 0;\n for (const [, damageAttr] of Object.entries(bin.attr)) {\n totalDamageAttribution += (damageAttr as number) || 0;\n }\n\n if (totalDamageAttribution === 0) return 0;\n\n // The proportion is: damage from this outcome / total damage from all outcomes\n // This gives us exactly what you want: for damage 13 = hit(11) + miss(2),\n // hit proportion = 11/13, miss proportion = 2/13\n const outcomeFraction =\n outcomeDamageContribution / totalDamageAttribution;\n\n // Scale by probability for bar height while preserving damage attribution percentages\n return outcomeFraction * bin.p * 100;\n } else {\n return outcomeDamageContribution;\n }\n });\n }\n\n return {\n support,\n outcomes: existingOutcomes,\n data,\n };\n }\n\n /**\n * Returns pure mathematical data for cumulative distribution function (CDF).\n * Shows P(X ≤ x) - the probability of getting at most x damage.\n *\n * @param asPercentages Whether to return percentages (0-100) or probabilities (0-1)\n * @returns Pure data structure with support and cumulative probabilities\n *\n * @example\n * query.toCDFSeries()\n * // → {support: [0, 6, 12], data: [5.2, 18.3, 45.1]}\n */\n toCDFSeries(asPercentages: boolean = true): {\n support: number[];\n data: number[];\n } {\n const originalSupport = this.combined.support();\n if (originalSupport.length === 0) {\n return { support: [], data: [] };\n }\n\n // Create complete integer range from min to max\n const minDamage = Math.min(...originalSupport);\n const maxDamage = Math.max(...originalSupport);\n const support = Array.from(\n { length: maxDamage - minDamage + 1 },\n (_, i) => minDamage + i\n );\n\n let cumulativeProbability = 0;\n const cdfData: number[] = [];\n\n for (const damage of support) {\n const bin = this.combined.map.get(damage);\n if (bin) {\n cumulativeProbability += bin.p;\n }\n cdfData.push(\n asPercentages ? cumulativeProbability * 100 : cumulativeProbability\n );\n }\n\n return {\n support,\n data: cdfData,\n };\n }\n\n /**\n * Returns pure mathematical data for complementary cumulative distribution function (CCDF).\n * Shows P(X ≥ x) - the probability of getting at least x damage.\n *\n * @param asPercentages Whether to return percentages (0-100) or probabilities (0-1)\n * @returns Pure data structure with support and complementary cumulative probabilities\n *\n * @example\n * query.toCCDFSeries()\n * // → {support: [0, 6, 12], data: [100, 94.8, 81.7]}\n */\n toCCDFSeries(asPercentages: boolean = true): {\n support: number[];\n data: number[];\n } {\n const originalSupport = this.combined.support();\n if (originalSupport.length === 0) {\n return { support: [], data: [] };\n }\n\n // Create complete integer range from min to max\n const minDamage = Math.min(...originalSupport);\n const maxDamage = Math.max(...originalSupport);\n const support = Array.from(\n { length: maxDamage - minDamage + 1 },\n (_, i) => minDamage + i\n );\n\n // Calculate CCDF: P(X ≥ x) = 1 - P(X < x)\n let cumulativeProbability = 0;\n const ccdfData: number[] = [];\n\n for (const damage of support) {\n // For CCDF at point x, we want P(X ≥ x) = 1 - P(X < x)\n // which is the total probability minus cumulative up to (but not including) x\n const ccdf = 1 - cumulativeProbability;\n ccdfData.push(asPercentages ? ccdf * 100 : ccdf);\n\n // Now add current probability for next iteration\n const bin = this.combined.map.get(damage);\n if (bin) {\n cumulativeProbability += bin.p;\n }\n }\n\n return {\n support,\n data: ccdfData,\n };\n }\n\n /*\n Statistics snapshot of the query.\n */\n\n /** Probability of doing strictly more than threshold damage (default >0). */\n probDamageGreaterThan(threshold = 0): number {\n let acc = 0;\n for (const [x, bin] of this.combined.map) if (x > threshold) acc += bin.p;\n return acc;\n }\n\n /** All outcome keys actually present (typed & ordered if you pass an order). */\n outcomeKeys(order?: OutcomeType[]): OutcomeType[] {\n const found = new Set<string>();\n for (const [, bin] of this.combined.map) {\n for (const k in bin.count)\n if (bin.count[k] && (bin.count[k] as number) > 0) found.add(k);\n }\n if (found.size === 0)\n [\"hit\", \"crit\", \"missNone\"].forEach((k) => found.add(k));\n const keys = Array.from(found).filter(\n (k) => order?.includes(k as OutcomeType) ?? true\n ) as OutcomeType[];\n if (order && order.length)\n keys.sort((a, b) => order.indexOf(a) + 999 - (order.indexOf(b) + 999));\n return keys;\n }\n\n /** Total probability per outcome across the PMF. */\n outcomeTotals(\n outcomes: OutcomeType[] = this.outcomeKeys()\n ): Map<OutcomeType, number> {\n const totals = new Map<OutcomeType, number>();\n outcomes.forEach((o) => totals.set(o, 0));\n for (const [, row] of this.combined.map) {\n for (const o of outcomes) {\n const p = (row.count[o] as number) || 0; // if your bins store per-outcome p; else derive via toLabeledTable\n totals.set(o, (totals.get(o) || 0) + p);\n }\n }\n return totals;\n }\n\n /** Conditional damage range per outcome (min/avg/max of X | outcome). */\n outcomeDamageRanges(\n outcomes: OutcomeType[] = this.outcomeKeys()\n ): Map<OutcomeType, { min: number; avg: number; max: number }> {\n // Use toLabeledTable to stay consistent with your existing attribution\n const table = this.toLabeledTable(outcomes);\n const ranges = new Map<\n OutcomeType,\n { min?: number; max?: number; sum: number; mass: number }\n >();\n outcomes.forEach((o) => ranges.set(o, { sum: 0, mass: 0 }));\n\n for (const row of table) {\n const dmg = row.damage as number;\n for (const o of outcomes) {\n const p = (row[o] as number) || 0; // joint mass at (damage, outcome)\n if (p > 0) {\n const r = ranges.get(o)!;\n r.sum += dmg * p;\n r.mass += p;\n if (r.min === undefined || dmg < r.min) r.min = dmg;\n if (r.max === undefined || dmg > r.max) r.max = dmg;\n }\n }\n }\n\n const out = new Map<\n OutcomeType,\n { min: number; avg: number; max: number }\n >();\n for (const o of outcomes) {\n const r = ranges.get(o)!;\n const avg = r.mass > 0 ? r.sum / r.mass : 0;\n out.set(o, { min: r.min ?? 0, avg, max: r.max ?? 0 });\n }\n return out;\n }\n\n /**\n * Snapshot of the distribution in the exact shape the UI consumes.\n * - outcome probabilities are \"at least one\" (and equal to \"all\" for a single PMF)\n * - damageRange is conditional on the outcome occurring\n */\n snapshot(order?: readonly OutcomeType[]): Snapshot {\n // 1) Discover which outcomes actually appear in this PMF\n const discovered = new Set<string>();\n for (const [, bin] of this.combined.map) {\n for (const k in bin.count) {\n if (bin.count[k] && (bin.count[k] as number) > 0) discovered.add(k);\n }\n }\n if (discovered.size === 0) {\n for (const k of DiceQuery.DEFAULT_OUTCOMES) discovered.add(k);\n }\n\n let outcomes = Array.from(discovered);\n\n // Optional filtering + ordering if a preferred order was provided\n if (order && order.length) {\n const inOrder = new Set(order);\n outcomes = outcomes.filter((k) => inOrder.has(k as OutcomeType));\n const rank = new Map(order.map((k, i) => [k, i]));\n outcomes.sort(\n (a, b) =>\n (rank.get(a as OutcomeType) ?? 999) -\n (rank.get(b as OutcomeType) ?? 999)\n );\n }\n\n // 2) Aggregate per-outcome mass and conditional damage ranges via labeled table\n const rows = this.toLabeledTable(outcomes as OutcomeType[]);\n\n const totals = new Map<OutcomeType, number>();\n const rangeAcc = new Map<\n OutcomeType,\n { min?: number; max?: number; sum: number; mass: number }\n >();\n for (const ot of outcomes) {\n totals.set(ot as OutcomeType, 0);\n rangeAcc.set(ot as OutcomeType, { sum: 0, mass: 0 });\n }\n\n for (const row of rows) {\n const dmg = row.damage as number;\n for (const ot of outcomes) {\n const p = (row[ot] as number) || 0;\n if (p <= 0) continue;\n totals.set(ot as OutcomeType, (totals.get(ot as OutcomeType) || 0) + p);\n\n const r = rangeAcc.get(ot as OutcomeType)!;\n r.sum += dmg * p;\n r.mass += p;\n if (r.min === undefined || dmg < r.min) r.min = dmg;\n if (r.max === undefined || dmg > r.max) r.max = dmg;\n }\n }\n\n const outcomeMap = new Map<OutcomeType, OutcomeSnapshot>();\n for (const ot of outcomes) {\n const total = totals.get(ot as OutcomeType) || 0;\n const r = rangeAcc.get(ot as OutcomeType)!;\n const avg = r.mass > 0 ? r.sum / r.mass : 0;\n outcomeMap.set(ot as OutcomeType, {\n atLeastOneProbability: total,\n allProbability: total, // single aggregate PMF: same value\n damageRange: { min: r.min ?? 0, avg, max: r.max ?? 0 },\n });\n }\n\n // 3) Scalars: mean, damageChance, and percentiles from the dense CDF\n const averageDPR = this.mean();\n\n let damageChance = 0; // P(total damage > 0)\n for (const [x, bin] of this.combined.map) if (x > 0) damageChance += bin.p;\n\n const { support, data } = this.toCDFSeries(false); // P(X ≤ x) in 0..1\n const quantile = (p: number) => {\n if (support.length === 0) return 0;\n for (let i = 0; i < support.length; i++)\n if (data[i] >= p) return support[i];\n return support[support.length - 1];\n };\n const percentiles = {\n p25: quantile(0.25),\n p50: quantile(0.5),\n p75: quantile(0.75),\n };\n\n return { averageDPR, damageChance, percentiles, outcomes: outcomeMap };\n }\n\n /**\n * PMF Transformation Methods\n *\n * These methods provide a fluent API for transforming dice queries by wrapping\n * the underlying PMF transformation methods. All operations work on the combined\n * PMF and return new DiceQuery instances.\n */\n\n /**\n * Returns a new DiceQuery with normalized probabilities (ensuring they sum to 1.0).\n *\n * @returns New DiceQuery with normalized combined PMF\n */\n normalize(): DiceQuery {\n return new DiceQuery([this.combined.normalize()]);\n }\n\n /**\n * Returns a new DiceQuery with low-probability outcomes removed.\n *\n * @param eps Minimum probability threshold (defaults to PMF epsilon)\n * @param keepFinalBin Whether to keep the highest damage bin regardless of probability\n * @returns New DiceQuery with compacted combined PMF\n */\n compact(eps?: number, keepFinalBin?: boolean): DiceQuery {\n return new DiceQuery([this.combined.compact(eps, keepFinalBin)]);\n }\n\n /**\n * Returns a new DiceQuery with an additional scaled branch added.\n * Useful for conditional outcomes like \"30% chance of opportunity attack\".\n *\n * @param branch DiceQuery to add as a scaled branch\n * @param probability Probability of the branch occurring (0-1)\n * @returns New DiceQuery combining this query with the scaled branch\n *\n * @example\n * const baseAttack = parse(\"(d20 + 5 AC 15) * (2d6 + 3)\");\n * const opportunityAttack = parse(\"(d20 + 5 AC 15) * (1d8 + 3)\");\n * const withOpportunity = baseAttack.addScaled(opportunityAttack, 0.3);\n */\n addScaled(branch: DiceQuery, probability: number): DiceQuery {\n return new DiceQuery([\n this.combined.addScaled(branch.combined, probability),\n ]);\n }\n\n /**\n * Returns a new DiceQuery with all probabilities scaled by a factor.\n * Used for conditional scenarios where the entire outcome has reduced probability.\n *\n * @param factor Scaling factor for probabilities\n * @returns New DiceQuery with scaled probabilities\n *\n * @example\n * const fullAttack = parse(\"(d20 + 5 AC 15) * (2d6 + 3)\");\n * const conditionalAttack = fullAttack.scaleMass(0.3); // 30% chance scenario\n */\n scaleMass(factor: number): DiceQuery {\n return new DiceQuery([this.combined.scaleMass(factor)]);\n }\n\n totalMass(): number {\n return this.combined.mass();\n }\n\n /**\n * Returns a new DiceQuery with damage values transformed by a function.\n * Useful for applying modifiers, resistances, or other damage transformations.\n *\n * @param damageTransformFunction Function to transform each damage value\n * @returns New DiceQuery with transformed damage values\n *\n * @example\n * const baseAttack = parse(\"2d6 + 3\");\n * const withResistance = baseAttack.mapDamage(dmg => Math.floor(dmg / 2)); // Half damage\n * const withBonus = baseAttack.mapDamage(dmg => dmg + 5); // +5 damage\n */\n mapDamage(\n damageTransformFunction: (damageValue: number) => number\n ): DiceQuery {\n return new DiceQuery([this.combined.mapDamage(damageTransformFunction)]);\n }\n\n /**\n * Returns a new DiceQuery with damage values scaled by a factor.\n * Convenient wrapper around mapDamage for multiplicative scaling.\n *\n * @param factor Scaling factor for damage values\n * @param rounding Rounding method: \"floor\" (default), \"round\", or \"ceil\"\n * @returns New DiceQuery with scaled damage values\n *\n * @example\n * const baseAttack = parse(\"2d6 + 3\");\n * const doubled = baseAttack.scaleDamage(2); // Double damage\n * const halfDamage = baseAttack.scaleDamage(0.5, \"round\"); // Half damage, rounded\n */\n scaleDamage(\n factor: number,\n rounding: \"floor\" | \"round\" | \"ceil\" = \"floor\"\n ): DiceQuery {\n return new DiceQuery([this.combined.scaleDamage(factor, rounding)]);\n }\n\n /**\n * Returns a new DiceQuery combining this query with another via convolution.\n * Equivalent to rolling both queries independently and adding results.\n * It is important to use this rather than combing()ing the PMFs directly!\n * This method maintains the provenance of the PMFs which is needed for damage attribution.\n * Combining the .combined PMFs directly is still valid for DPR calculations but\n * is not statistically sound for queries.\n *\n * @param other DiceQuery to combine with\n * @param eps Optional epsilon for precision control\n * @returns New DiceQuery representing the combined outcome\n *\n * @example\n * const mainAttack = parse(\"(d20 + 5 AC 15) * (2d6 + 3)\");\n * const bonusAttack = parse(\"(d20 + 3 AC 15) * (1d6 + 1)\");\n * const bothAttacks = mainAttack.convolve(bonusAttack);\n */\n convolve(other: DiceQuery): DiceQuery {\n const singles = [...this.singles, ...other.singles];\n return new DiceQuery(singles);\n }\n\n /**\n * First-success split over an ordered list of DISTINCT single-swing PMFs.\n * Each PMF may have different success/subset probabilities (from labels).\n *\n * successOutcome: e.g., [\"success\"] or [\"hit\", \"crit\"]\n * subsetOutcome: e.g., [\"subset\"] or [\"crit\"] where subset ⊆ success\n *\n * Returns tuple: [pFirstNonSubset, pFirstSubset, pAnySuccess, pNone]\n */\n public firstSuccessSplit(\n successOutcome: string | string[],\n subsetOutcome: string | string[],\n eps = EPS\n ): readonly [pSuccess: number, pSubset: number, pAny: number, pNone: number] {\n const pmfs = this.singles;\n if (!pmfs.length) {\n throw new Error(\"firstSuccessSplitFromPMFs: pmfs must be non-empty\");\n }\n\n const toArr = (x: string | string[]) => (Array.isArray(x) ? x : [x]);\n const clamp01 = (x: number) => Math.max(0, Math.min(1, x));\n const tol = Math.max(eps, 8 * Number.EPSILON);\n\n // Per-event probabilities from each PMF via DiceQuery([pmf])\n const per = pmfs.map((pmf) => {\n const dq = new DiceQuery([pmf]);\n const pS = dq.probAtLeastOne(toArr(successOutcome) as any);\n const pB = dq.probAtLeastOne(toArr(subsetOutcome) as any);\n if (pB - pS > eps) {\n throw new Error(\n \"firstSuccessSplitFromPMFs: P(subset) > P(success) for an event. Ensure subset ⊆ success.\"\n );\n }\n return { pS, pB };\n });\n\n // Aggregate with running miss prefix\n let missSoFar = 1;\n let pFirstSubset = 0;\n let pFirstNonSubset = 0;\n let pNone = 1;\n\n for (const { pS, pB } of per) {\n pFirstSubset += missSoFar * pB;\n pFirstNonSubset += missSoFar * (pS - pB);\n const miss = 1 - pS;\n missSoFar *= miss;\n pNone *= miss;\n }\n\n const pAny = 1 - pNone;\n\n // Clamp and sanity check\n const a = clamp01(pFirstNonSubset);\n const b = clamp01(pFirstSubset);\n const any = clamp01(pAny);\n const none = clamp01(pNone);\n\n if (Math.abs(a + b - any) > tol * Math.max(1, any)) {\n throw new Error(\n `firstSuccessSplitFromPMFs: parts do not sum to pAny. got a+b=${\n a + b\n }, pAny=${any}`\n );\n }\n\n return [a, b, any, none] as const;\n }\n}\n// Make sure these types are exported in your public index, or inline them here.\nexport type OutcomeSnapshot = {\n atLeastOneProbability: number; // P(outcome occurs at least once)\n allProbability: number; // equal to atLeastOneProbability for a single aggregated PMF\n damageRange: { min: number; avg: number; max: number }; // conditional on the outcome occurring\n};\n\nexport type Snapshot = {\n averageDPR: number;\n damageChance: number; // P(total damage > 0)\n percentiles: { p25: number; p50: number; p75: number };\n outcomes: Map<OutcomeType, OutcomeSnapshot>;\n};\n","import { LRUCache } from \"../common/lru-cache\";\nimport type { Bin, OutcomeLabelMap, Rounding } from \"../common/types\";\nimport { EPS } from \"../common/types\";\nimport { DiceQuery } from \"./query\";\n\nconst cacheEnabled = true;\n\nexport const pmfCache = new LRUCache<string, PMF>(1000);\n\n/**\n * Probability Mass Function for discrete damage distributions.\n */\nexport class PMF {\n // Unique ID generator for anonymous PMFs to avoid cache key collisions\n private static __anonIdCounter = 1;\n\n // Cached computed values\n private _support?: number[];\n private _min?: number;\n private _max?: number;\n private _totalMass?: number;\n private _mean?: number;\n private _variance?: number;\n private _stdev?: number;\n\n constructor(\n public readonly map: Map<number, Bin> = new Map(),\n public readonly epsilon = EPS,\n public readonly normalized = false,\n public readonly identifier: string = `anon#${PMF.__anonIdCounter++}`,\n private _preservedProvenance = true\n ) {}\n\n static empty(epsilon = EPS, identifier = \"empty\") {\n return new PMF(new Map(), epsilon, false, identifier);\n }\n\n // This has a single bin at value 0, mass of 1\n static zero(epsilon = EPS): PMF {\n const m = new Map();\n m.set(0, { p: 1, count: { miss: 1 }, attr: {} });\n return new PMF(m, epsilon, false, \"zero\");\n }\n\n static delta(value: number, epsilon = EPS): PMF {\n return PMF.fromMap(new Map([[value, 1]]), epsilon);\n }\n\n // This creates a single bin at value 0, but with weight 0.\n static emptyMass(): PMF {\n return PMF.zero().scaleMass(0);\n }\n\n // Makes PMF iterable over [damage, bin] pairs.\n [Symbol.iterator](): IterableIterator<[number, Bin]> {\n return this.map[Symbol.iterator]();\n }\n\n static clearCache() {\n pmfCache.clear();\n }\n\n /**\n * Creates a conditional PMF from two branches (success and failure) and a probability.\n * This is the core logic for modeling any probabilistic event where there are two\n * distinct outcomes.\n */\n static branch(\n successPMF: PMF,\n failurePMF: PMF,\n successProbability: number\n ): PMF {\n let p = successProbability;\n if (!Number.isFinite(p)) p = 0;\n if (p < 0) p = 0;\n if (p > 1) p = 1;\n\n const q = 1 - p;\n\n // Fast paths\n if (p === 0) return failurePMF.scaleMass(1); // clone\n if (p === 1) return successPMF.scaleMass(1); // clone\n\n // Choose epsilon. You can also pick Math.min for a tighter threshold.\n const eps = successPMF.epsilon ?? failurePMF.epsilon;\n const id = `branch(${failurePMF.identifier}*${q.toFixed(6)} + ${\n successPMF.identifier\n }*${p.toFixed(6)})`;\n\n // Proper Bernoulli mixture: q·failure ⊕ p·success\n const out = PMF.empty(eps, id)\n .addScaled(failurePMF, q)\n .addScaled(successPMF, p);\n\n // Optional hygiene: drop exact zeros\n // return out.compact();\n return out;\n }\n\n /**\n * withProbability()\n *\n * A convenience wrapper around branch() for the common case where the \"failure\" branch is always zero().\n *\n * Think of this as a shortcut for:\n * pmf.gate(p, PMF.zero())\n *\n * Use this to model a *single* Bernoulli event — an outcome that either happens or doesn't,\n * like an opportunity attack that occurs with probability p, or a single attack that either hits or misses.\n *\n * This is **not** for combining multiple independent attacks or mutually exclusive multi-outcome scenarios.\n * - For multiple independent swings, use DiceQuery with separate PMFs for each attack.\n * - For modeling \"first success\" logic across multiple attacks (like Sneak Attack or Smite)\n * use query.firstSuccessSplit() to get the exact probabilities.\n * - For scenarios with several mutually exclusive outcomes (like crit vs hit vs none), use PMF.exclusive().\n *\n */\n static withProbability(successPMF: PMF, probability: number): PMF {\n return PMF.branch(successPMF, PMF.zero(), probability);\n }\n\n /**\n * gate()\n *\n * A conditional wrapper around branch() that applies this PMF with probability `p`,\n * and applies a provided fallback PMF otherwise.\n *\n * This is useful for modeling a binary choice between two outcomes:\n * - The \"success\" outcome (this PMF) happens with probability `p`.\n * - The \"failure\" outcome (fallback PMF) happens with probability `1 - p`.\n *\n * Examples:\n * - 25% chance to include an opportunity attack, otherwise nothing:\n * attackPMF.gate(0.25, PMF.zero())\n *\n * - 50% chance to deal fireball damage, otherwise cone of cold damage:\n * fireballPMF.gate(0.5, coneOfColdPMF)\n *\n * Relationship to other helpers:\n * - **withProbability()** is a shortcut for the common case where the fallback is `PMF.zero()`.\n * - **exclusive()** is for three or more mutually exclusive outcomes (e.g., crit vs hit vs none).\n *\n * @param p Probability of applying this PMF (between 0 and 1).\n * @param fallback PMF to apply when this PMF is *not* selected.\n * @returns A new PMF representing the weighted mixture of this PMF and the fallback.\n */\n gate(p: number, zero: PMF) {\n return PMF.branch(this, zero, p);\n }\n\n /**\n * PMF.exclusive()\n *\n * Builds a single PMF from a set of mutually exclusive weighted outcomes.\n * Exactly one of the provided options will occur.\n *\n * Each option has:\n * - A PMF representing its outcome (e.g., damage dice).\n * - A weight representing its probability of being selected.\n *\n * Notes:\n * - If total weight < 1 (within eps), leftover mass is assumed to be PMF.zero()\n *\n * @param options Array of `{ pmf, weight }` or `[PMF, number]`.\n * @param eps Optional tolerance for floating point rounding.\n */\n static exclusive(\n options: Array<{ pmf: PMF; weight: number } | [PMF, number]>,\n eps = EPS\n ): PMF {\n const items = options.map((o) =>\n Array.isArray(o) ? { pmf: o[0], weight: o[1] } : o\n );\n\n // Validate weights\n for (const { weight } of items) {\n if (!Number.isFinite(weight) || weight < -eps) {\n throw new Error(`PMF.exclusive: invalid weight ${weight}.`);\n }\n }\n\n // Sum and check\n let totalWeight = items.reduce((s, { weight }) => s + weight, 0);\n\n // Normalize tiny negatives to 0 and tiny overshoot to 1 when within eps\n if (Math.abs(totalWeight) <= eps) totalWeight = 0;\n if (Math.abs(1 - totalWeight) <= eps) totalWeight = 1;\n\n if (totalWeight > 1 + EPS) {\n throw new Error(\n `PMF.exclusive: total weight ${totalWeight} exceeds 1. (epsilon: ${eps})`\n );\n }\n\n // Accumulate scaled components, skipping near-zero weights\n let out = PMF.empty(eps);\n for (const { pmf, weight } of items) {\n if (weight > eps) out = out.addScaled(pmf, weight);\n }\n\n // Add leftover mass at zero outcome\n const leftover = Math.max(0, 1 - totalWeight);\n if (leftover > eps) {\n out = out.addScaled(PMF.zero(), leftover);\n }\n\n return out;\n }\n\n /**\n * PMF.mix()\n *\n * Builds a PMF as a linear combination of input PMFs with the given weights.\n * Unlike `exclusive`, this does NOT:\n * - enforce that weights sum to 1\n * - add leftover probability to δ0 (PMF.zero())\n *\n * Use when outcomes are not mutually exclusive, or for interpolation/blending.\n *\n * @param options Array of `{ pmf, weight }` or `[PMF, number]`.\n * @param eps Optional tolerance for skipping tiny weights.\n */\n static mix(\n options: Array<{ pmf: PMF; weight: number } | [PMF, number]>,\n eps = EPS\n ): PMF {\n const items = options.map((o) =>\n Array.isArray(o) ? { pmf: o[0], weight: o[1] } : o\n );\n\n // Validate weights, but do not constrain their sum.\n for (const { weight } of items) {\n if (!Number.isFinite(weight)) {\n throw new Error(`PMF.mix: invalid weight ${weight}.`);\n }\n }\n\n let out = PMF.empty(eps);\n for (const { pmf, weight } of items) {\n if (Math.abs(weight) <= eps) continue; // ignore crumbs\n out = out.addScaled(pmf, weight);\n }\n return out;\n }\n /**\n * Adds damage attribution metadata to this PMF based on existing count metadata.\n * For each bin, sets attr[outcome] = damage × count[outcome].\n *\n * This enables damage attribution charts to work with builder-generated PMFs.\n * The parser generates attr automatically, but builder PMFs only have count.\n *\n * @returns New PMF with attr field populated in each bin\n */\n withAttribution(): PMF {\n // Fast path: if attr already exists, return this PMF unchanged\n // Check if any non-zero damage bin has attr\n for (const [damage, bin] of this.map) {\n if (damage !== 0 && bin.attr && Object.keys(bin.attr).length > 0) {\n return this; // Already has attribution\n }\n // Only check first non-zero bin for performance\n if (damage > 0) break;\n }\n\n const newMap = new Map<number, Bin>();\n\n for (const [damage, bin] of this.map) {\n const attr: OutcomeLabelMap = {};\n\n // For each outcome type in count, compute its damage contribution\n for (const outcome in bin.count) {\n const probability = bin.count[outcome] as number;\n if (probability > 0) {\n attr[outcome] = damage * probability;\n }\n }\n\n // Create new bin with attribution\n newMap.set(damage, {\n p: bin.p,\n count: { ...bin.count },\n attr: Object.keys(attr).length > 0 ? attr : undefined,\n });\n }\n\n // Use a different identifier to avoid cache collisions with non-attributed version\n return new PMF(\n newMap,\n this.epsilon,\n this.normalized,\n `${this.identifier}~attr`\n );\n }\n\n /**\n * General-purpose N-way mixture.\n * weights: Array of [weight, PMF].\n *\n * Example: PMF.mixN([\n * [pMiss, zero],\n * [pHit, hitPMF],\n * [pCrit, critPMF],\n * ]);\n */\n static mixN(weights: [number, PMF][], eps = EPS): PMF {\n // Treat tiny/negative as zero; keep performance clean\n const filtered = weights.filter(([w]) => w > eps);\n\n if (filtered.length === 0) {\n return PMF.emptyMass(); // not PMF.zero(): we want \"no mass\" mixture\n }\n\n // No need to normalize up front; we accumulate and blend by relative weight\n let acc: PMF | null = null;\n let sum = 0;\n\n for (const [w, pmf] of filtered) {\n if (acc === null) {\n acc = pmf;\n sum = w;\n } else {\n const q = w / (sum + w); // relative weight of the new component\n acc = PMF.branch(pmf, acc, q); // success=new pmf, failure=acc\n sum += w;\n }\n }\n\n // If everything got filtered out (all ~0), return empty mass\n return acc ?? PMF.emptyMass();\n }\n\n // This is a convenience method for when we use power\n // TODO: It can be smarter in the future, and we can also add it to query\n // That way statistics operations on invalid PMFs can throw an error\n // TODO… how can we detect if manually merging two queries' combined PMFs, as that loses provenance?\n private setPreservedProvenance(preserved: boolean) {\n if (!this._preservedProvenance && preserved) {\n throw new Error(\n \"Preserved provenance is already set to false, cannot fix that\"\n );\n }\n this._preservedProvenance = preserved;\n }\n\n public preservedProvenance(): boolean {\n return this._preservedProvenance;\n }\n\n private getPowerCacheKey(n: number, eps: number): string {\n const id = this.identifier;\n let key = `${id}`;\n for (let i = 1; i < n; i++) key += `+${id}`;\n return `${key}@${eps}`;\n }\n\n /**\n * Efficiently computes this PMF convolved with itself `n` times.\n * Uses exponentiation by squaring to reduce total convolutions.\n * n must be a positive integer.\n * *\n * * NOTE: This folds multiple independent attacks into a single PMF.\n * As a result, The power() method causes a loss of data provenance.\n * This is ONLY SAFE if you are trying to calculate masses.\n * If you want to query any atLeast probabilities, you should use the DiceQuery class instead without power().\n */\n power(n: number, eps = this.epsilon): PMF {\n if (!Number.isInteger(n) || n <= 0) {\n throw new Error(\"power(n): n must be a positive integer\");\n }\n if (n === 1) return this;\n\n const epsilon = eps ?? this.epsilon;\n\n const key = this.getPowerCacheKey(n, epsilon);\n if (cacheEnabled) {\n const cached = pmfCache?.get(key);\n if (cached) return cached;\n }\n\n // Start from the base PMF and accumulate n-1 additional powers\n let base: PMF = this.normalized ? this : this.normalize();\n let result: PMF = base;\n let exp = n - 1;\n\n while (exp > 0) {\n if (exp & 1) {\n result = result.convolve(base, epsilon);\n }\n exp >>= 1;\n if (exp > 0) {\n base = base.convolve(base, epsilon);\n }\n }\n\n result.setPreservedProvenance(false);\n if (cacheEnabled) {\n pmfCache?.set(key, result);\n }\n return result;\n }\n\n /*\n * Helper for chaining multiple identical attacks\n */\n replicate(n: number): PMF[] {\n if (!Number.isInteger(n) || n <= 0) {\n throw new Error(\"combineN(n): n must be a positive integer\");\n }\n if (n === 1) return [this];\n return Array.from({ length: n }, () => this);\n }\n\n mass(): number {\n if (this._totalMass === undefined) {\n let totalProbabilityMass = 0;\n for (const { p } of this.map.values()) {\n totalProbabilityMass += p;\n }\n this._totalMass = totalProbabilityMass;\n }\n return this._totalMass;\n }\n\n outcomeMass(outcome: string): number {\n let totalProbabilityMass = 0;\n for (const { p, count } of this.map.values()) {\n totalProbabilityMass += p * ((count[outcome] as number) ?? 0);\n }\n return totalProbabilityMass;\n }\n\n // Helper for testing\n faceTotal(): number {\n return [...this.map.keys()].reduce((sum, key) => sum + key, 0);\n }\n\n normalize(): PMF {\n if (this.normalized) return this;\n const normalizationFactor = this.mass();\n if (normalizationFactor === 0) return this;\n\n const normalizedMap = new Map<number, Bin>();\n for (const [damageValue, probabilityBin] of this.map) {\n const normalizedProbability = probabilityBin.p / normalizationFactor;\n const normalizedCount: OutcomeLabelMap = {};\n\n for (const labelKey in probabilityBin.count) {\n normalizedCount[labelKey] =\n (probabilityBin.count[labelKey] as number) / normalizationFactor;\n }\n\n let normalizedAttributes: OutcomeLabelMap | undefined;\n if (probabilityBin.attr) {\n normalizedAttributes = {};\n for (const labelKey in probabilityBin.attr) {\n normalizedAttributes[labelKey] =\n (probabilityBin.attr[labelKey] as number) / normalizationFactor;\n }\n }\n\n normalizedMap.set(damageValue, {\n p: normalizedProbability,\n count: normalizedCount,\n attr: normalizedAttributes,\n });\n }\n return new PMF(normalizedMap, this.epsilon, true, this.identifier);\n }\n\n /**\n * Returns a copy with negligible probabilities removed (p < eps).\n * If keepFinalBin is true, the bin with the largest key is always kept,\n * even if its probability is below eps. count/attr submaps are still cleaned.\n */\n compact(eps = this.epsilon, keepFinalBin = false): PMF {\n let maxKey = -Infinity;\n if (keepFinalBin) {\n for (const key of this.map.keys()) {\n if (key > maxKey) maxKey = key;\n }\n }\n\n const compactedMap = new Map<number, Bin>();\n\n for (const [damageValue, probabilityBin] of this.map) {\n const shouldKeep =\n probabilityBin.p >= eps || (keepFinalBin && damageValue === maxKey);\n\n if (!shouldKeep) continue;\n\n // Clean up count entries below epsilon (mutates the bin like your original)\n for (const labelKey in probabilityBin.count) {\n if (Math.abs(probabilityBin.count[labelKey] || 0) < eps) {\n delete probabilityBin.count[labelKey];\n }\n }\n\n // Clean up attr entries below epsilon\n if (probabilityBin.attr) {\n for (const labelKey in probabilityBin.attr) {\n if (Math.abs(probabilityBin.attr[labelKey] || 0) < eps) {\n delete probabilityBin.attr[labelKey];\n }\n }\n if (Object.keys(probabilityBin.attr).length === 0) {\n probabilityBin.attr = undefined;\n }\n }\n\n compactedMap.set(damageValue, probabilityBin);\n }\n\n return new PMF(compactedMap, eps, this.normalized, this.identifier);\n }\n\n // Note: The \"support\" of a PMF is the set of all non-zero probability outcomes.\n // This returns all damage values with non-zero probability, sorted ascending.\n support(): number[] {\n if (this._support === undefined) {\n this._support = [...this.map.keys()].sort((a, b) => a - b);\n }\n return this._support!;\n }\n\n // Minimum possible damage value.\n min(): number {\n if (this._min === undefined) {\n const support = this.support();\n this._min = support.length > 0 ? support[0] : 0;\n }\n return this._min;\n }\n\n // Maximum possible damage value.\n max(): number {\n if (this._max === undefined) {\n const support = this.support();\n this._max = support.length > 0 ? support[support.length - 1] : 0;\n }\n return this._max;\n }\n\n /**\n * Returns the expected (mean) damage value.\n * Cached for performance since this requires iterating through all bins.\n */\n mean(): number {\n if (this._mean === undefined) {\n let totalSum = 0;\n for (const [damageValue, probabilityBin] of this.map) {\n totalSum += damageValue * probabilityBin.p;\n }\n this._mean = totalSum;\n }\n return this._mean;\n }\n\n /**\n * Returns the variance of the damage distribution.\n * Cached for performance since this requires mean calculation plus iteration.\n */\n variance(): number {\n if (this._variance === undefined) {\n const meanValue = this.mean();\n let varianceSum = 0;\n for (const [damageValue, probabilityBin] of this.map) {\n const deviationFromMean = damageValue - meanValue;\n varianceSum += deviationFromMean * deviationFromMean * probabilityBin.p;\n }\n this._variance = varianceSum;\n }\n return this._variance;\n }\n\n /**\n * Returns the standard deviation of the damage distribution.\n */\n stdev(): number {\n if (this._stdev === undefined) {\n this._stdev = Math.sqrt(this.variance());\n }\n return this._stdev;\n }\n\n private static mergeInto(\n destinationMap: Map<number, Bin>,\n damageValue: number,\n binToAdd: Bin\n ) {\n const existingBin = destinationMap.get(damageValue);\n if (!existingBin) {\n destinationMap.set(damageValue, {\n p: binToAdd.p,\n count: { ...binToAdd.count },\n attr: binToAdd.attr ? { ...binToAdd.attr } : undefined,\n });\n return;\n }\n\n existingBin.p += binToAdd.p;\n\n for (const labelKey in binToAdd.count) {\n existingBin.count[labelKey] =\n (existingBin.count[labelKey] || 0) +\n (binToAdd.count[labelKey] as number);\n }\n\n if (binToAdd.attr) {\n if (!existingBin.attr) {\n existingBin.attr = {};\n }\n for (const labelKey in binToAdd.attr) {\n existingBin.attr[labelKey] =\n (existingBin.attr[labelKey] || 0) +\n (binToAdd.attr[labelKey] as number);\n }\n }\n }\n\n // Convenience method\n add(other: PMF): PMF {\n return this.addScaled(other, 1);\n }\n\n /**\n * Returns a new PMF with a scaled branch added to this one.\n * The branch PMF is scaled by the given probability before merging\n * This will be very useful for conditional effects and for being\n * able to model \"I can probably have this opportunity attack 40% of rounds\"\n * Example: `pmf.addScaled(critBranch, 0.05)` → PMF including 5% crit outcomes\n */\n addScaled(branch: PMF, probability: number): PMF {\n if (probability === 0) return this;\n\n const resultMap = new Map<number, Bin>();\n for (const [dmg, bin] of this.map) {\n resultMap.set(dmg, {\n p: bin.p,\n count: { ...bin.count },\n attr: bin.attr ? { ...bin.attr } : undefined,\n });\n }\n\n for (const [damageValue, probabilityBin] of branch.map) {\n const scaledCount: OutcomeLabelMap = {};\n for (const k in probabilityBin.count) {\n scaledCount[k] = probability * (probabilityBin.count[k] as number);\n }\n\n let scaledAttributes: OutcomeLabelMap | undefined;\n if (probabilityBin.attr) {\n scaledAttributes = {};\n for (const k in probabilityBin.attr) {\n scaledAttributes[k] =\n probability * (probabilityBin.attr[k] as number);\n }\n }\n\n PMF.mergeInto(resultMap, damageValue, {\n p: probability * probabilityBin.p,\n count: scaledCount,\n attr: scaledAttributes,\n });\n }\n\n return new PMF(\n resultMap,\n this.epsilon,\n false,\n `${this.identifier}+scaled(${branch.identifier},${probability})`\n );\n }\n\n scaleMass(factor: number): PMF {\n if (factor === 1) return this;\n\n const scaledMap = new Map<number, Bin>();\n for (const [damageValue, probabilityBin] of this.map) {\n const scaledCount: OutcomeLabelMap = {};\n for (const labelKey in probabilityBin.count) {\n scaledCount[labelKey] =\n (probabilityBin.count[labelKey] as number) * factor;\n }\n\n let scaledAttributes: OutcomeLabelMap | undefined;\n if (probabilityBin.attr) {\n scaledAttributes = {};\n for (const labelKey in probabilityBin.attr) {\n scaledAttributes[labelKey] =\n (probabilityBin.attr[labelKey] as number) * factor;\n }\n }\n\n scaledMap.set(damageValue, {\n p: probabilityBin.p * factor,\n count: scaledCount,\n attr: scaledAttributes,\n });\n }\n return new PMF(\n scaledMap,\n this.epsilon,\n false,\n `scale(${this.identifier},${factor})`\n );\n }\n\n mapDamage(damageTransformFunction: (damageValue: number) => number): PMF {\n const transformedMap = new Map<number, Bin>();\n for (const [originalDamage, probabilityBin] of this.map) {\n const transformedDamage = damageTransformFunction(originalDamage);\n PMF.mergeInto(transformedMap, transformedDamage, {\n p: probabilityBin.p,\n count: { ...probabilityBin.count },\n attr: probabilityBin.attr ? { ...probabilityBin.attr } : undefined,\n });\n }\n return new PMF(\n transformedMap,\n this.epsilon,\n this.normalized,\n `map(${this.identifier})`\n );\n }\n\n scaleDamage(\n factor: number,\n rounding: \"floor\" | \"round\" | \"ceil\" = \"floor\"\n ): PMF {\n const roundFunction =\n rounding === \"round\"\n ? Math.round\n : rounding === \"ceil\"\n ? Math.ceil\n : Math.floor;\n return this.mapDamage((damageValue) => roundFunction(damageValue * factor));\n }\n\n private getPMFCombineCacheKey(\n p1: PMF,\n p2: PMF,\n eps: number,\n raw: boolean\n ): string {\n const [id1, id2] = [p1.identifier, p2.identifier].sort();\n\n // tiny fingerprints so keys change if the underlying numbers changed\n const fp = (x: PMF) => {\n // robust + cheap: mass + size + face sum\n const m = x.mass().toFixed(12);\n const n = x.map.size;\n let faceSum = 0;\n for (const k of x.map.keys()) faceSum += k;\n return `${m}|${n}|${faceSum}`;\n };\n\n return `v4:${raw ? \"RAW\" : \"N\"}:${id1}+${id2}@${eps}|${fp(p1)}|${fp(p2)}`;\n }\n\n convolve(other: PMF, eps?: number, raw = false): PMF {\n const epsilon = eps ?? this.epsilon;\n\n // Normalize-by-value on non-raw path\n const norm = (x: PMF) =>\n raw ? x : Math.abs(x.mass() - 1) <= epsilon ? x : x.normalize();\n const A0 = norm(this);\n const B0 = norm(other);\n\n const [A, B] = A0.identifier <= B0.identifier ? [A0, B0] : [B0, A0];\n const cacheKey = this.getPMFCombineCacheKey(A, B, epsilon, raw);\n const cached = pmfCache?.get(cacheKey);\n if (cached) return cached;\n\n const combinedMap = new Map<number, Bin>();\n for (const [aVal, aBin] of A.map) {\n for (const [bVal, bBin] of B.map) {\n const p = aBin.p * bBin.p;\n const dmg = aVal + bVal;\n\n const count: OutcomeLabelMap = {};\n for (const k in aBin.count)\n count[k] = (count[k] || 0) + (aBin.count[k] as number) * bBin.p;\n for (const k in bBin.count)\n count[k] = (count[k] || 0) + (bBin.count[k] as number) * aBin.p;\n\n let attr: OutcomeLabelMap | undefined;\n if (aBin.attr || bBin.attr) {\n attr = {};\n if (aBin.attr)\n for (const k in aBin.attr)\n attr[k] = (attr[k] || 0) + (aBin.attr[k] as number) * bBin.p;\n if (bBin.attr)\n for (const k in bBin.attr)\n attr[k] = (attr[k] || 0) + (bBin.attr[k] as number) * aBin.p;\n }\n\n PMF.mergeInto(combinedMap, dmg, { p, count, attr });\n }\n }\n\n let result = new PMF(\n combinedMap,\n epsilon,\n !raw,\n `${A.identifier}${raw ? \"*\" : \"+\"}${B.identifier}`\n );\n\n // Enforce mass invariant: mass(out) = (raw? A.mass():1) * (raw? B.mass():1)\n const mExp = (raw ? A.mass() : 1) * (raw ? B.mass() : 1);\n const mGot = result.mass();\n if (mExp !== 0 && Math.abs(mGot - mExp) > epsilon) {\n result = result.scaleMass(mExp / mGot);\n }\n if (!raw && Math.abs(result.mass() - 1) > epsilon)\n result = result.normalize();\n\n pmfCache?.set(cacheKey, result);\n return result;\n }\n\n // 3) Nice wrapper so you can call pmf.combineRaw(other)\n combineRaw(other: PMF, eps?: number): PMF {\n return this.convolve(other, eps, true);\n }\n\n // Collapse repeated identical PMFs using power() and return a sorted list\n // Temporarily disabled for now. This was used for a performance optimization, but can lose data provenance.\n // private static collapseIdentical(pmfList: PMF[], eps: number): PMF[] {\n // const grouped = new Map<string, { pmf: PMF; count: number }>();\n // for (const pmf of pmfList) {\n // const id = pmf.identifier;\n // const g = grouped.get(id);\n // if (g) g.count++;\n // else grouped.set(id, { pmf, count: 1 });\n // }\n\n // if (grouped.size >= pmfList.length) return pmfList;\n\n // const collapsed: PMF[] = [];\n // for (const { pmf, count } of grouped.values()) {\n // collapsed.push(count > 1 ? pmf.power(count, eps) : pmf);\n // }\n\n // // Stable order for better cache locality\n // collapsed.sort((a, b) =>\n // a.identifier < b.identifier ? -1 : a.identifier > b.identifier ? 1 : 0\n // );\n // return collapsed;\n // }\n\n // Reduce a list of PMFs by left-folding convolve() with the given eps\n private static reduceConvolveLeft(pmfList: PMF[], eps: number): PMF {\n let result = pmfList[0];\n for (let i = 1; i < pmfList.length; i++) {\n result = result.convolve(pmfList[i], eps);\n }\n return result;\n }\n\n /**\n * Convolves multiple PMFs using linear convolution with automatic caching.\n * Uses a left-to-right accumulation approach for maximum cache reuse.\n * Each convolve() call automatically uses the convolution cache for performance.\n *\n * This linear approach provides better cache hits than pairwise because:\n * - Intermediate results are more predictable and stable\n * - Similar PMF lists share common prefixes (A+B, (A+B)+C, etc.)\n * - Order-independent cache keys work better with consistent build patterns\n */\n static convolveMany(pmfList: PMF[], eps = EPS): PMF {\n if (pmfList.length === 0) return PMF.empty(eps);\n if (pmfList.length === 1) return pmfList[0];\n\n // Optimization: Group identical PMFs and use power() to collapse repeats\n // If nothing collapses, this returns the same array reference.\n // const collapsed = PMF.collapseIdentical(pmfList, eps);\n\n // Optimization: Linear combination with automatic intermediate caching\n // Whether collapsed or not, reduce via left-folded convolved()\n return PMF.reduceConvolveLeft(pmfList, eps);\n }\n\n toJSON() {\n return JSON.stringify({\n bins: [...this.map.entries()],\n normalized: this.normalized,\n identifier: this.identifier,\n });\n }\n\n static fromJSON(jsonData: {\n bins: Array<[number, Bin]>;\n normalized?: boolean;\n identifier?: string;\n }) {\n return new PMF(\n new Map(jsonData.bins),\n EPS,\n !!jsonData.normalized,\n jsonData.identifier || \"fromJSON\"\n );\n }\n\n /**\n * Relative pruning with optional top-K floor.\n * Keeps bins with p >= epsRel * peak, always keeps min and max damage,\n * optionally guarantees at least `minBins` survivors by adding top-K.\n * Returns a new, non-normalized PMF.\n */\n prune(epsRel: number, minBins = 0): PMF {\n const size = this.map.size;\n if (size === 0) return this;\n\n // One pass: peak, min, max\n let peak = 0;\n let minDamage = Number.POSITIVE_INFINITY;\n let maxDamage = Number.NEGATIVE_INFINITY;\n for (const [dmg, bin] of this.map) {\n if (bin.p > peak) peak = bin.p;\n if (dmg < minDamage) minDamage = dmg;\n if (dmg > maxDamage) maxDamage = dmg;\n }\n if (peak === 0)\n return new PMF(new Map(this.map), epsRel, false, this.identifier);\n\n const thresh = epsRel * peak;\n const entries = [...this.map.entries()];\n\n // Protect endpoints\n const survivorsByDmg = new Map<number, Bin>();\n const protect = (d: number) => {\n const b = this.map.get(d);\n if (b) survivorsByDmg.set(d, b);\n };\n protect(minDamage);\n if (maxDamage !== minDamage) protect(maxDamage);\n\n // Relative survivors\n for (const [dmg, bin] of entries) {\n if (bin.p >= thresh) survivorsByDmg.set(dmg, bin);\n }\n\n // Enforce minBins via top-K if requested\n if (minBins > 0 && survivorsByDmg.size < minBins) {\n // Sort all entries by probability desc (or replace with Quickselect for O(n))\n entries.sort((a, b) => b[1].p - a[1].p);\n for (const [dmg, bin] of entries) {\n if (!survivorsByDmg.has(dmg)) {\n survivorsByDmg.set(dmg, bin);\n if (survivorsByDmg.size >= minBins) break;\n }\n }\n }\n\n // Rebuild map, pruning tiny count/attr entries with the same threshold\n const prunedMap = new Map<number, Bin>();\n for (const [dmg, bin] of survivorsByDmg) {\n const newCount: OutcomeLabelMap = {};\n for (const k in bin.count) {\n const v = bin.count[k] as number;\n if (Math.abs(v) >= thresh) newCount[k] = v;\n }\n let newAttr: OutcomeLabelMap | undefined;\n if (bin.attr) {\n for (const k in bin.attr) {\n const v = bin.attr[k] as number;\n if (Math.abs(v) >= thresh) {\n if (!newAttr) newAttr = {};\n newAttr[k] = v;\n }\n }\n }\n prunedMap.set(dmg, { p: bin.p, count: newCount, attr: newAttr });\n }\n\n // Return non-normalized PMF\n return new PMF(prunedMap, epsRel, false, `prune(${this.identifier})`);\n }\n\n /** NEW - REVIEW IF THESE ARE USEFUL OR DUPLCIATIVE? */\n /** Probability mass at exactly x. */\n pAt(x: number): number {\n return this.map.get(x)?.p ?? 0;\n }\n\n /** Dense integer support from min..max (inclusive).\n * Useful for showing empty bars in charts.\n */\n denseSupport(): number[] {\n const s = this.support();\n if (s.length === 0) return [];\n const lo = Math.min(...s),\n hi = Math.max(...s);\n return Array.from({ length: hi - lo + 1 }, (_, i) => lo + i).sort(\n (a, b) => a - b\n );\n }\n\n /** CDF at x: P(X ≤ x). */\n cdfAt(x: number): number {\n let acc = 0;\n for (const [val, bin] of this.map) if (val <= x) acc += bin.p;\n return acc;\n }\n\n /** Quantile / inverse CDF for p in [0,1]. Returns smallest x with CDF ≥ p. */\n quantile(p: number): number {\n if (this.map.size === 0) return 0;\n const s = this.support().sort((a, b) => a - b);\n let acc = 0;\n for (const x of s) {\n acc += this.pAt(x);\n if (acc >= p) return x;\n }\n return s[s.length - 1];\n }\n\n /** Get outcome probability at specific damage value. */\n outcomeAt(damage: number, outcome: string): number {\n return (this.map.get(damage)?.count[outcome] as number) ?? 0;\n }\n\n /** Get all outcome types present in this PMF. */\n outcomes(): string[] {\n const outcomeSet = new Set<string>();\n for (const [, bin] of this.map) {\n for (const outcome in bin.count) {\n if ((bin.count[outcome] as number) > 0) {\n outcomeSet.add(outcome);\n }\n }\n }\n return Array.from(outcomeSet).sort();\n }\n\n /** Get total probability of an outcome across all damage values. */\n outcomeProbability(outcome: string): number {\n let total = 0;\n for (const [, bin] of this.map) {\n total += (bin.count[outcome] as number) ?? 0;\n }\n return total;\n }\n\n /** Get damage attribution for an outcome at specific damage value. */\n outcomeAttributionAt(damage: number, outcome: string): number {\n return (this.map.get(damage)?.attr?.[outcome] as number) ?? 0;\n }\n\n /** Get all outcome data at specific damage value. */\n binAt(damage: number): {\n p: number;\n count: Record<string, number>;\n attr?: Record<string, number>;\n } | null {\n const bin = this.map.get(damage);\n if (!bin) return null;\n\n return {\n p: bin.p,\n count: { ...bin.count } as Record<string, number>,\n attr: bin.attr ? ({ ...bin.attr } as Record<string, number>) : undefined,\n };\n }\n\n /** Check if outcome exists in this PMF. */\n hasOutcome(outcome: string): boolean {\n for (const [, bin] of this.map) {\n if (((bin.count[outcome] as number) ?? 0) > 0) {\n return true;\n }\n }\n return false;\n }\n\n tailProbGE(t: number): number {\n let s = 0;\n for (const [x, rec] of this) {\n const p = typeof rec === \"number\" ? rec : rec.p;\n if (p > 0 && x >= t) s += p;\n }\n return s;\n }\n\n tailProbGT(t: number): number {\n let s = 0;\n for (const [x, rec] of this) {\n if (x > t) s += rec.p;\n }\n return s;\n }\n\n /**\n * Returns a new PMF containing only bins where the specified outcome has non-zero probability.\n * This creates a marginal distribution for the given outcome type, with probabilities\n * scaled to represent the unconditional mass attributable to that outcome.\n */\n filterOutcome(outcome: string): PMF {\n const filteredMap = new Map<number, Bin>();\n\n for (const [damageValue, bin] of this.map) {\n const outcomeCount = (bin.count[outcome] as number) ?? 0;\n\n // total paths that reached this bin (sum across labels)\n const totalCount = Object.values(bin.count ?? {}).reduce(\n (a, b) => (a ?? 0) + ((b as number) ?? 0),\n 0\n );\n\n if (outcomeCount > 0 && totalCount !== undefined && totalCount > 0) {\n // proportion of this bin's mass attributable to the outcome\n const proportion = outcomeCount / totalCount;\n\n // downweight p to the unconditional mass from the outcome only\n const newP = bin.p * proportion;\n\n const newCount: OutcomeLabelMap = { [outcome]: outcomeCount };\n\n let newAttr: OutcomeLabelMap | undefined;\n if (bin.attr && bin.attr[outcome] !== undefined) {\n // If attr is a count-like accumulator, scale it too.\n // If attr is already per-outcome only, you can just carry it over.\n newAttr = { [outcome]: (bin.attr[outcome] as number) * proportion };\n }\n\n filteredMap.set(damageValue, {\n p: newP,\n count: newCount,\n attr: newAttr,\n });\n }\n }\n\n return new PMF(\n filteredMap,\n this.epsilon,\n false, // don't normalize by default\n `filter(${this.identifier},${outcome})`\n );\n }\n /**\n * Calculates probabilities for first-success outcomes across n independent attempts.\n *\n * @param pSuccess - Total probability of any success on a single attempt.\n * @param pSpecial - Probability of a specific subset of successes (e.g., critical success).\n * @param n - Number of independent attempts.\n *\n * Returns:\n * - pSpecificSuccess: Probability that the first success was of the \"special\" type\n * - pGeneralSuccess: Probability that the first success was of the non-special type\n * - pNone: Probability that no successes occurred\n * - pAny: Probability that at least one success occurred\n */\n public static firstSuccessWeights(\n pSuccess: number,\n pSpecial: number,\n n: number\n ) {\n const pFail = 1 - pSuccess;\n const pFailAll = Math.pow(pFail, n);\n\n // Probability of at least one success\n const pAny = 1 - pFailAll;\n\n // Avoid divide-by-zero if pSuccess is 0\n const denom = pSuccess === 0 ? 1 : pSuccess;\n\n // Breakdown of first success type\n const pSpecificSuccess = (pSpecial * pAny) / denom;\n const pGeneralSuccess = ((pSuccess - pSpecial) * pAny) / denom;\n\n const pNone = 1 - pSpecificSuccess - pGeneralSuccess; // Should equal pFailAll\n\n return { pSpecificSuccess, pGeneralSuccess, pNone, pAny };\n }\n\n mapValues(\n f: (v: number) => number,\n eps: number = EPS,\n opts?: { rounding?: Rounding; preserveCounts?: boolean }\n ): PMF {\n const rounding = opts?.rounding ?? \"none\";\n const preserveCounts = opts?.preserveCounts ?? true;\n\n const round = (x: number) =>\n rounding === \"floor\"\n ? Math.floor(x)\n : rounding === \"ceil\"\n ? Math.ceil(x)\n : rounding === \"round\"\n ? Math.round(x)\n : x;\n\n // Accumulate probs and merged counts\n const probs = new Map<number, number>();\n const counts = new Map<number, Record<string, number>>();\n\n for (const [v, rec] of this) {\n if (Math.abs(rec.p) < eps) continue;\n const u = round(f(v));\n probs.set(u, (probs.get(u) ?? 0) + rec.p);\n\n if (preserveCounts) {\n // Merge counts if present\n const rec = this.map.get(v);\n const src = typeof rec === \"number\" ? undefined : rec?.count;\n if (src) {\n const dest = counts.get(u) ?? {};\n for (const k in src) {\n dest[k] = (dest[k] ?? 0) + (src[k] as number);\n }\n counts.set(u, dest);\n }\n }\n }\n\n // Build PMF with merged counts, then normalize\n const internal = new Map<number, Bin>();\n for (const [u, p] of probs) {\n internal.set(u, { p, count: counts.get(u) ?? {} });\n }\n // Normalize via pmfFromMap to keep one source of truth\n return PMF.fromMap(\n new Map(Array.from(internal, ([u, b]) => [u, b.p] as [number, number])),\n eps\n );\n }\n\n static fromMap(\n m: Map<number, number>,\n eps: number = EPS,\n { requireIntegerValues = true }: { requireIntegerValues?: boolean } = {}\n ): PMF {\n const filtered: Array<[number, number]> = [];\n for (const [v, p] of m) {\n if (!Number.isFinite(v) || !Number.isFinite(p)) continue;\n if (p <= 0 || Math.abs(p) < eps) continue;\n if (requireIntegerValues && !Number.isInteger(v)) {\n throw new Error(`fromMap: non-integer outcome ${v}`);\n }\n filtered.push([v, p]);\n }\n\n if (filtered.length === 0) {\n throw new Error(\"fromMap: empty or invalid input map\");\n }\n\n // Kahan sum for stability\n let sum = 0;\n let c = 0;\n for (const [, p] of filtered) {\n const y = p - c;\n const t = sum + y;\n c = t - sum - y;\n sum = t;\n }\n if (sum <= 0) throw new Error(\"pmfFromMap: probabilities sum to 0\");\n\n filtered.sort((a, b) => a[0] - b[0]);\n\n const internal = new Map<number, Bin>();\n for (const [v, p] of filtered) {\n internal.set(v, { p: p / sum, count: {} }); // keep count object present for consistency\n }\n return new PMF(internal, eps);\n }\n\n query(): DiceQuery {\n return new DiceQuery(this);\n }\n}\n","// dice.ts (internal)\n\nimport type {\n Bin,\n DamageDistribution,\n OutcomeLabelMap,\n OutcomeType,\n} from \"../common/types\";\nimport { EPS } from \"../common/types\";\nimport { PMF } from \"../pmf/pmf\";\n\n/**\n * @internal\n */\nexport class Dice {\n private readonly faces: DamageDistribution = {};\n public privateData: Record<string, any> = {};\n private outcomeData: Record<OutcomeType, DamageDistribution> = {} as Record<\n OutcomeType,\n DamageDistribution\n >;\n private hasHitDistributionCalculated = false;\n public identifier?: string;\n\n constructor(x: number = 0) {\n if (x <= 0) return;\n for (let i = 1; i <= x; i++) {\n this.faces[i] = 1;\n }\n }\n\n getOutcomeDistribution(key: OutcomeType): DamageDistribution | undefined {\n if (key === \"hit\") {\n this.ensureHitDistribution();\n }\n\n return this.outcomeData[key];\n }\n\n getFullOutcomeDistribution(): Record<\n OutcomeType,\n DamageDistribution | undefined\n > {\n return { ...this.outcomeData };\n }\n\n setOutcomeDistribution(\n key: OutcomeType,\n data: DamageDistribution | undefined\n ): void {\n if (data) {\n this.outcomeData[key] = data;\n } else {\n delete this.outcomeData[key];\n }\n }\n\n hasOutcomeData(key: OutcomeType): boolean {\n if (key === \"hit\") {\n this.ensureHitDistribution();\n }\n const data = this.outcomeData[key];\n return data !== undefined && Object.keys(data).length > 0;\n }\n\n getOutcomeCount(key: OutcomeType, face: number): number {\n return this.outcomeData[key]?.[face] ?? 0;\n }\n\n getAverage(key: OutcomeType): number {\n const distribution = this.getOutcomeDistribution(key);\n if (!distribution) return 0;\n // TODO caching opportunity\n\n const totalCount = Object.values(distribution).reduce(\n (sum, count) => sum + count,\n 0\n );\n const expectedDamage = Object.entries(distribution).reduce(\n (sum, [damage, count]) => sum + Number(damage) * count,\n 0\n );\n if (totalCount === 0) return 0;\n return expectedDamage / totalCount;\n }\n\n // TODO this can be private later if we change how testing works\n calculateHitDistribution(): DamageDistribution {\n const hitValues: DamageDistribution = {};\n\n for (const [face, totalCount] of Object.entries(this.faces)) {\n const numFace = Number(face);\n let hitCount = totalCount;\n\n for (const outcomeType of [\n \"crit\",\n \"missNone\",\n \"missDamage\",\n \"saveHalf\",\n \"saveFail\",\n \"pc\",\n ] as Partial<OutcomeType>[]) {\n const distribution = this.getOutcomeDistribution(outcomeType);\n if (distribution && distribution[numFace]) {\n hitCount -= distribution[numFace];\n }\n }\n\n // Zero damage should not be counted as hits - they represent misses\n if (numFace === 0) {\n hitCount = 0;\n }\n\n //WARNING: This is checking for the bug in old inclusion-exclusion logic.\n if (hitCount < 0) {\n console.error(\"hitCount is <=0?\", face, totalCount, hitCount);\n hitCount = 0;\n }\n hitValues[numFace] = hitCount;\n }\n\n return hitValues;\n }\n\n private ensureHitDistribution(): void {\n if (!this.hasHitDistributionCalculated) {\n const hitValues = this.calculateHitDistribution();\n this.setOutcomeDistribution(\"hit\", hitValues);\n this.hasHitDistributionCalculated = true;\n }\n }\n\n // PRIVATE FUNCTIONS\n\n private binaryOp(\n other: Dice | number,\n op: (a: number, b: number) => number,\n diceConstructor?: () => Dice\n ): Dice {\n const result = diceConstructor ? diceConstructor() : new Dice();\n\n const isScalar = typeof other === \"number\";\n const keys1 = this.keys();\n\n for (const key1 of keys1) {\n const value1 = this.faces[key1]!;\n\n if (isScalar) {\n const resultKey = op(key1, other as number);\n result.increment(resultKey, value1);\n } else {\n const keys2 = other.keys();\n for (const key2 of keys2) {\n const value2 = other.faces[key2]!;\n const resultKey = op(key1, key2);\n result.increment(resultKey, value1 * value2);\n }\n }\n }\n\n return result;\n }\n\n private removeFaces(facesToRemove: number[]): Dice {\n const result = new Dice();\n\n for (const [key, value] of Object.entries(this.faces)) {\n const numKey = Number(key);\n if (!facesToRemove.includes(numKey)) {\n result.faces[numKey] = value;\n }\n }\n\n result.privateData = { ...this.privateData };\n result.outcomeData = { ...this.outcomeData };\n return result;\n }\n\n // PUBLIC FUNTIONS\n\n getFaceEntries(): [number, number][] {\n return Object.entries(this.faces).map(([k, v]) => [Number(k), v]);\n }\n\n getFaceMap(): DamageDistribution {\n return { ...this.faces };\n }\n\n get(face: number): number {\n return this.faces[face] ?? 0;\n }\n\n keys(): number[] {\n return Object.keys(this.faces).map(Number);\n }\n\n values(): number[] {\n return Object.values(this.faces);\n }\n\n total(): number {\n return Object.values(this.faces).reduce((sum, value) => sum + value, 0);\n }\n\n public setFace(key: number, value: number): void {\n this.faces[key] = value;\n }\n\n public static scalar(value: number): Dice {\n const result = new Dice();\n result.increment(value, 1);\n return result;\n }\n\n public maxFace(): number {\n const numericKeys = this.keys();\n\n if (numericKeys.length === 0) {\n throw new Error(\"No numeric faces found\");\n }\n\n return Math.max(...numericKeys);\n }\n\n public minFace(): number {\n const numericKeys = this.keys();\n\n if (numericKeys.length === 0) {\n throw new Error(\"No numeric faces found\");\n }\n\n return Math.min(...numericKeys);\n }\n\n public increment(face: number, count: number): void {\n const current = this.faces[face] || 0;\n this.faces[face] = current + count;\n }\n\n public normalize(scalar: number): Dice {\n const result = new Dice();\n\n for (const [face, count] of Object.entries(this.faces)) {\n result.faces[Number(face)] = count * scalar;\n }\n\n result.privateData = { ...this.privateData };\n result.outcomeData = { ...this.outcomeData };\n return result;\n }\n\n // OPERATIONS\n\n public add(other: Dice | number): Dice {\n return this.binaryOp(other, (a, b) => a + b);\n }\n\n public subtract(other: Dice | number): Dice {\n return this.binaryOp(other, (a, b) => a - b);\n }\n\n public conditionalApply(other: Dice | number): Dice {\n return this.binaryOp(other, (a, b) => (a === 0 ? 0 : 1) * b);\n }\n\n public multiply(other: Dice | number): Dice {\n return this.binaryOp(other, (a, b) => a * b);\n }\n\n public addNonZero(other: Dice | number): Dice {\n return this.binaryOp(other, (a, b) => (a !== 0 ? a + b : a));\n }\n\n public eq(other: Dice | number): Dice {\n return this.binaryOp(other, (a, b) => (a === b ? 1 : 0));\n }\n\n public max(other: Dice | number): Dice {\n return this.binaryOp(other, (a, b) => Math.max(a, b));\n }\n\n public min(other: Dice | number): Dice {\n return this.binaryOp(other, (a, b) => Math.min(a, b));\n }\n\n public advantage(): Dice {\n return this.max(this);\n }\n\n public ge(other: Dice | number): Dice {\n return this.binaryOp(other, (a, b) => (a >= b ? 0 : 1));\n }\n\n public divide(other: Dice | number): Dice {\n return this.binaryOp(other, (a, b) => a / b);\n }\n\n public divideRoundUp(other: Dice | number): Dice {\n return this.binaryOp(other, (a, b) => Math.ceil(a / b));\n }\n\n public divideRoundDown(other: Dice | number): Dice {\n return this.binaryOp(other, (a, b) => Math.floor(a / b));\n }\n\n public and(other: Dice | number): Dice {\n return this.binaryOp(other, (a, b) => (a && b ? 1 : 0));\n }\n\n private checkTarget(\n other: Dice | number,\n comparisonLogic: (roll: number, target: number) => number\n ): Dice {\n const createResult = () => {\n const result = new Dice();\n result.increment(0, 0); // Success\n result.increment(1, 0); // Failure\n return result;\n };\n\n return this.binaryOp(other, comparisonLogic, createResult);\n }\n\n public dc(other: Dice | number): Dice {\n const dcCheck = (a: number, b: number) => (a >= b ? 0 : 1);\n const result = this.checkTarget(other, dcCheck);\n // Mark this as a DC check (save mechanic) for proper attribute assignment\n result.privateData.isDCCheck = true;\n return result;\n }\n\n public ac(other: Dice | number): Dice {\n const acCheck = (a: number, b: number) => (a >= b ? a : 0);\n return this.checkTarget(other, acCheck);\n }\n\n public deleteFace(face: number): Dice {\n const result = new Dice();\n\n for (const [key, value] of Object.entries(this.faces)) {\n const numKey = Number(key);\n if (numKey !== face) {\n result.increment(numKey, value);\n }\n }\n\n result.privateData = { ...this.privateData };\n result.outcomeData = { ...this.outcomeData };\n return result;\n }\n\n public reroll(toReroll: Dice | number): Dice {\n const rerollDice =\n typeof toReroll === \"number\" ? Dice.scalar(toReroll) : toReroll;\n\n const removed = this.removeFaces(rerollDice.keys());\n let result = new Dice();\n\n for (const face of this.keys()) {\n const wasRerolled = rerollDice.keys().includes(face);\n result = result.combine(removed);\n if (wasRerolled) {\n result = result.combine(this);\n }\n }\n\n return result;\n }\n\n // This is not addition and not rolling two dice at once.\n // Instead, it’s mixing two distributions into a single weighted die.\n public combine(other: Dice | number): Dice {\n if (typeof other === \"number\") {\n other = Dice.scalar(other);\n }\n\n // Start by copying \"other\" into a new Dice object\n const result = new Dice();\n for (const [key, value] of Object.entries(other.faces)) {\n result.faces[Number(key)] = value;\n }\n\n // Build the \"except\" dice and add faces from `this` to result\n const except = new Dice();\n for (const [key, value] of Object.entries(this.faces)) {\n const numKey = Number(key);\n result.increment(numKey, value);\n\n // If the key did not already exist in `other`, we remove it from `except`\n if (!(numKey in other.faces)) {\n except.increment(numKey, value); // still tracked in except\n }\n }\n\n result.privateData = { ...this.privateData, except: other };\n result.outcomeData = { ...this.outcomeData };\n return result;\n }\n\n public combineInPlace(other: Dice): void {\n for (const [key, value] of Object.entries(other.faces)) {\n const numKey = Number(key);\n const current = this.faces[numKey] || 0;\n this.faces[numKey] = current + value;\n }\n }\n\n public percent(): DamageDistribution {\n const total = this.total();\n const result: DamageDistribution = {};\n\n for (const [face, count] of Object.entries(this.faces)) {\n result[Number(face)] = count / total;\n }\n\n return result;\n }\n\n public average(): number {\n const total = this.total();\n if (total === 0) return 0;\n\n let sum = 0;\n for (const [key, value] of Object.entries(this.faces)) {\n sum += Number(key) * value;\n }\n\n return sum / total;\n }\n\n /*\n * Convert dice to PMF using OutcomeType labels directly from damage distribution.\n * This is much cleaner than the original complex distribution conversion.\n */\n public toPMF(numEpsilon: number = EPS): PMF {\n const total = this.total();\n if (total === 0) return PMF.empty(numEpsilon);\n\n // Ensure hit distribution is calculated before using it\n this.ensureHitDistribution();\n\n const map = new Map<number, Bin>();\n\n // Outcome distributions (counts, not probabilities)\n const hitDistro = this.getOutcomeDistribution(\"hit\") || {};\n const critDistro = this.getOutcomeDistribution(\"crit\") || {};\n const missDistro = this.getOutcomeDistribution(\"missDamage\") || {};\n const saveDistro = this.getOutcomeDistribution(\"saveHalf\") || {};\n const pcDistro = this.getOutcomeDistribution(\"pc\") || {};\n\n let isSaveHalf = false;\n for (const halfDamage of Object.keys(saveDistro).map(Number)) {\n const fullDamage = halfDamage * 2;\n if (fullDamage > 0 && hitDistro[fullDamage]) {\n isSaveHalf = true;\n break;\n }\n }\n\n const isDCCheck = this.privateData.isDCCheck === true;\n\n const clampNonNeg = (x: number) => (x < 0 && x > -1e-15 ? 0 : x);\n\n // Process each face value\n for (const [faceStr, faceCountRaw] of Object.entries(this.getFaceMap())) {\n const face = Number(faceStr);\n const faceCount = Number(faceCountRaw);\n\n // Skip structurally present but empty bins early\n if (faceCount <= 0) continue;\n\n let p = faceCount / total;\n p = clampNonNeg(p);\n\n // Always drop exact zeros to keep PMF semantics clean\n if (!(p > 0)) continue;\n\n // Optional pruning only when epsilon is enabled\n if (numEpsilon >= 0 && p < numEpsilon) continue;\n\n const count: OutcomeLabelMap = {};\n const attr: OutcomeLabelMap = {};\n\n // Add distribution counts and attributions\n if (hitDistro[face]) {\n const c = clampNonNeg(hitDistro[face] / total);\n if (c > 0) {\n if (isSaveHalf || isDCCheck) {\n count.saveFail = c; // full damage on failed save\n attr.saveFail = clampNonNeg((face * hitDistro[face]) / total);\n } else {\n count.hit = c;\n attr.hit = clampNonNeg((face * hitDistro[face]) / total);\n }\n }\n }\n\n if (critDistro[face]) {\n const c = clampNonNeg(critDistro[face] / total);\n if (c > 0) {\n count.crit = c;\n attr.crit = clampNonNeg((face * critDistro[face]) / total);\n }\n }\n\n if (missDistro[face]) {\n const c = clampNonNeg(missDistro[face] / total);\n if (c > 0) {\n count.missDamage = c;\n attr.missDamage = clampNonNeg((face * missDistro[face]) / total);\n }\n }\n\n if (saveDistro[face]) {\n const c = clampNonNeg(saveDistro[face] / total);\n if (c > 0) {\n if (isSaveHalf) {\n count.saveHalf = c; // half damage on successful save\n attr.saveHalf = clampNonNeg((face * saveDistro[face]) / total);\n } else {\n count.saveFail = (count.saveFail ?? 0) + c; // regular fail\n attr.saveFail = clampNonNeg(\n (attr.saveFail ?? 0) + (face * saveDistro[face]) / total\n );\n }\n }\n }\n\n if (pcDistro[face]) {\n const c = clampNonNeg(pcDistro[face] / total);\n if (c > 0) {\n count.pc = c;\n attr.pc = clampNonNeg((face * pcDistro[face]) / total);\n }\n }\n\n // Handle faces with no specific distribution (missNone) for non-save and non-DC checks\n if (!isSaveHalf && !isDCCheck) {\n const distroCountRaw =\n (hitDistro[face] || 0) +\n (critDistro[face] || 0) +\n (missDistro[face] || 0) +\n (saveDistro[face] || 0) +\n (pcDistro[face] || 0);\n\n const unaccountedCount = clampNonNeg(faceCount - distroCountRaw);\n if (unaccountedCount > 0) {\n const frac = clampNonNeg(unaccountedCount / total);\n if (frac > 0) {\n count.missNone = (count.missNone ?? 0) + frac;\n // missNone does 0 damage, so no attr contribution\n }\n }\n }\n\n const bin: Bin = { p, count };\n if (Object.keys(attr).length > 0) {\n bin.attr = attr;\n }\n\n map.set(face, bin);\n }\n\n const identifier = this.identifier || \"ERROR\";\n if (identifier === \"ERROR\") {\n console.error(\"Dice identifier is undefined\", this);\n }\n\n // Normalize, drop zeros again if any snuck in, then compaction and pruning\n return new PMF(map, numEpsilon, true, identifier).compact(numEpsilon, true);\n }\n}\n\nexport type _DiceInternal = never;\n","import { LRUCache } from \"../common/lru-cache\";\nimport type { OutcomeType } from \"../common/types\";\nimport type { PMF } from \"../pmf/pmf\";\nimport { Dice } from \"./dice\";\n\ntype DiceOperation = ((this: Dice, other: Dice | number) => Dice) & {\n unary?: boolean;\n};\n\n/**\n * Internal parse cache for PMFs produced from string expressions.\n * Keyed by cleaned expression (spaces stripped, lowercased) and optional `n` value.\n */\nconst parseCache = new LRUCache<string, PMF>(1000);\n\nlet cachingEnabled = true;\n\n/** Enable or disable the internal parse cache. */\nexport function setCachingEnabled(enabled: boolean): void {\n cachingEnabled = enabled;\n if (!enabled) clearParserCache();\n}\n\n/** Returns whether the internal parse cache is currently enabled. */\nexport function getCachingEnabled(): boolean {\n return cachingEnabled;\n}\n\n/** Clears the internal parse cache. */\nexport function clearParserCache(): void {\n parseCache.clear();\n}\n\n/**\n * Parse a dice expression into a PMF.\n *\n * - Expression is case-insensitive and ignores spaces.\n */\nexport function parse(expression: string, n: number = 0): PMF {\n // Check cache first if enabled\n const cleaned = expression.replace(/ /g, \"\").toLowerCase();\n\n if (cachingEnabled) {\n const cacheKey = `${cleaned}:${n}`;\n const cached = parseCache.get(cacheKey);\n if (cached) return cached;\n }\n\n const chars = [...cleaned];\n\n let result: Dice | undefined = undefined;\n try {\n result = parseExpression(chars, n);\n } catch (error) {\n throw new Error(`Cannot parse dice expression [${expression}]: ${error}`);\n }\n\n try {\n (result as any).privateData = (result as any).privateData || {};\n result.identifier = cleaned;\n } catch {}\n\n if (chars.length > 0) {\n throw new Error(\n `Unexpected token: '${chars[0]}' from expression: '${expression}'`\n );\n }\n\n // When creating the PMF, do not epsilon prune\n const resultPMF = result.toPMF(-1);\n if (cachingEnabled) {\n // store using the same cleaned key we used for lookup\n const cacheKey = `${cleaned}:${n}`;\n parseCache.set(cacheKey, resultPMF);\n }\n\n return resultPMF;\n}\n\nfunction combineDiceWithNormalization(\n dice: Dice,\n normValue: number,\n outcomeType: OutcomeType,\n currentNorm: number,\n finalResult: Dice\n): { newNorm: number; updatedResult: Dice } {\n dice = dice.normalize(currentNorm);\n finalResult = finalResult.normalize(normValue);\n finalResult.setOutcomeDistribution(outcomeType, dice.getFaceMap());\n finalResult = finalResult.combine(dice);\n return { newNorm: currentNorm * normValue, updatedResult: finalResult };\n}\n\nfunction parseExpression(arr: string[], n: number): Dice {\n const result = (() => {\n const res = parseArgument(arr, n);\n return typeof res === \"number\" ? Dice.scalar(res) : res;\n })();\n\n let op = parseOperation(arr);\n let finalResult = result;\n\n while (op != null) {\n const arg = !op.unary ? parseArgument(arr, n) : finalResult;\n\n // Handle crit (e.g. xcrit, crit)\n let crit: Dice | undefined;\n let critNorm = 1;\n if (arr[0] === \"x\" || arr[0] === \"c\") {\n const isXcrit = arr[0] === \"x\";\n if (isXcrit) assertToken(arr, \"x\");\n assertToken(arr, \"c\");\n assertToken(arr, \"r\");\n assertToken(arr, \"i\");\n assertToken(arr, \"t\");\n\n const count = isXcrit ? parseNumber(arr, n) : 1;\n\n crit = new Dice();\n for (let i = 0; i < count; i++) {\n const max = finalResult.maxFace();\n crit.setFace(max, finalResult.get(max));\n finalResult = finalResult.deleteFace(max);\n }\n\n critNorm = crit.total();\n crit = op.call(crit, parseBinaryArgument(arg, arr, n));\n\n critNorm = crit && critNorm ? crit.total() / critNorm : 1;\n }\n\n // Handle save\n let save: Dice | undefined;\n let saveNorm = 1;\n if (arr[0] === \"s\") {\n assertToken(arr, \"s\");\n assertToken(arr, \"a\");\n assertToken(arr, \"v\");\n assertToken(arr, \"e\");\n\n save = new Dice();\n const min = finalResult.minFace();\n save.increment(min > 0 ? min : 1, finalResult.get(min));\n\n saveNorm = save.total();\n finalResult = finalResult.deleteFace(min);\n save = op.call(save, parseBinaryArgument(arg, arr, n));\n saveNorm = save && saveNorm ? save.total() / saveNorm : 1;\n }\n\n // Handle half damage on hit (potent cantrip)\n let pc: Dice | undefined;\n let pcNorm = 1;\n\n if (arr.length >= 2 && arr[0] === \"p\" && arr[1] === \"c\") {\n assertToken(arr, \"p\");\n assertToken(arr, \"c\");\n\n pc = new Dice();\n const min = finalResult.minFace();\n pc.increment(min > 0 ? min : 1, finalResult.get(min));\n\n const missBefore = pc.total();\n finalResult = finalResult.deleteFace(min);\n\n pc = op.call(pc, parseBinaryArgument(arg, arr, n)).divideRoundDown(2); // parse the damage\n\n const missAfter = pc ? pc.total() : 0;\n pcNorm = missBefore ? missAfter / missBefore : 1;\n }\n\n // Handle miss\n let miss: Dice | undefined;\n let missNorm = 1;\n\n if (arr[0] === \"m\") {\n assertToken(arr, \"m\");\n assertToken(arr, \"i\");\n assertToken(arr, \"s\");\n assertToken(arr, \"s\");\n\n miss = new Dice();\n const min = finalResult.minFace();\n miss.increment(min > 0 ? min : 1, finalResult.get(min));\n\n missNorm = miss.total();\n finalResult = finalResult.deleteFace(min);\n\n miss = op.call(miss, parseBinaryArgument(arg, arr, n));\n missNorm = miss && missNorm ? miss.total() / missNorm : 1;\n }\n\n let norm = finalResult.total();\n\n finalResult = op.call(finalResult, arg);\n norm = norm ? finalResult.total() / norm : 1;\n\n // Combine dice with normalization\n if (crit) {\n const result = combineDiceWithNormalization(\n crit,\n critNorm,\n \"crit\",\n norm,\n finalResult\n );\n norm = result.newNorm;\n finalResult = result.updatedResult;\n }\n\n if (save) {\n const result = combineDiceWithNormalization(\n save,\n saveNorm,\n \"saveHalf\",\n norm,\n finalResult\n );\n norm = result.newNorm;\n finalResult = result.updatedResult;\n }\n\n if (miss) {\n const result = combineDiceWithNormalization(\n miss,\n missNorm,\n \"missDamage\",\n norm,\n finalResult\n );\n norm = result.newNorm;\n finalResult = result.updatedResult;\n }\n\n if (pc) {\n const result = combineDiceWithNormalization(\n pc,\n pcNorm,\n \"pc\",\n norm,\n finalResult\n );\n norm = result.newNorm;\n finalResult = result.updatedResult;\n }\n\n op = parseOperation(arr);\n }\n\n return finalResult;\n}\n\nfunction parseArgument(s: string[], n: number): Dice | number {\n let result = parseArgumentInternal(s, n);\n\n while (true) {\n const next = parseArgumentInternal(s, n);\n if (next === undefined) break;\n\n result = multiplyDiceByDice(result as Dice | number, next);\n }\n\n return result as Dice | number;\n}\n\nfunction multiplyDiceByDice(d1: Dice | number, d2: Dice | number): Dice {\n if (typeof d1 === \"number\") d1 = Dice.scalar(d1);\n if (typeof d2 === \"number\") d2 = Dice.scalar(d2);\n\n const result = new Dice();\n const faces: Record<number, Dice> = {};\n let normalizationFactor = 1;\n\n for (const key of d1.keys()) {\n let face: Dice;\n\n if (typeof key !== \"number\") {\n continue; // Skip invalid scalar\n }\n\n if (d2.privateData.keep) {\n // Repeat dice2 \"key\" times and apply keep\n const repeat: Dice[] = Array(key).fill(d2);\n face = opDice(repeat, d2.privateData.keep);\n } else {\n face = multiplyDice(key, d2);\n }\n\n normalizationFactor *= face.total();\n faces[key] = face;\n }\n\n for (const key of Object.keys(faces)) {\n const k = parseFloat(key); // keys from object are strings\n const face = faces[k];\n const count = d1.get(k);\n result.combineInPlace(\n face.normalize((count * normalizationFactor) / face.total())\n );\n }\n\n result.privateData.except = {};\n return result;\n}\n\nfunction multiplyDice(n: number, d: Dice): Dice {\n if (n === 0) return new Dice(0);\n if (n === 1) return d;\n\n const half = Math.floor(n / 2);\n let result = multiplyDice(half, d);\n result = result.add(result);\n\n if (n % 2 === 1) {\n result = result.add(d);\n }\n\n return result;\n}\n\nfunction opDice(diceList: Dice[], keepFn: (values: number[]) => number): Dice {\n return opDiceInternal(diceList, new Dice(), 0, [], 1, keepFn);\n}\n\nfunction opDiceInternal(\n diceList: Dice[],\n result: Dice,\n index: number,\n values: number[],\n weight: number,\n combineFn: (values: number[]) => number\n): Dice {\n if (index === diceList.length) {\n return result.combine(Dice.scalar(combineFn(values)).normalize(weight));\n }\n\n const currentDice = diceList[index];\n for (const face of currentDice.keys()) {\n values.push(face as number);\n result = opDiceInternal(\n diceList,\n result,\n index + 1,\n values,\n weight * currentDice.get(face),\n combineFn\n );\n values.pop();\n }\n\n return result;\n}\n\nfunction parseArgumentInternal(\n s: string[],\n n: number\n): Dice | number | undefined {\n if (s.length === 0) return;\n\n const c = s[0];\n\n switch (c) {\n case \"(\":\n s.shift();\n return assertToken(s, \")\", parseExpression(s, n));\n\n case \"h\":\n case \"d\":\n return parseDice(s, n);\n\n case \"k\":\n assertToken(s, \"k\");\n return parseKeep(s, n);\n\n case \"n\":\n return parseNumber(s, n);\n\n default:\n if (isDigit(c)) return parseNumber(s, n);\n return;\n }\n}\n\nfunction parseBinaryArgument(\n arg: Dice | number,\n arr: string[],\n n: number\n): Dice {\n if (arr.length >= 4 && arr[0] === \"h\" && peek(arr, \"half\")) {\n assertToken(arr, \"half\");\n\n const diceArg = typeof arg === \"number\" ? Dice.scalar(arg) : arg;\n return diceArg.divideRoundDown(2);\n }\n\n const parsed = parseArgument(arr, n);\n return typeof parsed === \"number\" ? Dice.scalar(parsed) : parsed;\n}\n\nfunction assertToken<T>(s: string[], expected: string, ret?: T): T | undefined {\n for (const ch of expected) {\n const found = s.shift();\n if (found !== ch) {\n throw new Error(`Expected character '${ch}', found '${found}'`);\n }\n }\n return ret;\n}\n\nfunction parseDice(s: string[], n: number): Dice | undefined {\n let rerollOne = false;\n\n if (peek(s, \"hd\") && peekIsNumber(s, 2)) {\n assertToken(s, \"h\");\n assertToken(s, \"d\");\n rerollOne = true;\n } else if (peek(s, \"d\") && peekIsNumber(s, 1)) {\n assertToken(s, \"d\");\n } else {\n return;\n }\n\n const sides = parseNumber(s, n);\n let result = new Dice(sides);\n\n if (rerollOne) {\n result = result.deleteFace(1).combine(result);\n }\n\n return result;\n}\n\nfunction peek(arr: string[], expected: string): boolean {\n if (expected.length > arr.length) return false;\n\n for (let i = 0; i < expected.length; i++) {\n if (arr[i] !== expected.charAt(i)) return false;\n }\n\n return true;\n}\n\nfunction peekIsNumber(arr: string[], index: number): boolean {\n if (index >= arr.length) return false;\n return isDigit(arr[index]) || arr[index] === \"n\";\n}\n\nfunction parseNumber(s: string[], n: number): number {\n let ret = \"\";\n\n while (s.length > 0 && (isDigit(s[0]) || s[0] === \"n\")) {\n const ch = s.shift()!;\n ret += ch === \"n\" ? n.toString() : ch;\n }\n\n if (ret.length === 0) {\n throw new Error(`Expected number, found: '${s[0]}'`);\n }\n\n return parseInt(ret, 10);\n}\n\nfunction isDigit(c: string): boolean {\n return c >= \"0\" && c <= \"9\";\n}\n\nfunction parseKeep(s: string[], n: number): Dice | undefined {\n let keepLowest = false;\n\n if (peek(s, \"l\")) {\n assertToken(s, \"l\");\n keepLowest = true;\n } else if (peek(s, \"h\")) {\n assertToken(s, \"h\");\n keepLowest = false;\n } else {\n return;\n }\n\n const keepCount = parseNumber(s, n);\n const result = parseArgumentInternal(s, n);\n\n if (result instanceof Dice) {\n result.privateData.keep = keepN(keepCount, keepLowest);\n return result;\n }\n\n throw new Error(\"Expected Dice after keep modifier\");\n}\n\nfunction keepN(n: number, low: boolean): (values: number[]) => number {\n return (values: number[]): number => {\n const sorted = [...values].sort((a, b) => (low ? a - b : b - a));\n return sorted.slice(0, n).reduce((sum, val) => sum + val, 0);\n };\n}\n\nfunction parseOperation(s: string[]): DiceOperation | undefined {\n switch (s[0]) {\n case \")\":\n return;\n\n case \"a\":\n assertToken(s, \"ac\");\n return Dice.prototype.ac;\n\n case \"d\":\n assertToken(s, \"dc\");\n return Dice.prototype.dc;\n\n case \"!\":\n assertToken(s, \"!\");\n const adv = Dice.prototype.advantage as DiceOperation;\n adv.unary = true;\n return adv;\n\n case \">\":\n assertToken(s, \">\");\n return Dice.prototype.max;\n\n case \"<\":\n assertToken(s, \"<\");\n return Dice.prototype.min;\n\n case \"+\":\n assertToken(s, \"+\");\n return Dice.prototype.addNonZero;\n\n case \"~\":\n assertToken(s, \"~\");\n assertToken(s, \"+\");\n return Dice.prototype.add;\n\n case \"-\":\n assertToken(s, \"-\");\n return Dice.prototype.subtract;\n\n case \"&\":\n assertToken(s, \"&\");\n return Dice.prototype.combine;\n\n case \"r\":\n assertToken(s, \"reroll\");\n return Dice.prototype.reroll;\n\n case \"*\":\n assertToken(s, \"*\");\n\n if (peek(s, \"*\")) {\n assertToken(s, \"*\");\n return Dice.prototype.multiply;\n }\n\n return Dice.prototype.conditionalApply;\n\n case \"/\":\n assertToken(s, \"/\");\n if (s[0] === \"/\") {\n assertToken(s, \"/\");\n return Dice.prototype.divideRoundDown;\n }\n return Dice.prototype.divideRoundUp;\n\n case \"=\":\n assertToken(s, \"=\");\n return Dice.prototype.eq;\n }\n\n return;\n}\n","import type { Bin } from \"../common/types\";\nimport { EPS } from \"../common/types\";\nimport { PMF } from \"./pmf\";\n\ntype BinEntries = Iterable<[number, Bin]>;\n\n/** A labeled mixture builder that preserves provenance in Bin.count. */\nexport class Mixture<L extends string = string> {\n private readonly totals = new Map<number, number>(); // raw mass per outcome (pre-normalization)\n private readonly labelMass = new Map<number, Record<L, number>>(); // raw mass per outcome per label\n private readonly eps: number;\n\n constructor(eps: number = EPS) {\n this.eps = Number.isFinite(eps) ? eps : EPS;\n }\n\n /** Remove all accumulated state. */\n clear(): this {\n this.totals.clear();\n this.labelMass.clear();\n return this;\n }\n\n /** Number of distinct outcome values currently accumulated. */\n size(): number {\n return this.totals.size;\n }\n\n /** Whether a label was ever added. */\n hasLabel(label: L): boolean {\n for (const bag of this.labelMass.values()) if (bag[label]) return true;\n return false;\n }\n\n /**\n * Add a labeled component with a mixture weight.\n * Weight can be any positive finite number. Very small contributions are pruned by eps.\n */\n add(label: L, pmf: PMF, weight = 1): this {\n if (!Number.isFinite(weight) || weight <= 0) return this;\n\n // Stream probabilities. Works whether PMF iterates as [v, p] or [v, Bin].\n for (const [v, binOrNumber] of pmf as any as BinEntries) {\n const isNumber = typeof binOrNumber === \"number\";\n const p = isNumber ? binOrNumber : binOrNumber?.p ?? 0;\n if (p <= 0) continue;\n\n const add = weight * p;\n if (!Number.isFinite(add) || Math.abs(add) < this.eps) continue;\n\n this.totals.set(v, (this.totals.get(v) ?? 0) + add);\n const bag = this.labelMass.get(v) ?? ({} as Record<L, number>);\n bag[label] = (bag[label] ?? 0) + add;\n this.labelMass.set(v, bag);\n }\n\n return this;\n }\n\n buildPMF(eps: number = EPS): PMF {\n // Kahan sum for robustness.\n let grand = 0;\n let c = 0;\n for (const m of this.totals.values()) {\n const y = m - c;\n const t = grand + y;\n c = t - grand - y;\n grand = t;\n }\n if (!(grand > 0)) throw new Error(\"Mixture: zero total mass\");\n\n const internal = new Map<number, Bin>();\n for (const [v, m] of this.totals) {\n if (m <= 0 || Math.abs(m) < this.eps) continue;\n const count = this.labelMass.get(v) ?? {};\n internal.set(v, { p: m / grand, count });\n }\n return new PMF(internal, eps);\n }\n\n /**\n * Produce normalized *per-label* PMFs (labels independent).\n * These are unlabeled PMFs built from the raw mass of that label alone.\n */\n byOutcome(): Record<L, PMF> {\n // Collect the set of labels present.\n const labels = new Set<L>();\n for (const bag of this.labelMass.values()) {\n for (const k of Object.keys(bag) as L[]) labels.add(k);\n }\n\n const out = {} as Record<L, PMF>;\n for (const label of labels) {\n const m = new Map<number, number>();\n for (const [v, bag] of this.labelMass) {\n const w = bag[label];\n if (w && Math.abs(w) >= this.eps) m.set(v, w);\n }\n if (m.size > 0) out[label] = PMF.fromMap(m, this.eps);\n }\n return out;\n }\n\n /**\n * Mixture weights per label, normalized to sum to 1 over labels that appeared.\n * Uses raw mass before per-outcome normalization.\n */\n weights(): Record<L, number> {\n const res = {} as Record<L, number>;\n for (const [, bag] of this.labelMass) {\n for (const [lab, w] of Object.entries(bag) as [L, number][]) {\n if (!Number.isFinite(w) || w <= 0) continue;\n res[lab] = (res[lab] ?? 0) + w;\n }\n }\n // Normalize\n let total = 0;\n let c = 0;\n for (const v of Object.values(res)) {\n const y = (v as number) - c;\n const t = total + y;\n c = t - total - y;\n total = t;\n }\n if (total > 0) {\n for (const k in res) res[k as L] = res[k as L] / total;\n }\n return res;\n }\n\n toJSON(): {\n totals: Array<[number, number]>;\n labels: Array<[number, Record<L, number>]>;\n eps: number;\n } {\n return {\n totals: Array.from(this.totals.entries()).sort((a, b) => a[0] - b[0]),\n labels: Array.from(this.labelMass.entries()).sort((a, b) => a[0] - b[0]),\n eps: this.eps,\n };\n }\n\n static mix<L extends string = string>(\n items: Array<[label: L, pmf: PMF, weight: number]>,\n eps: number = EPS\n ): PMF {\n const mix = new Mixture<L>(eps);\n for (const [lab, pmf, w] of items) mix.add(lab, pmf, w);\n return mix.buildPMF();\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/common/lru-cache.ts","../src/common/types.ts","../src/pmf/query.ts","../src/pmf/pmf.ts","../src/parser/dice.ts","../src/parser/parser.ts","../src/pmf/mixture.ts"],"names":["cumulativeSum","rec","result"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Simple LRU cache implementation\n */\n\nexport class LRUCache<K, V> {\n private cache = new Map<K, V>();\n\n constructor(private readonly maxSize = 1000) {}\n\n get(key: K): V | undefined {\n const value = this.cache.get(key);\n if (value === undefined) return undefined;\n\n this.cache.delete(key);\n this.cache.set(key, value);\n return value;\n }\n\n delete(key: K): void {\n this.cache.delete(key);\n }\n\n set(key: K, value: V): this {\n if (this.cache.size >= this.maxSize && !this.cache.has(key)) {\n const oldestKey = this.cache.keys().next().value;\n this.cache.delete(oldestKey as K);\n }\n this.cache.delete(key);\n this.cache.set(key, value);\n return this;\n }\n\n clear(): void {\n this.cache.clear();\n }\n\n get size(): number {\n return this.cache.size;\n }\n\n has(key: K): boolean {\n return this.cache.has(key);\n }\n\n keys(): IterableIterator<K> {\n return this.cache.keys();\n }\n\n values(): IterableIterator<V> {\n return this.cache.values();\n }\n}\n","/** Mapping from outcome label to probability mass or damage attribution. */\nexport type OutcomeLabelMap = Partial<Record<string, number>>;\n\n/** Computational epsilon for pruning negligible probabilities. */\nexport const EPS = 1e-12;\n\n/** A probability bin for a specific damage value. */\nexport interface Bin {\n /** Total probability mass at this damage value. */\n p: number;\n /** Per-outcome probability mass contributions at this damage. */\n count: OutcomeLabelMap;\n /** Optional per-outcome damage attribution at this damage. */\n attr?: OutcomeLabelMap;\n}\n\nexport interface CritConfig {\n critThreshold: number;\n}\n\n/** Simple mapping from damage value to probability. */\nexport type DamageDistribution = Record<number, number>;\n/** Canonical outcome labels supported by the query helpers. */\nexport type OutcomeType =\n | \"crit\"\n | \"hit\"\n | \"missNone\"\n | \"missDamage\"\n | \"saveHalf\"\n | \"saveFail\"\n | \"pc\";\n\nexport type Rounding = \"none\" | \"floor\" | \"round\" | \"ceil\";\n\nexport const onAnyHit: OutcomeType[] = [\"hit\", \"crit\"];\nexport const onCritOnly: OutcomeType[] = [\"crit\"];\nexport const onHitOnly: OutcomeType[] = [\"hit\"];\nexport const onMissOnly: OutcomeType[] = [\"missNone\", \"missDamage\"];\nexport const onMissDamageOnly: OutcomeType[] = [\"missDamage\"];\nexport const onSaveHalfOnly: OutcomeType[] = [\"saveHalf\"];\nexport const onSaveFailOnly: OutcomeType[] = [\"saveFail\"];\nexport const onPotentCantripOnly: OutcomeType[] = [\"pc\"];\n","import type { OutcomeType } from \"../common/types\";\nimport { EPS } from \"../common/types\";\nimport { PMF } from \"./pmf\";\n\n/**\n * Query interface for analyzing dice roll probability distributions.\n *\n * Combines multiple attack PMFs and provides statistical analysis methods for:\n * - Basic statistics (mean, variance, min/max, percentiles)\n * - Probability queries (hit chances, success rates, exact counts)\n * - Damage analysis (ranges by outcome type, expected values)\n * - Data export (charts, tables, visualizations)\n *\n */\n\nexport class DiceQuery {\n public readonly singles: PMF[];\n public readonly combined: PMF;\n private _combinedWithAttr?: PMF;\n\n constructor(singles: PMF | PMF[], combined?: PMF, eps = EPS) {\n this.singles = Array.isArray(singles) ? singles : [singles];\n if (this.singles.some((s) => s === undefined)) {\n throw new Error(\"DiceQuery contains undefined singles\");\n }\n const c = combined ?? PMF.convolveMany(this.singles);\n this.combined = Math.abs(c.mass() - 1) <= eps ? c : c.normalize();\n }\n\n private static readonly DEFAULT_OUTCOMES: readonly OutcomeType[] = [\n \"hit\",\n \"crit\",\n \"missNone\",\n ] as const;\n\n /**\n * Returns a new PMF with damage attribution metadata populated.\n *\n * This method computes attribution on-demand for builder-generated PMFs,\n * enabling them to work with damage attribution charts. The `attr` field\n * tracks how much damage each outcome type contributes at each damage value.\n *\n * For each bin at damage D: sum(attr.values()) ≈ D × P(damage = D)\n *\n * Performance: Cached after first call. Adds minimal overhead vs `combined`.\n *\n * @returns PMF with attr field populated for damage attribution charts\n *\n * @example\n * const attack = d20.plus(5).ac(15).onHit(d(2,6).plus(3)).onCrit(d(2,6))\n * const query = attack.toQuery()\n * const pmf = query.combinedWithAttribution()\n * // Now pmf can be used with toDamageAttributionChartSeries()\n */\n combinedWithAttribution(): PMF {\n if (this._combinedWithAttr) {\n return this._combinedWithAttr;\n }\n\n // Add attribution to each single PMF, then convolve\n // The existing convolution logic will preserve attribution correctly\n const singlesWithAttr = this.singles.map((pmf) => pmf.withAttribution());\n const combined = PMF.convolveMany(singlesWithAttr, this.combined.epsilon);\n\n // Normalize if needed\n const normalized =\n Math.abs(combined.mass() - 1) <= this.combined.epsilon\n ? combined\n : combined.normalize();\n\n this._combinedWithAttr = normalized;\n return normalized;\n }\n\n /**\n * Returns the expected damage across all possible outcomes.\n *\n * Example: `query.mean()` → 12.5\n * Use case: \"What's my average damage per round?\"\n */\n mean(): number {\n let totalSum = 0;\n for (const [damageValue, probabilityBin] of this.combined) {\n totalSum += damageValue * probabilityBin.p;\n }\n return totalSum;\n }\n\n /**\n * Returns the variance of the damage distribution.\n *\n * Example: `query.variance()` → 45.2\n * Use case: \"How much does my damage vary from the average?\"\n * High variance means higher risk/reward. Lower variance means more consistent damage.\n */\n variance(): number {\n const meanValue = this.mean();\n let varianceSum = 0;\n for (const [damageValue, probabilityBin] of this.combined) {\n const deviationFromMean = damageValue - meanValue;\n varianceSum += deviationFromMean * deviationFromMean * probabilityBin.p;\n }\n return varianceSum;\n }\n\n /**\n * Returns the standard deviation of the damage distribution.\n *\n * Example: `query.stdev()` → 6.7\n * Use case: \"What's the typical spread around my average damage?\"\n * Used to determine how consistent the damage is.\n */\n stddev(): number {\n return Math.sqrt(this.variance());\n }\n\n /**\n * Returns the Cumulative Distribution Function.\n */\n cdf(x: number): number {\n return this.probTotalAtMost(x);\n }\n\n /**\n * Returns the probability of dealing X damage or less.\n * In statistics, this is called the cumulative distribution function (CDF).\n * Example: `query.cdf(20)` → 0.75\n * Use case: \"What's the chance I deal 20 damage or less?\"\n */\n probTotalAtMost(x: number): number {\n let cumulativeProbability = 0;\n for (const [damageValue, probabilityBin] of this.combined) {\n if (damageValue <= x) {\n cumulativeProbability += probabilityBin.p;\n }\n }\n return cumulativeProbability;\n }\n\n /**\n * Returns the Complementary Cumulative Distribution Function.\n */\n ccdf(x: number): number {\n return this.probTotalAtLeast(x);\n }\n\n /**\n * Returns the probability of dealing at least X damage.\n *\n * Example: `query.probTotalAtLeast(25)` → 0.35\n * Use case: \"What's the chance I deal at least 25 damage to finish the enemy?\"\n */\n probTotalAtLeast(threshold: number): number {\n let probabilitySum = 0;\n for (const [damageValue, probabilityBin] of this.combined) {\n if (damageValue >= threshold) {\n probabilitySum += probabilityBin.p;\n }\n }\n return probabilitySum;\n }\n\n /**\n * Returns damage values at specific percentiles.\n *\n * Example: `query.percentiles([0.25, 0.5, 0.75])` → [8, 12, 18]\n * Use case: \"What are my 25th, 50th, and 75th percentile damage values?\"\n */\n percentiles(percentileValues: number[]): number[] {\n const sortedDamageValues = this.combined.support();\n if (sortedDamageValues.length === 0) return percentileValues.map(() => 0);\n\n const cumulativeProbabilities: number[] = [];\n let runningProbabilitySum = 0;\n for (const damageValue of sortedDamageValues) {\n runningProbabilitySum += this.combined.map.get(damageValue)!.p;\n cumulativeProbabilities.push(runningProbabilitySum);\n }\n\n return percentileValues.map((targetPercentile) => {\n // Binary search for efficiency\n let leftBound = 0;\n let rightBound = cumulativeProbabilities.length - 1;\n\n while (leftBound <= rightBound) {\n const middleIndex = Math.floor((leftBound + rightBound) / 2);\n if (cumulativeProbabilities[middleIndex] >= targetPercentile) {\n rightBound = middleIndex - 1;\n } else {\n leftBound = middleIndex + 1;\n }\n }\n\n return leftBound < sortedDamageValues.length\n ? sortedDamageValues[leftBound]\n : sortedDamageValues[sortedDamageValues.length - 1];\n });\n }\n\n /**\n * Returns the minimum possible damage.\n *\n * Example: `query.min()` → 0\n * Use case: \"What's the worst-case damage if everything misses?\"\n */\n min(): number {\n return this.combined.min();\n }\n\n /**\n * Returns the maximum possible damage.\n *\n * Example: `query.max()` → 56\n * Use case: \"What's the best-case damage if everything crits and rolls max?\"\n */\n max(): number {\n return this.combined.max();\n }\n\n private singleProb(diceIndex: number, label: OutcomeType): number {\n let probabilitySum = 0;\n for (const [, probabilityBin] of this.singles[diceIndex]) {\n probabilitySum += probabilityBin.count[label] || 0;\n }\n return probabilitySum;\n }\n\n probAtLeastK(labels: OutcomeType | OutcomeType[], k: number): number {\n const L = Array.isArray(labels) ? [...new Set(labels)] : [labels];\n const n = this.singles.length;\n\n if (k <= 0) return 1;\n if (k > n) return 0;\n\n let tail = 0;\n for (let i = k; i <= n; i++) {\n tail += this.probExactlyK(L, i);\n }\n\n if (tail < 0) return 0;\n if (tail > 1) return 1;\n return tail;\n }\n\n /**\n * Returns the probability that at least one attack has the specified outcome(s).\n * - This is the complement of probAtMostK(labels, 0)\n *\n * Examples:\n * - `query.probAtLeastOne('hit')` → 0.88 (88% chance at least one attack hits)\n * - `query.probAtLeastOne(['hit', 'crit'])` → 0.96 (96% chance at least one succeeds)\n *\n * Use cases:\n * - \"What's the chance at least one of my attacks connects?\"\n *\n * Note:\n *\n * - You have to pass in an array of labels to avoid double-counting if you are\n * using multiple labels. You cannot just add them.\n */\n probAtLeastOne(labels: OutcomeType | OutcomeType[]): number {\n // Handle single label case (backward compatibility)\n if (typeof labels === \"string\") {\n labels = [labels];\n }\n\n let productOfNonOccurrence = 1;\n for (let diceIndex = 0; diceIndex < this.singles.length; diceIndex++) {\n // Calculate total probability of any of the specified labels occurring\n let combinedProbability = 0;\n for (const label of labels) {\n combinedProbability += this.singleProb(diceIndex, label);\n }\n productOfNonOccurrence *= 1 - combinedProbability;\n }\n return 1 - productOfNonOccurrence;\n }\n\n /**\n * Computes binomial probabilities for exactly 0, 1, 2, ..., maxK occurrences of a label.\n *\n * Uses dynamic programming to efficiently calculate the probability distribution\n * of how many attacks will have the specified outcome, accounting for different\n * success probabilities across individual attacks.\n *\n * Example: For 3 attacks with 50% hit chance each, returns:\n * [0.125, 0.375, 0.375, 0.125] = [P(0 hits), P(1 hit), P(2 hits), P(3 hits)]\n *\n * @param label - The outcome type to count\n * @param maxK - Maximum number of occurrences to calculate (usually number of attacks)\n * @returns Array where index K contains P(exactly K attacks have the label)\n */\n private computeBinomialProbabilities(\n label: OutcomeType,\n maxK: number\n ): number[] {\n const individualProbabilities = this.singles.map((_, diceIndex) =>\n this.singleProb(diceIndex, label)\n );\n const binomialProbs = new Array(maxK + 1).fill(0);\n binomialProbs[0] = 1;\n\n for (const singleProbability of individualProbabilities) {\n for (let outcomeCount = maxK; outcomeCount >= 1; outcomeCount--) {\n binomialProbs[outcomeCount] =\n binomialProbs[outcomeCount] * (1 - singleProbability) +\n binomialProbs[outcomeCount - 1] * singleProbability;\n }\n binomialProbs[0] *= 1 - singleProbability;\n }\n\n return binomialProbs;\n }\n\n /**\n * Returns the probability that exactly K attacks result in the specified outcome(s).\n *\n * Single label examples:\n * - probExactlyK('hit', 2) = probability exactly 2 attacks hit\n * - probExactlyK('crit', 1) = probability exactly 1 attack crits\n * - probExactlyK('crit', 0) = probability no attacks crit\n *\n * Array examples:\n * - probExactlyK(['hit', 'crit'], 2) = probability exactly 2 attacks succeed\n * - probExactlyK(['hit', 'crit'], 1) = probability exactly 1 attack succeeds\n * - probExactlyK(['miss', 'missNone'], 0) = probability no attacks miss\n *\n * Use cases:\n * - \"What's the chance exactly one of my attacks hits?\"\n * - \"How likely am I to get exactly 2 successes out of 3 attacks?\"\n * - \"What's the probability that exactly half my attacks succeed?\"\n *\n * Note: For arrays, an attack counts as a \"success\" if it has any of the specified labels.\n * This is different from probAtMostK, which counts an attack as a \"success\" if it has ALL of the specified labels.\n */\n probExactlyK(labels: OutcomeType | OutcomeType[], k: number): number {\n // Handle single label case (backward compatibility)\n if (typeof labels === \"string\") {\n const probabilityArray = this.computeBinomialProbabilities(labels, k);\n return probabilityArray[k];\n }\n\n // For multiple labels, we need to compute success probability for each single attack\n const successProbabilities = this.singles.map((single) => {\n const singleQuery = new DiceQuery([single]);\n return singleQuery.probabilityOf(labels);\n });\n\n // Use binomial distribution with combined success probability\n const binomialProbs = new Array(k + 1).fill(0);\n binomialProbs[0] = 1;\n\n for (const successProb of successProbabilities) {\n for (let outcomeCount = k; outcomeCount >= 1; outcomeCount--) {\n binomialProbs[outcomeCount] =\n binomialProbs[outcomeCount] * (1 - successProb) +\n binomialProbs[outcomeCount - 1] * successProb;\n }\n binomialProbs[0] *= 1 - successProb;\n }\n\n return binomialProbs[k];\n }\n\n /**\n * Returns the probability that AT MOST K attacks result in the specified outcome(s).\n *\n * Single label examples:\n * - probAtMostK('hit', 1) = probability 0 or 1 attacks hit (at most 1)\n * - probAtMostK('crit', 0) = probability no attacks crit\n * - probAtMostK('miss', 2) = probability at most 2 attacks miss\n *\n * Array examples:\n * - probAtMostK(['hit', 'crit'], 1) = probability at most 1 attack succeeds\n * - probAtMostK(['hit', 'crit'], 0) = probability no attacks succeed (all miss)\n *\n * Use cases:\n * - \"What's the chance that at most one attack hits?\" (rest miss)\n * - \"How likely am I to have mostly failures?\" (at most 1 success)\n * - \"What's the probability of a really bad turn?\" (at most 0 successes)\n *\n */\n probAtMostK(labels: OutcomeType | OutcomeType[], k: number): number {\n // Handle single label case (backward compatibility)\n if (typeof labels === \"string\") {\n const probabilityArray = this.computeBinomialProbabilities(labels, k);\n let cumulativeSum = 0;\n for (let outcomeCount = 0; outcomeCount <= k; outcomeCount++) {\n cumulativeSum += probabilityArray[outcomeCount];\n }\n return cumulativeSum;\n }\n\n // For multiple labels, compute probabilities for 0 to k\n let cumulativeSum = 0;\n for (let outcomeCount = 0; outcomeCount <= k; outcomeCount++) {\n cumulativeSum += this.probExactlyK(labels, outcomeCount);\n }\n return cumulativeSum;\n }\n\n /**\n * Returns the expected damage attributed to specific outcome types.\n *\n * Single label examples:\n * - expectedDamageFrom('hit') = expected damage from hit components\n * - expectedDamageFrom('crit') = expected damage from crit components\n *\n * Array examples:\n * - expectedDamageFrom(['hit', 'crit']) = expected damage from any success\n * - expectedDamageFrom(['missDamage', 'missNone']) = expected damage from misses\n *\n * Use cases:\n * - \"How much damage do I expect from successful attacks?\"\n * - \"What's the damage contribution from critical hits specifically?\"\n * - \"How much damage comes from miss effects (like save-for-half spells)?\"\n */\n expectedDamageFrom(labels: OutcomeType | OutcomeType[]): number {\n const wanted = Array.isArray(labels) ? labels : [labels];\n\n let total = 0;\n // By linearity of expectation, we can sum the expected damages from each individual PMF. This avoids issues with the `count` aggregation during\n for (const single of this.singles) {\n for (const [dmg, bin] of single) {\n let p = 0;\n for (const label of wanted) p += bin.count[label] ?? 0;\n total += dmg * p;\n }\n }\n return total;\n }\n\n /**\n * Returns damage statistics for scenarios where AT LEAST ONE attack results in\n * the specified outcome(s).\n *\n * This method answers \"What happens when things go reasonably well?\" rather than\n * \"What's the theoretical maximum?\" It includes mixed scenarios which are more\n * common and tactically relevant than pure scenarios.\n *\n * Single label examples:\n * - damageStatsFrom('hit') = damage range when at least one attack hits\n * - damageStatsFrom('crit') = damage range when at least one attack crits\n *\n * Array examples:\n * - damageStatsFrom(['hit', 'crit']) = damage range when at least one attack succeeds\n * - damageStatsFrom(['miss', 'missNone']) = damage range when at least one attack misses\n *\n * Tactical Use Cases:\n * - \"Given that I don't completely whiff (99% of turns), what damage should I expect?\"\n * - \"When planning to kill a 60 HP enemy, what's my damage range on successful turns?\"\n * - \"Should I use this risky spell if it has good damage when it works?\"\n * - \"What's my damage potential when something goes right?\" (vs pure failure)\n *\n * Combat Planning Examples:\n * - 4 attacks with 90% hit chance: \"96% of the time you'll do 25-150 damage, avg 52\"\n * (Much more useful than \"You average 50 damage including complete misses\")\n * - Risk assessment: \"80% of successful turns do 40-80 damage, but 20% do 80-150\"\n * - Resource management: \"If I hit anything, I'll likely finish this enemy\"\n *\n * Statistical Note:\n * This includes mixed scenarios (2 hits + 1 crit, 3 hits + 1 miss, etc.) which\n * occur far more frequently than pure scenarios. For pure scenarios, use combinedDamageStats.\n *\n * @example\n * // High-level tactical planning\n * const successStats = query.damageStatsFrom('hit')\n * const successChance = query.probAtLeastOne('hit')\n * console.log(`${(successChance*100).toFixed(1)}% chance to do ${successStats.min}-${successStats.max} damage`)\n */\n damageStatsFrom(labels: OutcomeType | OutcomeType[]): {\n min: number;\n max: number;\n avg: number;\n count: number;\n } {\n // Normalize input to array for uniform handling\n const labelArray = typeof labels === \"string\" ? [labels] : labels;\n\n let minDamage = Infinity;\n let maxDamage = -Infinity;\n let totalDamage = 0;\n let totalCount = 0;\n\n for (const [damage, probabilityBin] of this.combined) {\n // Check if this bin has any of the specified labels\n let binHasAnyLabel = false;\n let binContribution = 0;\n\n for (const label of labelArray) {\n const count = probabilityBin.count[label] as number;\n if (count && count > 0) {\n binHasAnyLabel = true;\n binContribution += count;\n }\n }\n\n if (damage > 0 && binHasAnyLabel) {\n minDamage = Math.min(minDamage, damage);\n maxDamage = Math.max(maxDamage, damage);\n\n // For single labels, use the specific count; for multiple labels, use total probability\n const weightToUse =\n labelArray.length === 1 ? binContribution : probabilityBin.p;\n totalDamage += damage * weightToUse;\n totalCount += weightToUse;\n }\n }\n\n return {\n min: minDamage === Infinity ? 0 : minDamage,\n max: maxDamage === -Infinity ? 0 : maxDamage,\n avg: totalCount > 0 ? totalDamage / totalCount : 0,\n count: totalCount,\n };\n }\n\n /**\n * Returns damage statistics for scenarios where ALL attacks result in the specified\n * outcome, calculated by leveraging the pure partition of singles.\n *\n * This method answers \"What's the theoretical best/worst case?\" and \"What are the\n * clean mathematical boundaries?\" It provides pure scenarios without mixing outcomes.\n *\n * Examples:\n * - combinedDamageStats('hit') = damage range when all attacks hit (none crit, none miss)\n * - combinedDamageStats('crit') = damage range when all attacks crit (none just hit)\n *\n * UI and Display Use Cases:\n * - Statistics panels showing \"MAX Hit Damage\" (users expect pure hits, not mixed)\n * - \"Best case scenario\" vs \"worst case scenario\" analysis\n * - Mathematical verification: \"Does our hit damage calculation match manual math?\"\n * - Clean damage type attribution: \"How much comes from base hits vs crits?\"\n *\n * Design and Balance Use Cases:\n * - Game designers: \"What's the damage ceiling if someone gets lucky?\"\n * - Character optimization: \"What's my absolute maximum potential?\"\n * - Ability comparison: \"Which build has higher crit ceiling?\"\n * - Minimum guaranteed damage: \"What's the worst I can do if everything hits?\"\n *\n * Mathematical Use Cases:\n * - Validating complex calculations against simple manual math\n * - Understanding damage component contributions in isolation\n * - Separating luck (crit variance) from consistency (hit variance)\n * - Building intuition about damage sources\n *\n * When to Use This vs damageStatsFrom():\n * - Use THIS for: UI max/min displays, theoretical limits, clean comparisons\n * - Use damageStatsFrom() for: tactical planning, realistic expectations, mixed scenarios\n *\n * Statistical Note:\n * Pure scenarios (all hits, all crits) are rare but represent clear mathematical\n * boundaries. These stats help understand the \"shape\" of your damage potential.\n *\n * @example\n * // UI display logic\n * const pureHitMax = query.combinedDamageStats('hit').max // Clean \"MAX Hit Damage: 90\"\n * const pureCritMax = query.combinedDamageStats('crit').max // Clean \"MAX Crit Damage: 168\"\n *\n * // vs tactical planning (use damageStatsFrom instead)\n * const realisticRange = query.damageStatsFrom('hit') // Includes mixed scenarios\n */\n combinedDamageStats(targetLabel: OutcomeType): {\n min: number;\n max: number;\n avg: number;\n count: number;\n } {\n // Get pure statistics from each single attack (singles are already pure partitions)\n const singleStats = this.singles.map((single) =>\n new DiceQuery([single]).damageStatsFrom(targetLabel)\n );\n\n // If any single attack has no outcomes of this type, return zeros\n if (singleStats.some((stats) => stats.count === 0)) {\n return { min: 0, max: 0, avg: 0, count: 0 };\n }\n\n // Calculate combined statistics for N attacks all of target type\n const combinedMin = singleStats.reduce((sum, stats) => sum + stats.min, 0);\n const combinedMax = singleStats.reduce((sum, stats) => sum + stats.max, 0);\n const combinedAvg = singleStats.reduce((sum, stats) => sum + stats.avg, 0);\n const combinedProb = singleStats.reduce(\n (product, stats) => product * stats.count,\n 1\n );\n\n return {\n min: combinedMin,\n max: combinedMax,\n avg: combinedAvg,\n count: combinedProb,\n };\n }\n\n /**\n * Returns the probability that a result includes ANY of the specified labels.\n *\n * Examples:\n * - `query.probabilityOf('hit')` → 0.88 (probability at least one hit occurs)\n * - `query.probabilityOf(['hit', 'crit'])` → 0.96 (probability of any success)\n *\n * Use cases:\n * - \"What's the chance my resolution includes a success label?\"\n * - \"How likely am I to get any hits or crits across all attacks?\"\n */\n probabilityOf(labels: OutcomeType | OutcomeType[]): number {\n // Handle single label case (backward compatibility)\n if (typeof labels === \"string\") {\n labels = [labels];\n }\n\n let totalProbability = 0;\n for (const [, probabilityBin] of this.combined) {\n // Calculate probability that this bin contains ANY of the specified labels\n // Use inclusion-exclusion principle to avoid double-counting overlaps\n let binHasAnyLabel = false;\n for (const label of labels) {\n if (\n probabilityBin.count[label] &&\n (probabilityBin.count[label] as number) > 0\n ) {\n binHasAnyLabel = true;\n break;\n }\n }\n if (binHasAnyLabel) {\n totalProbability += probabilityBin.p;\n }\n }\n return totalProbability;\n }\n\n /**\n * Returns the probability of missing (any type of miss).\n *\n * Example: `query.missChance()` → 0.04\n * Use case: \"What's the chance I miss completely this turn?\"\n */\n missChance(): number {\n // Miss can be either explicit misses with damage or zero-damage misses\n return this.probabilityOf([\"missDamage\", \"missNone\"]);\n }\n\n /**\n * Returns data formatted for plotting damage probability distribution.\n *\n * Example: `query.toChartSeries()` → [{x: 0, y: 0.04}, {x: 6, y: 0.1}, ...]\n * Use case: \"I want to visualize my damage distribution in a chart.\"\n */\n toChartSeries(): Array<{ x: number; y: number }> {\n return this.combined.support().map((damageValue) => ({\n x: damageValue,\n y: this.combined.map.get(damageValue)!.p,\n }));\n }\n\n /**\n * Returns tabular data showing damage values and their probability breakdowns.\n *\n * Example: `query.toLabeledTable(['hit', 'crit'])` →\n * [{damage: 6, total: 0.01, hit: 0.008, crit: 0}, ...]\n *\n * Use case: \"I want to see exactly how hit/crit probabilities contribute to each damage value.\"\n */\n toLabeledTable(\n labels: OutcomeType[] = []\n ): Array<{ damage: number; total: number } & Record<string, number>> {\n return this.combined.support().map((damageValue) => {\n const probabilityBin = this.combined.map.get(damageValue)!;\n const tableRow: { damage: number; total: number } & Record<\n string,\n number\n > = {\n damage: damageValue,\n total: probabilityBin.p,\n };\n for (const outcomeLabel of labels) {\n tableRow[outcomeLabel] = probabilityBin.count[outcomeLabel] || 0;\n }\n return tableRow;\n });\n }\n\n /**\n * Returns data for stacked charts with unconditional per-label probability mass per damage.\n *\n * - Each dataset value equals the unconditional probability mass for that label at that damage\n * (i.e., `bin.count[label]`).\n * - Column sums may be less than the total probability `bin.p` when you omit labels or when\n * there is unlabeled mass. Include all relevant outcome labels if you need the sum to match.\n * - This behavior matches tests that expect raw per-label mass (not proportional scaling).\n * - NOTE: This implementation may break dprcalc.com chart binning at large n, need to test it more.\n *\n * @example\n * query.toStackedChartData(['hit', 'crit'])\n * // → {labels: [0, 6, 12, ...], datasets: [{label: 'hit', data: [0, 0.03, ...]}, ...]}\n */\n toStackedChartData(\n labels: OutcomeType[] = [],\n epsilon = EPS\n ): { labels: number[]; datasets: Array<{ label: string; data: number[] }> } {\n const damageValues = this.combined.support();\n\n // Precompute totalCount per bin for the labels you intend to stack for efficiency.\n damageValues.map((dmg) => {\n const bin = this.combined.map.get(dmg)!;\n return labels.reduce((sum, lab) => sum + (bin.count[lab] || 0), 0);\n });\n\n const datasets = labels.map((outcomeLabel) => ({\n label: outcomeLabel,\n data: damageValues.map((dmg) => {\n const bin = this.combined.map.get(dmg);\n const v = bin ? (bin.count[outcomeLabel] as number) || 0 : 0;\n return v <= epsilon ? 0 : v;\n }),\n }));\n\n return { labels: damageValues, datasets };\n }\n\n /**\n * Returns pure mathematical data for attribution charts showing outcome contributions.\n *\n * Automatically discovers all outcome types present in the PMF, applies filtering rules,\n * and returns proportional data suitable for stacked visualization.\n *\n * @param options Configuration options\n * @param options.stackOrder Preferred order for outcome types (unknowns placed at end)\n * @param options.filterRules Function to determine if outcome should be included for a given damage value\n * @param options.asPercentages Whether to return percentages (0-100) or probabilities (0-1)\n * @returns Pure data structure with support, outcomes, and proportional data\n *\n * @example\n * query.toAttributionChartSeries()\n * // → {support: [0, 6, 12], outcomes: ['hit', 'crit'], data: {hit: [5.2, 8.1, ...], crit: [0, 2.3, ...]}}\n */\n toAttributionChartSeries(\n options: {\n stackOrder?: string[];\n filterRules?: (outcome: string, damage: number) => boolean;\n asPercentages?: boolean;\n } = {}\n ): {\n support: number[];\n outcomes: string[];\n data: { [outcome: string]: number[] };\n } {\n const {\n stackOrder = [\n \"missNone\",\n \"missDamage\",\n \"saveFail\",\n \"saveHalf\",\n \"pc\",\n \"hit\",\n \"crit\",\n ],\n filterRules = (outcome: string, damage: number) =>\n !(outcome === \"missNone\" && damage !== 0),\n asPercentages = true,\n } = options;\n\n const originalSupport = this.combined.support();\n if (originalSupport.length === 0) {\n return { support: [], outcomes: [], data: {} };\n }\n\n // Create complete integer range from min to max\n const minDamage = Math.min(...originalSupport);\n const maxDamage = Math.max(...originalSupport);\n const support = Array.from(\n { length: maxDamage - minDamage + 1 },\n (_, i) => minDamage + i\n );\n\n // Find ALL outcome types that exist in the PMF\n const allOutcomeTypes = new Set<string>();\n for (const [, bin] of this.combined.map) {\n for (const outcomeType in bin.count) {\n if (bin.count[outcomeType] && (bin.count[outcomeType] as number) > 0) {\n allOutcomeTypes.add(outcomeType);\n }\n }\n }\n\n // Sort existing outcomes by preferred stack order, with unknowns at end\n const existingOutcomes = Array.from(allOutcomeTypes).sort((a, b) => {\n const indexA = stackOrder.indexOf(a);\n const indexB = stackOrder.indexOf(b);\n\n // If both are in stackOrder, use that order\n if (indexA >= 0 && indexB >= 0) return indexA - indexB;\n\n // Put unknowns at the end\n if (indexA >= 0) return -1;\n if (indexB >= 0) return 1;\n\n // Both unknown, alphabetical\n return a.localeCompare(b);\n });\n\n if (existingOutcomes.length === 0) {\n return { support, outcomes: [], data: {} };\n }\n\n // Calculate data for each outcome type\n const data: { [outcome: string]: number[] } = {};\n\n for (const outcome of existingOutcomes) {\n data[outcome] = support.map((damage) => {\n const bin = this.combined.map.get(damage);\n if (!bin) return 0;\n\n // Apply filter rules\n if (!filterRules(outcome, damage)) {\n return 0;\n }\n\n // Calculate proportion only among outcomes that will actually be charted\n const outcomeCount = (bin.count[outcome] as number) || 0;\n\n // Calculate total count excluding outcomes that will be filtered out\n let totalChartableCount = 0;\n for (const [outcomeName, count] of Object.entries(bin.count)) {\n if (filterRules(outcomeName, damage)) {\n totalChartableCount += (count as number) || 0;\n }\n }\n\n if (totalChartableCount === 0) return 0;\n\n // Calculate what fraction of chartable probability comes from this outcome\n const outcomeFraction = outcomeCount / totalChartableCount;\n const outcomeProbability = bin.p * outcomeFraction;\n\n return asPercentages ? outcomeProbability * 100 : outcomeProbability;\n });\n }\n\n return {\n support,\n outcomes: existingOutcomes,\n data,\n };\n }\n\n /**\n * Returns pure mathematical data for damage attribution charts showing damage contribution\n * from each outcome type at each damage value.\n *\n * Similar to toAttributionChartSeries() but uses bin.attr (damage attribution) instead of\n * bin.count (probability attribution).\n *\n * @param options Configuration options\n * @param options.stackOrder Preferred order for outcome types (unknowns placed at end)\n * @param options.filterRules Function to determine if outcome should be included for a given damage value\n * @param options.asPercentages Whether to return percentages (0-100) or raw damage values (0+)\n * @returns Pure data structure with support, outcomes, and damage attribution data\n *\n * @example\n * query.toDamageAttributionChartSeries()\n * // → {support: [0, 6, 12], outcomes: ['hit', 'crit'], data: {hit: [3.2, 5.1, ...], crit: [0, 1.8, ...]}}\n */\n toDamageAttributionChartSeries(\n options: {\n stackOrder?: string[];\n filterRules?: (outcome: string, damage: number) => boolean;\n asPercentages?: boolean;\n } = {}\n ): {\n support: number[];\n outcomes: string[];\n data: { [outcome: string]: number[] };\n } {\n const {\n stackOrder = [\n \"missNone\",\n \"missDamage\",\n \"saveFail\",\n \"saveHalf\",\n \"pc\",\n \"hit\",\n \"crit\",\n ],\n filterRules = (outcome: string, damage: number) =>\n !(outcome === \"missNone\" && damage !== 0),\n asPercentages = true,\n } = options;\n\n const originalSupport = this.combined.support();\n if (originalSupport.length === 0) {\n return { support: [], outcomes: [], data: {} };\n }\n\n // Create complete integer range from min to max\n const minDamage = Math.min(...originalSupport);\n const maxDamage = Math.max(...originalSupport);\n const support = Array.from(\n { length: maxDamage - minDamage + 1 },\n (_, i) => minDamage + i\n );\n\n // Find ALL outcome types that exist in the PMF (from attr, not count)\n const allOutcomeTypes = new Set<string>();\n for (const [, bin] of this.combined.map) {\n if (bin.attr) {\n for (const outcomeType in bin.attr) {\n if (bin.attr[outcomeType] && (bin.attr[outcomeType] as number) > 0) {\n allOutcomeTypes.add(outcomeType);\n }\n }\n }\n }\n\n // Sort existing outcomes by preferred stack order, with unknowns at end\n const existingOutcomes = Array.from(allOutcomeTypes).sort((a, b) => {\n const indexA = stackOrder.indexOf(a);\n const indexB = stackOrder.indexOf(b);\n\n // If both are in stackOrder, use that order\n if (indexA >= 0 && indexB >= 0) return indexA - indexB;\n\n // Put unknowns at the end\n if (indexA >= 0) return -1;\n if (indexB >= 0) return 1;\n\n // Both unknown, alphabetical\n return a.localeCompare(b);\n });\n\n if (existingOutcomes.length === 0) {\n return { support, outcomes: [], data: {} };\n }\n\n // Calculate data for each outcome type\n const data: { [outcome: string]: number[] } = {};\n\n for (const outcome of existingOutcomes) {\n data[outcome] = support.map((damage) => {\n const bin = this.combined.map.get(damage);\n if (!bin || !bin.attr) return 0;\n\n // Apply filter rules\n if (!filterRules(outcome, damage)) {\n return 0;\n }\n\n // Get the damage attribution for this outcome at this damage value\n const outcomeDamageAttribution = (bin.attr[outcome] as number) || 0;\n\n if (asPercentages) {\n // Calculate total damage attribution at this damage value (for percentage calculation)\n let totalDamageAttribution = 0;\n for (const [outcomeName, damageAttr] of Object.entries(bin.attr)) {\n if (filterRules(outcomeName, damage)) {\n totalDamageAttribution += (damageAttr as number) || 0;\n }\n }\n\n if (totalDamageAttribution === 0) return 0;\n\n // Calculate the damage attribution percentage\n const damagePercentage =\n (outcomeDamageAttribution / totalDamageAttribution) * 100;\n\n // Scale by the probability of this damage value occurring\n // This makes bar height proportional to P(damage = x) while preserving attribution percentages\n return damagePercentage * bin.p * 100; // Scale by probability, *100 to make visible\n } else {\n return outcomeDamageAttribution;\n }\n });\n }\n\n return {\n support,\n outcomes: existingOutcomes,\n data,\n };\n }\n\n /**\n * Returns pure mathematical data for outcome attribution charts showing which\n * attack outcome combinations can produce each damage value.\n *\n * Unlike toDamageAttributionChartSeries() which tracks damage sources, this tracks\n * outcome combinations - answering \"what attack outcomes produced this damage?\"\n *\n * @param options Configuration options\n * @param options.stackOrder Preferred order for outcome types (unknowns placed at end)\n * @param options.filterRules Function to determine if outcome should be included for a given damage value\n * @param options.asPercentages Whether to return percentages (0-100) or probabilities (0-1)\n * @returns Pure data structure with support, outcomes, and outcome combination probabilities\n *\n * @example\n * query.toOutcomeAttributionChartSeries()\n * // → {support: [0, 6, 12], outcomes: ['all_miss', 'mixed', 'all_hit'], data: {all_miss: [15, 0, 0], mixed: [60, 80, 20], all_hit: [25, 20, 80]}}\n */\n toOutcomeAttributionChartSeries(\n options: {\n stackOrder?: string[];\n filterRules?: (outcome: string, damage: number) => boolean;\n asPercentages?: boolean;\n } = {}\n ): {\n support: number[];\n outcomes: string[];\n data: { [outcome: string]: number[] };\n } {\n const {\n stackOrder = [\n \"missNone\",\n \"missDamage\",\n \"saveFail\",\n \"saveHalf\",\n \"pc\",\n \"hit\",\n \"crit\",\n ],\n filterRules = (outcome: string, damage: number) =>\n !(outcome === \"missNone\" && damage !== 0),\n asPercentages = true,\n } = options;\n\n const originalSupport = this.combined.support();\n if (originalSupport.length === 0) {\n return { support: [], outcomes: [], data: {} };\n }\n\n // Create complete integer range from min to max\n const minDamage = Math.min(...originalSupport);\n const maxDamage = Math.max(...originalSupport);\n const support = Array.from(\n { length: maxDamage - minDamage + 1 },\n (_, i) => minDamage + i\n );\n\n // Find ALL outcome types that exist in the PMF (from count, for outcome tracking)\n const allOutcomeTypes = new Set<string>();\n for (const [, bin] of this.combined.map) {\n for (const outcomeType in bin.count) {\n if (bin.count[outcomeType] && (bin.count[outcomeType] as number) > 0) {\n allOutcomeTypes.add(outcomeType);\n }\n }\n }\n\n // Sort existing outcomes by preferred stack order, with unknowns at end\n const existingOutcomes = Array.from(allOutcomeTypes).sort((a, b) => {\n const indexA = stackOrder.indexOf(a);\n const indexB = stackOrder.indexOf(b);\n\n if (indexA >= 0 && indexB >= 0) return indexA - indexB;\n if (indexA >= 0) return -1;\n if (indexB >= 0) return 1;\n return a.localeCompare(b);\n });\n\n if (existingOutcomes.length === 0) {\n return { support, outcomes: [], data: {} };\n }\n\n // Calculate data for each outcome type\n const data: { [outcome: string]: number[] } = {};\n\n for (const outcome of existingOutcomes) {\n data[outcome] = support.map((damage) => {\n const bin = this.combined.map.get(damage);\n if (!bin) return 0;\n\n // Apply filter rules\n if (!filterRules(outcome, damage)) {\n return 0;\n }\n\n // Handle missNone specially since it doesn't appear in bin.attr (0 damage)\n if (outcome === \"missNone\") {\n // For missNone, use bin.count since it contributes 0 damage\n const outcomeCount = (bin.count[outcome] as number) || 0;\n if (outcomeCount === 0) return 0;\n\n if (asPercentages) {\n // For missNone, show probability proportion since damage attribution would be 0\n let totalChartableCount = 0;\n for (const [outcomeName, count] of Object.entries(bin.count)) {\n if (filterRules(outcomeName, damage)) {\n totalChartableCount += (count as number) || 0;\n }\n }\n if (totalChartableCount === 0) return 0;\n const outcomeFraction = outcomeCount / totalChartableCount;\n return outcomeFraction * bin.p * 100;\n } else {\n return outcomeCount;\n }\n }\n\n // Use damage attribution to calculate proportional contribution for non-missNone outcomes\n if (!bin.attr) return 0;\n\n const outcomeDamageContribution = (bin.attr[outcome] as number) || 0;\n\n if (asPercentages) {\n // Calculate total damage attribution at this damage value\n let totalDamageAttribution = 0;\n for (const [, damageAttr] of Object.entries(bin.attr)) {\n totalDamageAttribution += (damageAttr as number) || 0;\n }\n\n if (totalDamageAttribution === 0) return 0;\n\n // The proportion is: damage from this outcome / total damage from all outcomes\n // This gives us exactly what you want: for damage 13 = hit(11) + miss(2),\n // hit proportion = 11/13, miss proportion = 2/13\n const outcomeFraction =\n outcomeDamageContribution / totalDamageAttribution;\n\n // Scale by probability for bar height while preserving damage attribution percentages\n return outcomeFraction * bin.p * 100;\n } else {\n return outcomeDamageContribution;\n }\n });\n }\n\n return {\n support,\n outcomes: existingOutcomes,\n data,\n };\n }\n\n /**\n * Returns pure mathematical data for cumulative distribution function (CDF).\n * Shows P(X ≤ x) - the probability of getting at most x damage.\n *\n * @param asPercentages Whether to return percentages (0-100) or probabilities (0-1)\n * @returns Pure data structure with support and cumulative probabilities\n *\n * @example\n * query.toCDFSeries()\n * // → {support: [0, 6, 12], data: [5.2, 18.3, 45.1]}\n */\n toCDFSeries(asPercentages: boolean = true): {\n support: number[];\n data: number[];\n } {\n const originalSupport = this.combined.support();\n if (originalSupport.length === 0) {\n return { support: [], data: [] };\n }\n\n // Create complete integer range from min to max\n const minDamage = Math.min(...originalSupport);\n const maxDamage = Math.max(...originalSupport);\n const support = Array.from(\n { length: maxDamage - minDamage + 1 },\n (_, i) => minDamage + i\n );\n\n let cumulativeProbability = 0;\n const cdfData: number[] = [];\n\n for (const damage of support) {\n const bin = this.combined.map.get(damage);\n if (bin) {\n cumulativeProbability += bin.p;\n }\n cdfData.push(\n asPercentages ? cumulativeProbability * 100 : cumulativeProbability\n );\n }\n\n return {\n support,\n data: cdfData,\n };\n }\n\n /**\n * Returns pure mathematical data for complementary cumulative distribution function (CCDF).\n * Shows P(X ≥ x) - the probability of getting at least x damage.\n *\n * @param asPercentages Whether to return percentages (0-100) or probabilities (0-1)\n * @returns Pure data structure with support and complementary cumulative probabilities\n *\n * @example\n * query.toCCDFSeries()\n * // → {support: [0, 6, 12], data: [100, 94.8, 81.7]}\n */\n toCCDFSeries(asPercentages: boolean = true): {\n support: number[];\n data: number[];\n } {\n const originalSupport = this.combined.support();\n if (originalSupport.length === 0) {\n return { support: [], data: [] };\n }\n\n // Create complete integer range from min to max\n const minDamage = Math.min(...originalSupport);\n const maxDamage = Math.max(...originalSupport);\n const support = Array.from(\n { length: maxDamage - minDamage + 1 },\n (_, i) => minDamage + i\n );\n\n // Calculate CCDF: P(X ≥ x) = 1 - P(X < x)\n let cumulativeProbability = 0;\n const ccdfData: number[] = [];\n\n for (const damage of support) {\n // For CCDF at point x, we want P(X ≥ x) = 1 - P(X < x)\n // which is the total probability minus cumulative up to (but not including) x\n const ccdf = 1 - cumulativeProbability;\n ccdfData.push(asPercentages ? ccdf * 100 : ccdf);\n\n // Now add current probability for next iteration\n const bin = this.combined.map.get(damage);\n if (bin) {\n cumulativeProbability += bin.p;\n }\n }\n\n return {\n support,\n data: ccdfData,\n };\n }\n\n /*\n Statistics snapshot of the query.\n */\n\n /** Probability of doing strictly more than threshold damage (default >0). */\n probDamageGreaterThan(threshold = 0): number {\n let acc = 0;\n for (const [x, bin] of this.combined.map) if (x > threshold) acc += bin.p;\n return acc;\n }\n\n /** All outcome keys actually present (typed & ordered if you pass an order). */\n outcomeKeys(order?: OutcomeType[]): OutcomeType[] {\n const found = new Set<string>();\n for (const [, bin] of this.combined.map) {\n for (const k in bin.count)\n if (bin.count[k] && (bin.count[k] as number) > 0) found.add(k);\n }\n if (found.size === 0)\n [\"hit\", \"crit\", \"missNone\"].forEach((k) => found.add(k));\n const keys = Array.from(found).filter(\n (k) => order?.includes(k as OutcomeType) ?? true\n ) as OutcomeType[];\n if (order && order.length)\n keys.sort((a, b) => order.indexOf(a) + 999 - (order.indexOf(b) + 999));\n return keys;\n }\n\n /** Total probability per outcome across the PMF. */\n outcomeTotals(\n outcomes: OutcomeType[] = this.outcomeKeys()\n ): Map<OutcomeType, number> {\n const totals = new Map<OutcomeType, number>();\n outcomes.forEach((o) => totals.set(o, 0));\n for (const [, row] of this.combined.map) {\n for (const o of outcomes) {\n const p = (row.count[o] as number) || 0; // if your bins store per-outcome p; else derive via toLabeledTable\n totals.set(o, (totals.get(o) || 0) + p);\n }\n }\n return totals;\n }\n\n /** Conditional damage range per outcome (min/avg/max of X | outcome). */\n outcomeDamageRanges(\n outcomes: OutcomeType[] = this.outcomeKeys()\n ): Map<OutcomeType, { min: number; avg: number; max: number }> {\n // Use toLabeledTable to stay consistent with your existing attribution\n const table = this.toLabeledTable(outcomes);\n const ranges = new Map<\n OutcomeType,\n { min?: number; max?: number; sum: number; mass: number }\n >();\n outcomes.forEach((o) => ranges.set(o, { sum: 0, mass: 0 }));\n\n for (const row of table) {\n const dmg = row.damage as number;\n for (const o of outcomes) {\n const p = (row[o] as number) || 0; // joint mass at (damage, outcome)\n if (p > 0) {\n const r = ranges.get(o)!;\n r.sum += dmg * p;\n r.mass += p;\n if (r.min === undefined || dmg < r.min) r.min = dmg;\n if (r.max === undefined || dmg > r.max) r.max = dmg;\n }\n }\n }\n\n const out = new Map<\n OutcomeType,\n { min: number; avg: number; max: number }\n >();\n for (const o of outcomes) {\n const r = ranges.get(o)!;\n const avg = r.mass > 0 ? r.sum / r.mass : 0;\n out.set(o, { min: r.min ?? 0, avg, max: r.max ?? 0 });\n }\n return out;\n }\n\n /**\n * Snapshot of the distribution in the exact shape the UI consumes.\n * - outcome probabilities are \"at least one\" (and equal to \"all\" for a single PMF)\n * - damageRange is conditional on the outcome occurring\n */\n snapshot(order?: readonly OutcomeType[]): Snapshot {\n // 1) Discover which outcomes actually appear in this PMF\n const discovered = new Set<string>();\n for (const [, bin] of this.combined.map) {\n for (const k in bin.count) {\n if (bin.count[k] && (bin.count[k] as number) > 0) discovered.add(k);\n }\n }\n if (discovered.size === 0) {\n for (const k of DiceQuery.DEFAULT_OUTCOMES) discovered.add(k);\n }\n\n let outcomes = Array.from(discovered);\n\n // Optional filtering + ordering if a preferred order was provided\n if (order && order.length) {\n const inOrder = new Set(order);\n outcomes = outcomes.filter((k) => inOrder.has(k as OutcomeType));\n const rank = new Map(order.map((k, i) => [k, i]));\n outcomes.sort(\n (a, b) =>\n (rank.get(a as OutcomeType) ?? 999) -\n (rank.get(b as OutcomeType) ?? 999)\n );\n }\n\n // 2) Aggregate per-outcome mass and conditional damage ranges via labeled table\n const rows = this.toLabeledTable(outcomes as OutcomeType[]);\n\n const totals = new Map<OutcomeType, number>();\n const rangeAcc = new Map<\n OutcomeType,\n { min?: number; max?: number; sum: number; mass: number }\n >();\n for (const ot of outcomes) {\n totals.set(ot as OutcomeType, 0);\n rangeAcc.set(ot as OutcomeType, { sum: 0, mass: 0 });\n }\n\n for (const row of rows) {\n const dmg = row.damage as number;\n for (const ot of outcomes) {\n const p = (row[ot] as number) || 0;\n if (p <= 0) continue;\n totals.set(ot as OutcomeType, (totals.get(ot as OutcomeType) || 0) + p);\n\n const r = rangeAcc.get(ot as OutcomeType)!;\n r.sum += dmg * p;\n r.mass += p;\n if (r.min === undefined || dmg < r.min) r.min = dmg;\n if (r.max === undefined || dmg > r.max) r.max = dmg;\n }\n }\n\n const outcomeMap = new Map<OutcomeType, OutcomeSnapshot>();\n for (const ot of outcomes) {\n const total = totals.get(ot as OutcomeType) || 0;\n const r = rangeAcc.get(ot as OutcomeType)!;\n const avg = r.mass > 0 ? r.sum / r.mass : 0;\n outcomeMap.set(ot as OutcomeType, {\n atLeastOneProbability: total,\n allProbability: total, // single aggregate PMF: same value\n damageRange: { min: r.min ?? 0, avg, max: r.max ?? 0 },\n });\n }\n\n // 3) Scalars: mean, damageChance, and percentiles from the dense CDF\n const averageDPR = this.mean();\n\n let damageChance = 0; // P(total damage > 0)\n for (const [x, bin] of this.combined.map) if (x > 0) damageChance += bin.p;\n\n const { support, data } = this.toCDFSeries(false); // P(X ≤ x) in 0..1\n const quantile = (p: number) => {\n if (support.length === 0) return 0;\n for (let i = 0; i < support.length; i++)\n if (data[i] >= p) return support[i];\n return support[support.length - 1];\n };\n const percentiles = {\n p25: quantile(0.25),\n p50: quantile(0.5),\n p75: quantile(0.75),\n };\n\n return { averageDPR, damageChance, percentiles, outcomes: outcomeMap };\n }\n\n /**\n * PMF Transformation Methods\n *\n * These methods provide a fluent API for transforming dice queries by wrapping\n * the underlying PMF transformation methods. All operations work on the combined\n * PMF and return new DiceQuery instances.\n */\n\n /**\n * Returns a new DiceQuery with normalized probabilities (ensuring they sum to 1.0).\n *\n * @returns New DiceQuery with normalized combined PMF\n */\n normalize(): DiceQuery {\n return new DiceQuery([this.combined.normalize()]);\n }\n\n /**\n * Returns a new DiceQuery with low-probability outcomes removed.\n *\n * @param eps Minimum probability threshold (defaults to PMF epsilon)\n * @param keepFinalBin Whether to keep the highest damage bin regardless of probability\n * @returns New DiceQuery with compacted combined PMF\n */\n compact(eps?: number, keepFinalBin?: boolean): DiceQuery {\n return new DiceQuery([this.combined.compact(eps, keepFinalBin)]);\n }\n\n /**\n * Returns a new DiceQuery with an additional scaled branch added.\n * Useful for conditional outcomes like \"30% chance of opportunity attack\".\n *\n * @param branch DiceQuery to add as a scaled branch\n * @param probability Probability of the branch occurring (0-1)\n * @returns New DiceQuery combining this query with the scaled branch\n *\n * @example\n * const baseAttack = parse(\"(d20 + 5 AC 15) * (2d6 + 3)\");\n * const opportunityAttack = parse(\"(d20 + 5 AC 15) * (1d8 + 3)\");\n * const withOpportunity = baseAttack.addScaled(opportunityAttack, 0.3);\n */\n addScaled(branch: DiceQuery, probability: number): DiceQuery {\n return new DiceQuery([\n this.combined.addScaled(branch.combined, probability),\n ]);\n }\n\n /**\n * Returns a new DiceQuery with all probabilities scaled by a factor.\n * Used for conditional scenarios where the entire outcome has reduced probability.\n *\n * @param factor Scaling factor for probabilities\n * @returns New DiceQuery with scaled probabilities\n *\n * @example\n * const fullAttack = parse(\"(d20 + 5 AC 15) * (2d6 + 3)\");\n * const conditionalAttack = fullAttack.scaleMass(0.3); // 30% chance scenario\n */\n scaleMass(factor: number): DiceQuery {\n return new DiceQuery([this.combined.scaleMass(factor)]);\n }\n\n totalMass(): number {\n return this.combined.mass();\n }\n\n /**\n * Returns a new DiceQuery with damage values transformed by a function.\n * Useful for applying modifiers, resistances, or other damage transformations.\n *\n * @param damageTransformFunction Function to transform each damage value\n * @returns New DiceQuery with transformed damage values\n *\n * @example\n * const baseAttack = parse(\"2d6 + 3\");\n * const withResistance = baseAttack.mapDamage(dmg => Math.floor(dmg / 2)); // Half damage\n * const withBonus = baseAttack.mapDamage(dmg => dmg + 5); // +5 damage\n */\n mapDamage(\n damageTransformFunction: (damageValue: number) => number\n ): DiceQuery {\n return new DiceQuery([this.combined.mapDamage(damageTransformFunction)]);\n }\n\n /**\n * Returns a new DiceQuery with damage values scaled by a factor.\n * Convenient wrapper around mapDamage for multiplicative scaling.\n *\n * @param factor Scaling factor for damage values\n * @param rounding Rounding method: \"floor\" (default), \"round\", or \"ceil\"\n * @returns New DiceQuery with scaled damage values\n *\n * @example\n * const baseAttack = parse(\"2d6 + 3\");\n * const doubled = baseAttack.scaleDamage(2); // Double damage\n * const halfDamage = baseAttack.scaleDamage(0.5, \"round\"); // Half damage, rounded\n */\n scaleDamage(\n factor: number,\n rounding: \"floor\" | \"round\" | \"ceil\" = \"floor\"\n ): DiceQuery {\n return new DiceQuery([this.combined.scaleDamage(factor, rounding)]);\n }\n\n /**\n * Returns a new DiceQuery combining this query with another via convolution.\n * Equivalent to rolling both queries independently and adding results.\n * It is important to use this rather than combing()ing the PMFs directly!\n * This method maintains the provenance of the PMFs which is needed for damage attribution.\n * Combining the .combined PMFs directly is still valid for DPR calculations but\n * is not statistically sound for queries.\n *\n * @param other DiceQuery to combine with\n * @param eps Optional epsilon for precision control\n * @returns New DiceQuery representing the combined outcome\n *\n * @example\n * const mainAttack = parse(\"(d20 + 5 AC 15) * (2d6 + 3)\");\n * const bonusAttack = parse(\"(d20 + 3 AC 15) * (1d6 + 1)\");\n * const bothAttacks = mainAttack.convolve(bonusAttack);\n */\n convolve(other: DiceQuery): DiceQuery {\n const singles = [...this.singles, ...other.singles];\n return new DiceQuery(singles);\n }\n\n /**\n * First-success split over an ordered list of DISTINCT single-swing PMFs.\n * Each PMF may have different success/subset probabilities (from labels).\n *\n * successOutcome: e.g., [\"success\"] or [\"hit\", \"crit\"]\n * subsetOutcome: e.g., [\"subset\"] or [\"crit\"] where subset ⊆ success\n *\n * Returns tuple: [pFirstNonSubset, pFirstSubset, pAnySuccess, pNone]\n */\n public firstSuccessSplit(\n successOutcome: string | string[],\n subsetOutcome: string | string[],\n eps = EPS\n ): readonly [pSuccess: number, pSubset: number, pAny: number, pNone: number] {\n const pmfs = this.singles;\n if (!pmfs.length) {\n throw new Error(\"firstSuccessSplitFromPMFs: pmfs must be non-empty\");\n }\n\n const toArr = (x: string | string[]) => (Array.isArray(x) ? x : [x]);\n const clamp01 = (x: number) => Math.max(0, Math.min(1, x));\n const tol = Math.max(eps, 8 * Number.EPSILON);\n\n // Per-event probabilities from each PMF via DiceQuery([pmf])\n const per = pmfs.map((pmf) => {\n const dq = new DiceQuery([pmf]);\n const pS = dq.probAtLeastOne(toArr(successOutcome) as any);\n const pB = dq.probAtLeastOne(toArr(subsetOutcome) as any);\n if (pB - pS > eps) {\n throw new Error(\n \"firstSuccessSplitFromPMFs: P(subset) > P(success) for an event. Ensure subset ⊆ success.\"\n );\n }\n return { pS, pB };\n });\n\n // Aggregate with running miss prefix\n let missSoFar = 1;\n let pFirstSubset = 0;\n let pFirstNonSubset = 0;\n let pNone = 1;\n\n for (const { pS, pB } of per) {\n pFirstSubset += missSoFar * pB;\n pFirstNonSubset += missSoFar * (pS - pB);\n const miss = 1 - pS;\n missSoFar *= miss;\n pNone *= miss;\n }\n\n const pAny = 1 - pNone;\n\n // Clamp and sanity check\n const a = clamp01(pFirstNonSubset);\n const b = clamp01(pFirstSubset);\n const any = clamp01(pAny);\n const none = clamp01(pNone);\n\n if (Math.abs(a + b - any) > tol * Math.max(1, any)) {\n throw new Error(\n `firstSuccessSplitFromPMFs: parts do not sum to pAny. got a+b=${\n a + b\n }, pAny=${any}`\n );\n }\n\n return [a, b, any, none] as const;\n }\n}\n// Make sure these types are exported in your public index, or inline them here.\nexport type OutcomeSnapshot = {\n atLeastOneProbability: number; // P(outcome occurs at least once)\n allProbability: number; // equal to atLeastOneProbability for a single aggregated PMF\n damageRange: { min: number; avg: number; max: number }; // conditional on the outcome occurring\n};\n\nexport type Snapshot = {\n averageDPR: number;\n damageChance: number; // P(total damage > 0)\n percentiles: { p25: number; p50: number; p75: number };\n outcomes: Map<OutcomeType, OutcomeSnapshot>;\n};\n","import { LRUCache } from \"../common/lru-cache\";\nimport type { Bin, OutcomeLabelMap, Rounding } from \"../common/types\";\nimport { EPS } from \"../common/types\";\nimport { DiceQuery } from \"./query\";\n\nconst cacheEnabled = true;\n\nexport const pmfCache = new LRUCache<string, PMF>(1000);\n\n/**\n * Probability Mass Function for discrete damage distributions.\n */\nexport class PMF {\n // Unique ID generator for anonymous PMFs to avoid cache key collisions\n private static __anonIdCounter = 1;\n\n // Cached computed values\n private _support?: number[];\n private _min?: number;\n private _max?: number;\n private _totalMass?: number;\n private _mean?: number;\n private _variance?: number;\n private _stdev?: number;\n\n constructor(\n public readonly map: Map<number, Bin> = new Map(),\n public readonly epsilon = EPS,\n public readonly normalized = false,\n public readonly identifier: string = `anon#${PMF.__anonIdCounter++}`,\n private _preservedProvenance = true\n ) {}\n\n static empty(epsilon = EPS, identifier = \"empty\") {\n return new PMF(new Map(), epsilon, false, identifier);\n }\n\n // This has a single bin at value 0, mass of 1\n static zero(epsilon = EPS): PMF {\n const m = new Map();\n m.set(0, { p: 1, count: { miss: 1 }, attr: {} });\n return new PMF(m, epsilon, false, \"zero\");\n }\n\n static delta(value: number, epsilon = EPS): PMF {\n return PMF.fromMap(new Map([[value, 1]]), epsilon);\n }\n\n // This creates a single bin at value 0, but with weight 0.\n static emptyMass(): PMF {\n return PMF.zero().scaleMass(0);\n }\n\n // Makes PMF iterable over [damage, bin] pairs.\n [Symbol.iterator](): IterableIterator<[number, Bin]> {\n return this.map[Symbol.iterator]();\n }\n\n static clearCache() {\n pmfCache.clear();\n }\n\n /**\n * Creates a conditional PMF from two branches (success and failure) and a probability.\n * This is the core logic for modeling any probabilistic event where there are two\n * distinct outcomes.\n */\n static branch(\n successPMF: PMF,\n failurePMF: PMF,\n successProbability: number\n ): PMF {\n let p = successProbability;\n if (!Number.isFinite(p)) p = 0;\n if (p < 0) p = 0;\n if (p > 1) p = 1;\n\n const q = 1 - p;\n\n // Fast paths\n if (p === 0) return failurePMF.scaleMass(1); // clone\n if (p === 1) return successPMF.scaleMass(1); // clone\n\n // Choose epsilon. You can also pick Math.min for a tighter threshold.\n const eps = successPMF.epsilon ?? failurePMF.epsilon;\n const id = `branch(${failurePMF.identifier}*${q.toFixed(6)} + ${\n successPMF.identifier\n }*${p.toFixed(6)})`;\n\n // Proper Bernoulli mixture: q·failure ⊕ p·success\n const out = PMF.empty(eps, id)\n .addScaled(failurePMF, q)\n .addScaled(successPMF, p);\n\n // Optional hygiene: drop exact zeros\n // return out.compact();\n return out;\n }\n\n /**\n * withProbability()\n *\n * A convenience wrapper around branch() for the common case where the \"failure\" branch is always zero().\n *\n * Think of this as a shortcut for:\n * pmf.gate(p, PMF.zero())\n *\n * Use this to model a *single* Bernoulli event — an outcome that either happens or doesn't,\n * like an opportunity attack that occurs with probability p, or a single attack that either hits or misses.\n *\n * This is **not** for combining multiple independent attacks or mutually exclusive multi-outcome scenarios.\n * - For multiple independent swings, use DiceQuery with separate PMFs for each attack.\n * - For modeling \"first success\" logic across multiple attacks (like Sneak Attack or Smite)\n * use query.firstSuccessSplit() to get the exact probabilities.\n * - For scenarios with several mutually exclusive outcomes (like crit vs hit vs none), use PMF.exclusive().\n *\n */\n static withProbability(successPMF: PMF, probability: number): PMF {\n return PMF.branch(successPMF, PMF.zero(), probability);\n }\n\n /**\n * gate()\n *\n * A conditional wrapper around branch() that applies this PMF with probability `p`,\n * and applies a provided fallback PMF otherwise.\n *\n * This is useful for modeling a binary choice between two outcomes:\n * - The \"success\" outcome (this PMF) happens with probability `p`.\n * - The \"failure\" outcome (fallback PMF) happens with probability `1 - p`.\n *\n * Examples:\n * - 25% chance to include an opportunity attack, otherwise nothing:\n * attackPMF.gate(0.25, PMF.zero())\n *\n * - 50% chance to deal fireball damage, otherwise cone of cold damage:\n * fireballPMF.gate(0.5, coneOfColdPMF)\n *\n * Relationship to other helpers:\n * - **withProbability()** is a shortcut for the common case where the fallback is `PMF.zero()`.\n * - **exclusive()** is for three or more mutually exclusive outcomes (e.g., crit vs hit vs none).\n *\n * @param p Probability of applying this PMF (between 0 and 1).\n * @param fallback PMF to apply when this PMF is *not* selected.\n * @returns A new PMF representing the weighted mixture of this PMF and the fallback.\n */\n gate(p: number, zero: PMF) {\n return PMF.branch(this, zero, p);\n }\n\n /**\n * PMF.exclusive()\n *\n * Builds a single PMF from a set of mutually exclusive weighted outcomes.\n * Exactly one of the provided options will occur.\n *\n * Each option has:\n * - A PMF representing its outcome (e.g., damage dice).\n * - A weight representing its probability of being selected.\n *\n * Notes:\n * - If total weight < 1 (within eps), leftover mass is assumed to be PMF.zero()\n *\n * @param options Array of `{ pmf, weight }` or `[PMF, number]`.\n * @param eps Optional tolerance for floating point rounding.\n */\n static exclusive(\n options: Array<{ pmf: PMF; weight: number } | [PMF, number]>,\n eps = EPS\n ): PMF {\n const items = options.map((o) =>\n Array.isArray(o) ? { pmf: o[0], weight: o[1] } : o\n );\n\n // Validate weights\n for (const { weight } of items) {\n if (!Number.isFinite(weight) || weight < -eps) {\n throw new Error(`PMF.exclusive: invalid weight ${weight}.`);\n }\n }\n\n // Sum and check\n let totalWeight = items.reduce((s, { weight }) => s + weight, 0);\n\n // Normalize tiny negatives to 0 and tiny overshoot to 1 when within eps\n if (Math.abs(totalWeight) <= eps) totalWeight = 0;\n if (Math.abs(1 - totalWeight) <= eps) totalWeight = 1;\n\n if (totalWeight > 1 + EPS) {\n throw new Error(\n `PMF.exclusive: total weight ${totalWeight} exceeds 1. (epsilon: ${eps})`\n );\n }\n\n // Accumulate scaled components, skipping near-zero weights\n let out = PMF.empty(eps);\n for (const { pmf, weight } of items) {\n if (weight > eps) out = out.addScaled(pmf, weight);\n }\n\n // Add leftover mass at zero outcome\n const leftover = Math.max(0, 1 - totalWeight);\n if (leftover > eps) {\n out = out.addScaled(PMF.zero(), leftover);\n }\n\n return out;\n }\n\n /**\n * PMF.mix()\n *\n * Builds a PMF as a linear combination of input PMFs with the given weights.\n * Unlike `exclusive`, this does NOT:\n * - enforce that weights sum to 1\n * - add leftover probability to δ0 (PMF.zero())\n *\n * Use when outcomes are not mutually exclusive, or for interpolation/blending.\n *\n * @param options Array of `{ pmf, weight }` or `[PMF, number]`.\n * @param eps Optional tolerance for skipping tiny weights.\n */\n static mix(\n options: Array<{ pmf: PMF; weight: number } | [PMF, number]>,\n eps = EPS\n ): PMF {\n const items = options.map((o) =>\n Array.isArray(o) ? { pmf: o[0], weight: o[1] } : o\n );\n\n // Validate weights, but do not constrain their sum.\n for (const { weight } of items) {\n if (!Number.isFinite(weight)) {\n throw new Error(`PMF.mix: invalid weight ${weight}.`);\n }\n }\n\n let out = PMF.empty(eps);\n for (const { pmf, weight } of items) {\n if (Math.abs(weight) <= eps) continue; // ignore crumbs\n out = out.addScaled(pmf, weight);\n }\n return out;\n }\n /**\n * Adds damage attribution metadata to this PMF based on existing count metadata.\n * For each bin, sets attr[outcome] = damage × count[outcome].\n *\n * This enables damage attribution charts to work with builder-generated PMFs.\n * The parser generates attr automatically, but builder PMFs only have count.\n *\n * @returns New PMF with attr field populated in each bin\n */\n withAttribution(): PMF {\n // Fast path: if attr already exists, return this PMF unchanged\n // Check if any non-zero damage bin has attr\n for (const [damage, bin] of this.map) {\n if (damage !== 0 && bin.attr && Object.keys(bin.attr).length > 0) {\n return this; // Already has attribution\n }\n // Only check first non-zero bin for performance\n if (damage > 0) break;\n }\n\n const newMap = new Map<number, Bin>();\n\n for (const [damage, bin] of this.map) {\n const attr: OutcomeLabelMap = {};\n\n // For each outcome type in count, compute its damage contribution\n for (const outcome in bin.count) {\n const probability = bin.count[outcome] as number;\n if (probability > 0) {\n attr[outcome] = damage * probability;\n }\n }\n\n // Create new bin with attribution\n newMap.set(damage, {\n p: bin.p,\n count: { ...bin.count },\n attr: Object.keys(attr).length > 0 ? attr : undefined,\n });\n }\n\n // Use a different identifier to avoid cache collisions with non-attributed version\n return new PMF(\n newMap,\n this.epsilon,\n this.normalized,\n `${this.identifier}~attr`\n );\n }\n\n /**\n * General-purpose N-way mixture.\n * weights: Array of [weight, PMF].\n *\n * Example: PMF.mixN([\n * [pMiss, zero],\n * [pHit, hitPMF],\n * [pCrit, critPMF],\n * ]);\n */\n static mixN(weights: [number, PMF][], eps = EPS): PMF {\n // Treat tiny/negative as zero; keep performance clean\n const filtered = weights.filter(([w]) => w > eps);\n\n if (filtered.length === 0) {\n return PMF.emptyMass(); // not PMF.zero(): we want \"no mass\" mixture\n }\n\n // No need to normalize up front; we accumulate and blend by relative weight\n let acc: PMF | null = null;\n let sum = 0;\n\n for (const [w, pmf] of filtered) {\n if (acc === null) {\n acc = pmf;\n sum = w;\n } else {\n const q = w / (sum + w); // relative weight of the new component\n acc = PMF.branch(pmf, acc, q); // success=new pmf, failure=acc\n sum += w;\n }\n }\n\n // If everything got filtered out (all ~0), return empty mass\n return acc ?? PMF.emptyMass();\n }\n\n // This is a convenience method for when we use power\n // TODO: It can be smarter in the future, and we can also add it to query\n // That way statistics operations on invalid PMFs can throw an error\n // TODO… how can we detect if manually merging two queries' combined PMFs, as that loses provenance?\n private setPreservedProvenance(preserved: boolean) {\n if (!this._preservedProvenance && preserved) {\n throw new Error(\n \"Preserved provenance is already set to false, cannot fix that\"\n );\n }\n this._preservedProvenance = preserved;\n }\n\n public preservedProvenance(): boolean {\n return this._preservedProvenance;\n }\n\n private getPowerCacheKey(n: number, eps: number): string {\n const id = this.identifier;\n let key = `${id}`;\n for (let i = 1; i < n; i++) key += `+${id}`;\n return `${key}@${eps}`;\n }\n\n /**\n * Efficiently computes this PMF convolved with itself `n` times.\n * Uses exponentiation by squaring to reduce total convolutions.\n * n must be a positive integer.\n * *\n * * NOTE: This folds multiple independent attacks into a single PMF.\n * As a result, The power() method causes a loss of data provenance.\n * This is ONLY SAFE if you are trying to calculate masses.\n * If you want to query any atLeast probabilities, you should use the DiceQuery class instead without power().\n */\n power(n: number, eps = this.epsilon): PMF {\n if (!Number.isInteger(n) || n <= 0) {\n throw new Error(\"power(n): n must be a positive integer\");\n }\n if (n === 1) return this;\n\n const epsilon = eps ?? this.epsilon;\n\n const key = this.getPowerCacheKey(n, epsilon);\n if (cacheEnabled) {\n const cached = pmfCache?.get(key);\n if (cached) return cached;\n }\n\n // Start from the base PMF and accumulate n-1 additional powers\n let base: PMF = this.normalized ? this : this.normalize();\n let result: PMF = base;\n let exp = n - 1;\n\n while (exp > 0) {\n if (exp & 1) {\n result = result.convolve(base, epsilon);\n }\n exp >>= 1;\n if (exp > 0) {\n base = base.convolve(base, epsilon);\n }\n }\n\n result.setPreservedProvenance(false);\n if (cacheEnabled) {\n pmfCache?.set(key, result);\n }\n return result;\n }\n\n /*\n * Helper for chaining multiple identical attacks\n */\n replicate(n: number): PMF[] {\n if (!Number.isInteger(n) || n <= 0) {\n throw new Error(\"combineN(n): n must be a positive integer\");\n }\n if (n === 1) return [this];\n return Array.from({ length: n }, () => this);\n }\n\n mass(): number {\n if (this._totalMass === undefined) {\n let totalProbabilityMass = 0;\n for (const { p } of this.map.values()) {\n totalProbabilityMass += p;\n }\n this._totalMass = totalProbabilityMass;\n }\n return this._totalMass;\n }\n\n outcomeMass(outcome: string): number {\n let totalProbabilityMass = 0;\n for (const { p, count } of this.map.values()) {\n totalProbabilityMass += p * ((count[outcome] as number) ?? 0);\n }\n return totalProbabilityMass;\n }\n\n // Helper for testing\n faceTotal(): number {\n return [...this.map.keys()].reduce((sum, key) => sum + key, 0);\n }\n\n normalize(): PMF {\n if (this.normalized) return this;\n const normalizationFactor = this.mass();\n if (normalizationFactor === 0) return this;\n\n const normalizedMap = new Map<number, Bin>();\n for (const [damageValue, probabilityBin] of this.map) {\n const normalizedProbability = probabilityBin.p / normalizationFactor;\n const normalizedCount: OutcomeLabelMap = {};\n\n for (const labelKey in probabilityBin.count) {\n normalizedCount[labelKey] =\n (probabilityBin.count[labelKey] as number) / normalizationFactor;\n }\n\n let normalizedAttributes: OutcomeLabelMap | undefined;\n if (probabilityBin.attr) {\n normalizedAttributes = {};\n for (const labelKey in probabilityBin.attr) {\n normalizedAttributes[labelKey] =\n (probabilityBin.attr[labelKey] as number) / normalizationFactor;\n }\n }\n\n normalizedMap.set(damageValue, {\n p: normalizedProbability,\n count: normalizedCount,\n attr: normalizedAttributes,\n });\n }\n return new PMF(normalizedMap, this.epsilon, true, this.identifier);\n }\n\n /**\n * Returns a copy with negligible probabilities removed (p < eps).\n * If keepFinalBin is true, the bin with the largest key is always kept,\n * even if its probability is below eps. count/attr submaps are still cleaned.\n */\n compact(eps = this.epsilon, keepFinalBin = false): PMF {\n let maxKey = -Infinity;\n if (keepFinalBin) {\n for (const key of this.map.keys()) {\n if (key > maxKey) maxKey = key;\n }\n }\n\n const compactedMap = new Map<number, Bin>();\n\n for (const [damageValue, probabilityBin] of this.map) {\n const shouldKeep =\n probabilityBin.p >= eps || (keepFinalBin && damageValue === maxKey);\n\n if (!shouldKeep) continue;\n\n // Clean up count entries below epsilon (mutates the bin like your original)\n for (const labelKey in probabilityBin.count) {\n if (Math.abs(probabilityBin.count[labelKey] || 0) < eps) {\n delete probabilityBin.count[labelKey];\n }\n }\n\n // Clean up attr entries below epsilon\n if (probabilityBin.attr) {\n for (const labelKey in probabilityBin.attr) {\n if (Math.abs(probabilityBin.attr[labelKey] || 0) < eps) {\n delete probabilityBin.attr[labelKey];\n }\n }\n if (Object.keys(probabilityBin.attr).length === 0) {\n probabilityBin.attr = undefined;\n }\n }\n\n compactedMap.set(damageValue, probabilityBin);\n }\n\n return new PMF(compactedMap, eps, this.normalized, this.identifier);\n }\n\n // Note: The \"support\" of a PMF is the set of all non-zero probability outcomes.\n // This returns all damage values with non-zero probability, sorted ascending.\n support(): number[] {\n if (this._support === undefined) {\n this._support = [...this.map.keys()].sort((a, b) => a - b);\n }\n return this._support!;\n }\n\n // Minimum possible damage value.\n min(): number {\n if (this._min === undefined) {\n const support = this.support();\n this._min = support.length > 0 ? support[0] : 0;\n }\n return this._min;\n }\n\n // Maximum possible damage value.\n max(): number {\n if (this._max === undefined) {\n const support = this.support();\n this._max = support.length > 0 ? support[support.length - 1] : 0;\n }\n return this._max;\n }\n\n /**\n * Returns the expected (mean) damage value.\n * Cached for performance since this requires iterating through all bins.\n */\n mean(): number {\n if (this._mean === undefined) {\n let totalSum = 0;\n for (const [damageValue, probabilityBin] of this.map) {\n totalSum += damageValue * probabilityBin.p;\n }\n this._mean = totalSum;\n }\n return this._mean;\n }\n\n /**\n * Returns the variance of the damage distribution.\n * Cached for performance since this requires mean calculation plus iteration.\n */\n variance(): number {\n if (this._variance === undefined) {\n const meanValue = this.mean();\n let varianceSum = 0;\n for (const [damageValue, probabilityBin] of this.map) {\n const deviationFromMean = damageValue - meanValue;\n varianceSum += deviationFromMean * deviationFromMean * probabilityBin.p;\n }\n this._variance = varianceSum;\n }\n return this._variance;\n }\n\n /**\n * Returns the standard deviation of the damage distribution.\n */\n stdev(): number {\n if (this._stdev === undefined) {\n this._stdev = Math.sqrt(this.variance());\n }\n return this._stdev;\n }\n\n private static mergeInto(\n destinationMap: Map<number, Bin>,\n damageValue: number,\n binToAdd: Bin\n ) {\n const existingBin = destinationMap.get(damageValue);\n if (!existingBin) {\n destinationMap.set(damageValue, {\n p: binToAdd.p,\n count: { ...binToAdd.count },\n attr: binToAdd.attr ? { ...binToAdd.attr } : undefined,\n });\n return;\n }\n\n existingBin.p += binToAdd.p;\n\n for (const labelKey in binToAdd.count) {\n existingBin.count[labelKey] =\n (existingBin.count[labelKey] || 0) +\n (binToAdd.count[labelKey] as number);\n }\n\n if (binToAdd.attr) {\n if (!existingBin.attr) {\n existingBin.attr = {};\n }\n for (const labelKey in binToAdd.attr) {\n existingBin.attr[labelKey] =\n (existingBin.attr[labelKey] || 0) +\n (binToAdd.attr[labelKey] as number);\n }\n }\n }\n\n // Convenience method\n add(other: PMF): PMF {\n return this.addScaled(other, 1);\n }\n\n /**\n * Returns a new PMF with a scaled branch added to this one.\n * The branch PMF is scaled by the given probability before merging\n * This will be very useful for conditional effects and for being\n * able to model \"I can probably have this opportunity attack 40% of rounds\"\n * Example: `pmf.addScaled(critBranch, 0.05)` → PMF including 5% crit outcomes\n */\n addScaled(branch: PMF, probability: number): PMF {\n if (probability === 0) return this;\n\n const resultMap = new Map<number, Bin>();\n for (const [dmg, bin] of this.map) {\n resultMap.set(dmg, {\n p: bin.p,\n count: { ...bin.count },\n attr: bin.attr ? { ...bin.attr } : undefined,\n });\n }\n\n for (const [damageValue, probabilityBin] of branch.map) {\n const scaledCount: OutcomeLabelMap = {};\n for (const k in probabilityBin.count) {\n scaledCount[k] = probability * (probabilityBin.count[k] as number);\n }\n\n let scaledAttributes: OutcomeLabelMap | undefined;\n if (probabilityBin.attr) {\n scaledAttributes = {};\n for (const k in probabilityBin.attr) {\n scaledAttributes[k] =\n probability * (probabilityBin.attr[k] as number);\n }\n }\n\n PMF.mergeInto(resultMap, damageValue, {\n p: probability * probabilityBin.p,\n count: scaledCount,\n attr: scaledAttributes,\n });\n }\n\n return new PMF(\n resultMap,\n this.epsilon,\n false,\n `${this.identifier}+scaled(${branch.identifier},${probability})`\n );\n }\n\n scaleMass(factor: number): PMF {\n if (factor === 1) return this;\n\n const scaledMap = new Map<number, Bin>();\n for (const [damageValue, probabilityBin] of this.map) {\n const scaledCount: OutcomeLabelMap = {};\n for (const labelKey in probabilityBin.count) {\n scaledCount[labelKey] =\n (probabilityBin.count[labelKey] as number) * factor;\n }\n\n let scaledAttributes: OutcomeLabelMap | undefined;\n if (probabilityBin.attr) {\n scaledAttributes = {};\n for (const labelKey in probabilityBin.attr) {\n scaledAttributes[labelKey] =\n (probabilityBin.attr[labelKey] as number) * factor;\n }\n }\n\n scaledMap.set(damageValue, {\n p: probabilityBin.p * factor,\n count: scaledCount,\n attr: scaledAttributes,\n });\n }\n return new PMF(\n scaledMap,\n this.epsilon,\n false,\n `scale(${this.identifier},${factor})`\n );\n }\n\n mapDamage(damageTransformFunction: (damageValue: number) => number): PMF {\n const transformedMap = new Map<number, Bin>();\n for (const [originalDamage, probabilityBin] of this.map) {\n const transformedDamage = damageTransformFunction(originalDamage);\n PMF.mergeInto(transformedMap, transformedDamage, {\n p: probabilityBin.p,\n count: { ...probabilityBin.count },\n attr: probabilityBin.attr ? { ...probabilityBin.attr } : undefined,\n });\n }\n return new PMF(\n transformedMap,\n this.epsilon,\n this.normalized,\n `map(${this.identifier})`\n );\n }\n\n scaleDamage(\n factor: number,\n rounding: \"floor\" | \"round\" | \"ceil\" = \"floor\"\n ): PMF {\n const roundFunction =\n rounding === \"round\"\n ? Math.round\n : rounding === \"ceil\"\n ? Math.ceil\n : Math.floor;\n return this.mapDamage((damageValue) => roundFunction(damageValue * factor));\n }\n\n private getPMFCombineCacheKey(\n p1: PMF,\n p2: PMF,\n eps: number,\n raw: boolean\n ): string {\n const [id1, id2] = [p1.identifier, p2.identifier].sort();\n\n // tiny fingerprints so keys change if the underlying numbers changed\n const fp = (x: PMF) => {\n // robust + cheap: mass + size + face sum\n const m = x.mass().toFixed(12);\n const n = x.map.size;\n let faceSum = 0;\n for (const k of x.map.keys()) faceSum += k;\n return `${m}|${n}|${faceSum}`;\n };\n\n return `v4:${raw ? \"RAW\" : \"N\"}:${id1}+${id2}@${eps}|${fp(p1)}|${fp(p2)}`;\n }\n\n convolve(other: PMF, eps?: number, raw = false): PMF {\n const epsilon = eps ?? this.epsilon;\n\n // Normalize-by-value on non-raw path\n const norm = (x: PMF) =>\n raw ? x : Math.abs(x.mass() - 1) <= epsilon ? x : x.normalize();\n const A0 = norm(this);\n const B0 = norm(other);\n\n const [A, B] = A0.identifier <= B0.identifier ? [A0, B0] : [B0, A0];\n const cacheKey = this.getPMFCombineCacheKey(A, B, epsilon, raw);\n const cached = pmfCache?.get(cacheKey);\n if (cached) return cached;\n\n const combinedMap = new Map<number, Bin>();\n for (const [aVal, aBin] of A.map) {\n for (const [bVal, bBin] of B.map) {\n const p = aBin.p * bBin.p;\n const dmg = aVal + bVal;\n\n const count: OutcomeLabelMap = {};\n for (const k in aBin.count)\n count[k] = (count[k] || 0) + (aBin.count[k] as number) * bBin.p;\n for (const k in bBin.count)\n count[k] = (count[k] || 0) + (bBin.count[k] as number) * aBin.p;\n\n let attr: OutcomeLabelMap | undefined;\n if (aBin.attr || bBin.attr) {\n attr = {};\n if (aBin.attr)\n for (const k in aBin.attr)\n attr[k] = (attr[k] || 0) + (aBin.attr[k] as number) * bBin.p;\n if (bBin.attr)\n for (const k in bBin.attr)\n attr[k] = (attr[k] || 0) + (bBin.attr[k] as number) * aBin.p;\n }\n\n PMF.mergeInto(combinedMap, dmg, { p, count, attr });\n }\n }\n\n let result = new PMF(\n combinedMap,\n epsilon,\n !raw,\n `${A.identifier}${raw ? \"*\" : \"+\"}${B.identifier}`\n );\n\n // Enforce mass invariant: mass(out) = (raw? A.mass():1) * (raw? B.mass():1)\n const mExp = (raw ? A.mass() : 1) * (raw ? B.mass() : 1);\n const mGot = result.mass();\n if (mExp !== 0 && Math.abs(mGot - mExp) > epsilon) {\n result = result.scaleMass(mExp / mGot);\n }\n if (!raw && Math.abs(result.mass() - 1) > epsilon)\n result = result.normalize();\n\n pmfCache?.set(cacheKey, result);\n return result;\n }\n\n // 3) Nice wrapper so you can call pmf.combineRaw(other)\n combineRaw(other: PMF, eps?: number): PMF {\n return this.convolve(other, eps, true);\n }\n\n // Collapse repeated identical PMFs using power() and return a sorted list\n // Temporarily disabled for now. This was used for a performance optimization, but can lose data provenance.\n // private static collapseIdentical(pmfList: PMF[], eps: number): PMF[] {\n // const grouped = new Map<string, { pmf: PMF; count: number }>();\n // for (const pmf of pmfList) {\n // const id = pmf.identifier;\n // const g = grouped.get(id);\n // if (g) g.count++;\n // else grouped.set(id, { pmf, count: 1 });\n // }\n\n // if (grouped.size >= pmfList.length) return pmfList;\n\n // const collapsed: PMF[] = [];\n // for (const { pmf, count } of grouped.values()) {\n // collapsed.push(count > 1 ? pmf.power(count, eps) : pmf);\n // }\n\n // // Stable order for better cache locality\n // collapsed.sort((a, b) =>\n // a.identifier < b.identifier ? -1 : a.identifier > b.identifier ? 1 : 0\n // );\n // return collapsed;\n // }\n\n // Reduce a list of PMFs by left-folding convolve() with the given eps\n private static reduceConvolveLeft(pmfList: PMF[], eps: number): PMF {\n let result = pmfList[0];\n for (let i = 1; i < pmfList.length; i++) {\n result = result.convolve(pmfList[i], eps);\n }\n return result;\n }\n\n /**\n * Convolves multiple PMFs using linear convolution with automatic caching.\n * Uses a left-to-right accumulation approach for maximum cache reuse.\n * Each convolve() call automatically uses the convolution cache for performance.\n *\n * This linear approach provides better cache hits than pairwise because:\n * - Intermediate results are more predictable and stable\n * - Similar PMF lists share common prefixes (A+B, (A+B)+C, etc.)\n * - Order-independent cache keys work better with consistent build patterns\n */\n static convolveMany(pmfList: PMF[], eps = EPS): PMF {\n if (pmfList.length === 0) return PMF.empty(eps);\n if (pmfList.length === 1) return pmfList[0];\n\n // Optimization: Group identical PMFs and use power() to collapse repeats\n // If nothing collapses, this returns the same array reference.\n // const collapsed = PMF.collapseIdentical(pmfList, eps);\n\n // Optimization: Linear combination with automatic intermediate caching\n // Whether collapsed or not, reduce via left-folded convolved()\n return PMF.reduceConvolveLeft(pmfList, eps);\n }\n\n toJSON() {\n return JSON.stringify({\n bins: [...this.map.entries()],\n normalized: this.normalized,\n identifier: this.identifier,\n });\n }\n\n static fromJSON(jsonData: {\n bins: Array<[number, Bin]>;\n normalized?: boolean;\n identifier?: string;\n }) {\n return new PMF(\n new Map(jsonData.bins),\n EPS,\n !!jsonData.normalized,\n jsonData.identifier || \"fromJSON\"\n );\n }\n\n /**\n * Relative pruning with optional top-K floor.\n * Keeps bins with p >= epsRel * peak, always keeps min and max damage,\n * optionally guarantees at least `minBins` survivors by adding top-K.\n * Returns a new, non-normalized PMF.\n */\n prune(epsRel: number, minBins = 0): PMF {\n const size = this.map.size;\n if (size === 0) return this;\n\n // One pass: peak, min, max\n let peak = 0;\n let minDamage = Number.POSITIVE_INFINITY;\n let maxDamage = Number.NEGATIVE_INFINITY;\n for (const [dmg, bin] of this.map) {\n if (bin.p > peak) peak = bin.p;\n if (dmg < minDamage) minDamage = dmg;\n if (dmg > maxDamage) maxDamage = dmg;\n }\n if (peak === 0)\n return new PMF(new Map(this.map), epsRel, false, this.identifier);\n\n const thresh = epsRel * peak;\n const entries = [...this.map.entries()];\n\n // Protect endpoints\n const survivorsByDmg = new Map<number, Bin>();\n const protect = (d: number) => {\n const b = this.map.get(d);\n if (b) survivorsByDmg.set(d, b);\n };\n protect(minDamage);\n if (maxDamage !== minDamage) protect(maxDamage);\n\n // Relative survivors\n for (const [dmg, bin] of entries) {\n if (bin.p >= thresh) survivorsByDmg.set(dmg, bin);\n }\n\n // Enforce minBins via top-K if requested\n if (minBins > 0 && survivorsByDmg.size < minBins) {\n // Sort all entries by probability desc (or replace with Quickselect for O(n))\n entries.sort((a, b) => b[1].p - a[1].p);\n for (const [dmg, bin] of entries) {\n if (!survivorsByDmg.has(dmg)) {\n survivorsByDmg.set(dmg, bin);\n if (survivorsByDmg.size >= minBins) break;\n }\n }\n }\n\n // Rebuild map, pruning tiny count/attr entries with the same threshold\n const prunedMap = new Map<number, Bin>();\n for (const [dmg, bin] of survivorsByDmg) {\n const newCount: OutcomeLabelMap = {};\n for (const k in bin.count) {\n const v = bin.count[k] as number;\n if (Math.abs(v) >= thresh) newCount[k] = v;\n }\n let newAttr: OutcomeLabelMap | undefined;\n if (bin.attr) {\n for (const k in bin.attr) {\n const v = bin.attr[k] as number;\n if (Math.abs(v) >= thresh) {\n if (!newAttr) newAttr = {};\n newAttr[k] = v;\n }\n }\n }\n prunedMap.set(dmg, { p: bin.p, count: newCount, attr: newAttr });\n }\n\n // Return non-normalized PMF\n return new PMF(prunedMap, epsRel, false, `prune(${this.identifier})`);\n }\n\n /** NEW - REVIEW IF THESE ARE USEFUL OR DUPLCIATIVE? */\n /** Probability mass at exactly x. */\n pAt(x: number): number {\n return this.map.get(x)?.p ?? 0;\n }\n\n /** Dense integer support from min..max (inclusive).\n * Useful for showing empty bars in charts.\n */\n denseSupport(): number[] {\n const s = this.support();\n if (s.length === 0) return [];\n const lo = Math.min(...s),\n hi = Math.max(...s);\n return Array.from({ length: hi - lo + 1 }, (_, i) => lo + i).sort(\n (a, b) => a - b\n );\n }\n\n /** CDF at x: P(X ≤ x). */\n cdfAt(x: number): number {\n let acc = 0;\n for (const [val, bin] of this.map) if (val <= x) acc += bin.p;\n return acc;\n }\n\n /** Quantile / inverse CDF for p in [0,1]. Returns smallest x with CDF ≥ p. */\n quantile(p: number): number {\n if (this.map.size === 0) return 0;\n const s = this.support().sort((a, b) => a - b);\n let acc = 0;\n for (const x of s) {\n acc += this.pAt(x);\n if (acc >= p) return x;\n }\n return s[s.length - 1];\n }\n\n /** Get outcome probability at specific damage value. */\n outcomeAt(damage: number, outcome: string): number {\n return (this.map.get(damage)?.count[outcome] as number) ?? 0;\n }\n\n /** Get all outcome types present in this PMF. */\n outcomes(): string[] {\n const outcomeSet = new Set<string>();\n for (const [, bin] of this.map) {\n for (const outcome in bin.count) {\n if ((bin.count[outcome] as number) > 0) {\n outcomeSet.add(outcome);\n }\n }\n }\n return Array.from(outcomeSet).sort();\n }\n\n /** Get total probability of an outcome across all damage values. */\n outcomeProbability(outcome: string): number {\n let total = 0;\n for (const [, bin] of this.map) {\n total += (bin.count[outcome] as number) ?? 0;\n }\n return total;\n }\n\n /** Get damage attribution for an outcome at specific damage value. */\n outcomeAttributionAt(damage: number, outcome: string): number {\n return (this.map.get(damage)?.attr?.[outcome] as number) ?? 0;\n }\n\n /** Get all outcome data at specific damage value. */\n binAt(damage: number): {\n p: number;\n count: Record<string, number>;\n attr?: Record<string, number>;\n } | null {\n const bin = this.map.get(damage);\n if (!bin) return null;\n\n return {\n p: bin.p,\n count: { ...bin.count } as Record<string, number>,\n attr: bin.attr ? ({ ...bin.attr } as Record<string, number>) : undefined,\n };\n }\n\n /** Check if outcome exists in this PMF. */\n hasOutcome(outcome: string): boolean {\n for (const [, bin] of this.map) {\n if (((bin.count[outcome] as number) ?? 0) > 0) {\n return true;\n }\n }\n return false;\n }\n\n tailProbGE(t: number): number {\n let s = 0;\n for (const [x, rec] of this) {\n const p = typeof rec === \"number\" ? rec : rec.p;\n if (p > 0 && x >= t) s += p;\n }\n return s;\n }\n\n tailProbGT(t: number): number {\n let s = 0;\n for (const [x, rec] of this) {\n if (x > t) s += rec.p;\n }\n return s;\n }\n\n /**\n * Returns a new PMF containing only bins where the specified outcome has non-zero probability.\n * This creates a marginal distribution for the given outcome type, with probabilities\n * scaled to represent the unconditional mass attributable to that outcome.\n */\n filterOutcome(outcome: string): PMF {\n const filteredMap = new Map<number, Bin>();\n\n for (const [damageValue, bin] of this.map) {\n const outcomeCount = (bin.count[outcome] as number) ?? 0;\n\n // total paths that reached this bin (sum across labels)\n const totalCount = Object.values(bin.count ?? {}).reduce(\n (a, b) => (a ?? 0) + ((b as number) ?? 0),\n 0\n );\n\n if (outcomeCount > 0 && totalCount !== undefined && totalCount > 0) {\n // proportion of this bin's mass attributable to the outcome\n const proportion = outcomeCount / totalCount;\n\n // downweight p to the unconditional mass from the outcome only\n const newP = bin.p * proportion;\n\n const newCount: OutcomeLabelMap = { [outcome]: outcomeCount };\n\n let newAttr: OutcomeLabelMap | undefined;\n if (bin.attr && bin.attr[outcome] !== undefined) {\n // If attr is a count-like accumulator, scale it too.\n // If attr is already per-outcome only, you can just carry it over.\n newAttr = { [outcome]: (bin.attr[outcome] as number) * proportion };\n }\n\n filteredMap.set(damageValue, {\n p: newP,\n count: newCount,\n attr: newAttr,\n });\n }\n }\n\n return new PMF(\n filteredMap,\n this.epsilon,\n false, // don't normalize by default\n `filter(${this.identifier},${outcome})`\n );\n }\n /**\n * Calculates probabilities for first-success outcomes across n independent attempts.\n *\n * @param pSuccess - Total probability of any success on a single attempt.\n * @param pSpecial - Probability of a specific subset of successes (e.g., critical success).\n * @param n - Number of independent attempts.\n *\n * Returns:\n * - pSpecificSuccess: Probability that the first success was of the \"special\" type\n * - pGeneralSuccess: Probability that the first success was of the non-special type\n * - pNone: Probability that no successes occurred\n * - pAny: Probability that at least one success occurred\n */\n public static firstSuccessWeights(\n pSuccess: number,\n pSpecial: number,\n n: number\n ) {\n const pFail = 1 - pSuccess;\n const pFailAll = Math.pow(pFail, n);\n\n // Probability of at least one success\n const pAny = 1 - pFailAll;\n\n // Avoid divide-by-zero if pSuccess is 0\n const denom = pSuccess === 0 ? 1 : pSuccess;\n\n // Breakdown of first success type\n const pSpecificSuccess = (pSpecial * pAny) / denom;\n const pGeneralSuccess = ((pSuccess - pSpecial) * pAny) / denom;\n\n const pNone = 1 - pSpecificSuccess - pGeneralSuccess; // Should equal pFailAll\n\n return { pSpecificSuccess, pGeneralSuccess, pNone, pAny };\n }\n\n mapValues(\n f: (v: number) => number,\n eps: number = EPS,\n opts?: { rounding?: Rounding; preserveCounts?: boolean }\n ): PMF {\n const rounding = opts?.rounding ?? \"none\";\n const preserveCounts = opts?.preserveCounts ?? true;\n\n const round = (x: number) =>\n rounding === \"floor\"\n ? Math.floor(x)\n : rounding === \"ceil\"\n ? Math.ceil(x)\n : rounding === \"round\"\n ? Math.round(x)\n : x;\n\n // Accumulate probs and merged counts\n const probs = new Map<number, number>();\n const counts = new Map<number, Record<string, number>>();\n\n for (const [v, rec] of this) {\n if (Math.abs(rec.p) < eps) continue;\n const u = round(f(v));\n probs.set(u, (probs.get(u) ?? 0) + rec.p);\n\n if (preserveCounts) {\n // Merge counts if present\n const rec = this.map.get(v);\n const src = typeof rec === \"number\" ? undefined : rec?.count;\n if (src) {\n const dest = counts.get(u) ?? {};\n for (const k in src) {\n dest[k] = (dest[k] ?? 0) + (src[k] as number);\n }\n counts.set(u, dest);\n }\n }\n }\n\n // Build PMF with merged counts, then normalize\n const internal = new Map<number, Bin>();\n for (const [u, p] of probs) {\n internal.set(u, { p, count: counts.get(u) ?? {} });\n }\n // Normalize via pmfFromMap to keep one source of truth\n return PMF.fromMap(\n new Map(Array.from(internal, ([u, b]) => [u, b.p] as [number, number])),\n eps\n );\n }\n\n static fromMap(\n m: Map<number, number>,\n eps: number = EPS,\n { requireIntegerValues = true }: { requireIntegerValues?: boolean } = {}\n ): PMF {\n const filtered: Array<[number, number]> = [];\n for (const [v, p] of m) {\n if (!Number.isFinite(v) || !Number.isFinite(p)) continue;\n if (p <= 0 || Math.abs(p) < eps) continue;\n if (requireIntegerValues && !Number.isInteger(v)) {\n throw new Error(`fromMap: non-integer outcome ${v}`);\n }\n filtered.push([v, p]);\n }\n\n if (filtered.length === 0) {\n throw new Error(\"fromMap: empty or invalid input map\");\n }\n\n // Kahan sum for stability\n let sum = 0;\n let c = 0;\n for (const [, p] of filtered) {\n const y = p - c;\n const t = sum + y;\n c = t - sum - y;\n sum = t;\n }\n if (sum <= 0) throw new Error(\"pmfFromMap: probabilities sum to 0\");\n\n filtered.sort((a, b) => a[0] - b[0]);\n\n const internal = new Map<number, Bin>();\n for (const [v, p] of filtered) {\n internal.set(v, { p: p / sum, count: {} }); // keep count object present for consistency\n }\n return new PMF(internal, eps);\n }\n\n query(): DiceQuery {\n return new DiceQuery(this);\n }\n}\n","// dice.ts (internal)\n\nimport type {\n Bin,\n DamageDistribution,\n OutcomeLabelMap,\n OutcomeType,\n} from \"../common/types\";\nimport { EPS } from \"../common/types\";\nimport { PMF } from \"../pmf/pmf\";\n\n/**\n * @internal\n */\nexport class Dice {\n private readonly faces: DamageDistribution = {};\n public privateData: Record<string, any> = {};\n private outcomeData: Record<OutcomeType, DamageDistribution> = {} as Record<\n OutcomeType,\n DamageDistribution\n >;\n private hasHitDistributionCalculated = false;\n public identifier?: string;\n\n constructor(x: number = 0) {\n if (x <= 0) return;\n for (let i = 1; i <= x; i++) {\n this.faces[i] = 1;\n }\n }\n\n getOutcomeDistribution(key: OutcomeType): DamageDistribution | undefined {\n if (key === \"hit\") {\n this.ensureHitDistribution();\n }\n\n const distribution = this.outcomeData[key];\n if (distribution === undefined) return undefined;\n\n return { ...distribution };\n }\n\n getFullOutcomeDistribution(): Record<\n OutcomeType,\n DamageDistribution | undefined\n > {\n return { ...this.outcomeData };\n }\n\n setOutcomeDistribution(\n key: OutcomeType,\n data: DamageDistribution | undefined\n ): void {\n if (data) {\n this.outcomeData[key] = data;\n } else {\n delete this.outcomeData[key];\n }\n }\n\n hasOutcomeData(key: OutcomeType): boolean {\n if (key === \"hit\") {\n this.ensureHitDistribution();\n }\n const data = this.outcomeData[key];\n return data !== undefined && Object.keys(data).length > 0;\n }\n\n getOutcomeCount(key: OutcomeType, face: number): number {\n return this.outcomeData[key]?.[face] ?? 0;\n }\n\n getAverage(key: OutcomeType): number {\n const distribution = this.getOutcomeDistribution(key);\n if (!distribution) return 0;\n // TODO caching opportunity\n\n const totalCount = Object.values(distribution).reduce(\n (sum, count) => sum + count,\n 0\n );\n const expectedDamage = Object.entries(distribution).reduce(\n (sum, [damage, count]) => sum + Number(damage) * count,\n 0\n );\n if (totalCount === 0) return 0;\n return expectedDamage / totalCount;\n }\n\n // TODO this can be private later if we change how testing works\n calculateHitDistribution(): DamageDistribution {\n const hitValues: DamageDistribution = {};\n\n for (const [face, totalCount] of Object.entries(this.faces)) {\n const numFace = Number(face);\n let hitCount = totalCount;\n\n for (const outcomeType of [\n \"crit\",\n \"missNone\",\n \"missDamage\",\n \"saveHalf\",\n \"saveFail\",\n \"pc\",\n ] as Partial<OutcomeType>[]) {\n const distribution = this.getOutcomeDistribution(outcomeType);\n if (distribution && distribution[numFace]) {\n hitCount -= distribution[numFace];\n }\n }\n\n // Zero damage should not be counted as hits - they represent misses\n if (numFace === 0) {\n hitCount = 0;\n }\n\n //WARNING: This is checking for the bug in old inclusion-exclusion logic.\n if (hitCount < 0) {\n console.error(\"hitCount is <=0?\", face, totalCount, hitCount);\n hitCount = 0;\n }\n hitValues[numFace] = hitCount;\n }\n\n return hitValues;\n }\n\n private ensureHitDistribution(): void {\n if (!this.hasHitDistributionCalculated) {\n const hitValues = this.calculateHitDistribution();\n this.setOutcomeDistribution(\"hit\", hitValues);\n this.hasHitDistributionCalculated = true;\n }\n }\n\n // PRIVATE FUNCTIONS\n\n private binaryOp(\n other: Dice | number,\n op: (a: number, b: number) => number,\n diceConstructor?: () => Dice\n ): Dice {\n const result = diceConstructor ? diceConstructor() : new Dice();\n\n const isScalar = typeof other === \"number\";\n const keys1 = this.keys();\n\n for (const key1 of keys1) {\n const value1 = this.faces[key1]!;\n\n if (isScalar) {\n const resultKey = op(key1, other as number);\n result.increment(resultKey, value1);\n } else {\n const keys2 = other.keys();\n for (const key2 of keys2) {\n const value2 = other.faces[key2]!;\n const resultKey = op(key1, key2);\n result.increment(resultKey, value1 * value2);\n }\n }\n }\n\n return result;\n }\n\n private removeFaces(facesToRemove: number[]): Dice {\n const result = new Dice();\n\n for (const [key, value] of Object.entries(this.faces)) {\n const numKey = Number(key);\n if (!facesToRemove.includes(numKey)) {\n result.faces[numKey] = value;\n }\n }\n\n result.privateData = { ...this.privateData };\n result.outcomeData = { ...this.outcomeData };\n return result;\n }\n\n // PUBLIC FUNTIONS\n\n getFaceEntries(): [number, number][] {\n return Object.entries(this.faces).map(([k, v]) => [Number(k), v]);\n }\n\n getFaceMap(): DamageDistribution {\n return { ...this.faces };\n }\n\n get(face: number): number {\n return this.faces[face] ?? 0;\n }\n\n keys(): number[] {\n return Object.keys(this.faces).map(Number);\n }\n\n values(): number[] {\n return Object.values(this.faces);\n }\n\n total(): number {\n return Object.values(this.faces).reduce((sum, value) => sum + value, 0);\n }\n\n public setFace(key: number, value: number): void {\n this.faces[key] = value;\n }\n\n public static scalar(value: number): Dice {\n const result = new Dice();\n result.increment(value, 1);\n return result;\n }\n\n public maxFace(): number {\n const numericKeys = this.keys();\n\n if (numericKeys.length === 0) {\n throw new Error(\"No numeric faces found\");\n }\n\n return Math.max(...numericKeys);\n }\n\n public minFace(): number {\n const numericKeys = this.keys();\n\n if (numericKeys.length === 0) {\n throw new Error(\"No numeric faces found\");\n }\n\n return Math.min(...numericKeys);\n }\n\n public increment(face: number, count: number): void {\n const current = this.faces[face] || 0;\n this.faces[face] = current + count;\n }\n\n public normalize(scalar: number): Dice {\n const result = new Dice();\n\n for (const [face, count] of Object.entries(this.faces)) {\n result.faces[Number(face)] = count * scalar;\n }\n\n result.privateData = { ...this.privateData };\n result.outcomeData = { ...this.outcomeData };\n return result;\n }\n\n // OPERATIONS\n\n public add(other: Dice | number): Dice {\n return this.binaryOp(other, (a, b) => a + b);\n }\n\n public subtract(other: Dice | number): Dice {\n return this.binaryOp(other, (a, b) => a - b);\n }\n\n public conditionalApply(other: Dice | number): Dice {\n return this.binaryOp(other, (a, b) => (a === 0 ? 0 : 1) * b);\n }\n\n public multiply(other: Dice | number): Dice {\n return this.binaryOp(other, (a, b) => a * b);\n }\n\n public addNonZero(other: Dice | number): Dice {\n return this.binaryOp(other, (a, b) => (a !== 0 ? a + b : a));\n }\n\n public eq(other: Dice | number): Dice {\n return this.binaryOp(other, (a, b) => (a === b ? 1 : 0));\n }\n\n public max(other: Dice | number): Dice {\n return this.binaryOp(other, (a, b) => Math.max(a, b));\n }\n\n public min(other: Dice | number): Dice {\n return this.binaryOp(other, (a, b) => Math.min(a, b));\n }\n\n public advantage(): Dice {\n return this.max(this);\n }\n\n public ge(other: Dice | number): Dice {\n return this.binaryOp(other, (a, b) => (a >= b ? 0 : 1));\n }\n\n public divide(other: Dice | number): Dice {\n return this.binaryOp(other, (a, b) => a / b);\n }\n\n public divideRoundUp(other: Dice | number): Dice {\n return this.binaryOp(other, (a, b) => Math.ceil(a / b));\n }\n\n public divideRoundDown(other: Dice | number): Dice {\n return this.binaryOp(other, (a, b) => Math.floor(a / b));\n }\n\n public and(other: Dice | number): Dice {\n return this.binaryOp(other, (a, b) => (a && b ? 1 : 0));\n }\n\n private checkTarget(\n other: Dice | number,\n comparisonLogic: (roll: number, target: number) => number\n ): Dice {\n const createResult = () => {\n const result = new Dice();\n result.increment(0, 0); // Success\n result.increment(1, 0); // Failure\n return result;\n };\n\n return this.binaryOp(other, comparisonLogic, createResult);\n }\n\n public dc(other: Dice | number): Dice {\n const dcCheck = (a: number, b: number) => (a >= b ? 0 : 1);\n const result = this.checkTarget(other, dcCheck);\n // Mark this as a DC check (save mechanic) for proper attribute assignment\n result.privateData.isDCCheck = true;\n return result;\n }\n\n public ac(other: Dice | number): Dice {\n const acCheck = (a: number, b: number) => (a >= b ? a : 0);\n return this.checkTarget(other, acCheck);\n }\n\n public deleteFace(face: number): Dice {\n const result = new Dice();\n\n for (const [key, value] of Object.entries(this.faces)) {\n const numKey = Number(key);\n if (numKey !== face) {\n result.increment(numKey, value);\n }\n }\n\n result.privateData = { ...this.privateData };\n result.outcomeData = { ...this.outcomeData };\n return result;\n }\n\n public reroll(toReroll: Dice | number): Dice {\n const rerollDice =\n typeof toReroll === \"number\" ? Dice.scalar(toReroll) : toReroll;\n\n const removed = this.removeFaces(rerollDice.keys());\n let result = new Dice();\n\n for (const face of this.keys()) {\n const wasRerolled = rerollDice.keys().includes(face);\n result = result.combine(removed);\n if (wasRerolled) {\n result = result.combine(this);\n }\n }\n\n return result;\n }\n\n // This is not addition and not rolling two dice at once.\n // Instead, it’s mixing two distributions into a single weighted die.\n public combine(other: Dice | number): Dice {\n if (typeof other === \"number\") {\n other = Dice.scalar(other);\n }\n\n // Start by copying \"other\" into a new Dice object\n const result = new Dice();\n for (const [key, value] of Object.entries(other.faces)) {\n result.faces[Number(key)] = value;\n }\n\n // Build the \"except\" dice and add faces from `this` to result\n const except = new Dice();\n for (const [key, value] of Object.entries(this.faces)) {\n const numKey = Number(key);\n result.increment(numKey, value);\n\n // If the key did not already exist in `other`, we remove it from `except`\n if (!(numKey in other.faces)) {\n except.increment(numKey, value); // still tracked in except\n }\n }\n\n result.privateData = { ...this.privateData, except: other };\n result.outcomeData = { ...this.outcomeData };\n return result;\n }\n\n public combineInPlace(other: Dice): void {\n for (const [key, value] of Object.entries(other.faces)) {\n const numKey = Number(key);\n const current = this.faces[numKey] || 0;\n this.faces[numKey] = current + value;\n }\n }\n\n public percent(): DamageDistribution {\n const total = this.total();\n const result: DamageDistribution = {};\n\n for (const [face, count] of Object.entries(this.faces)) {\n result[Number(face)] = count / total;\n }\n\n return result;\n }\n\n public average(): number {\n const total = this.total();\n if (total === 0) return 0;\n\n let sum = 0;\n for (const [key, value] of Object.entries(this.faces)) {\n sum += Number(key) * value;\n }\n\n return sum / total;\n }\n\n /*\n * Convert dice to PMF using OutcomeType labels directly from damage distribution.\n * This is much cleaner than the original complex distribution conversion.\n */\n public toPMF(numEpsilon: number = EPS): PMF {\n const total = this.total();\n if (total === 0) return PMF.empty(numEpsilon);\n\n // Ensure hit distribution is calculated before using it\n this.ensureHitDistribution();\n\n const map = new Map<number, Bin>();\n\n // Outcome distributions (counts, not probabilities)\n const hitDistro = this.getOutcomeDistribution(\"hit\") || {};\n const critDistro = this.getOutcomeDistribution(\"crit\") || {};\n const missDistro = this.getOutcomeDistribution(\"missDamage\") || {};\n const saveDistro = this.getOutcomeDistribution(\"saveHalf\") || {};\n const pcDistro = this.getOutcomeDistribution(\"pc\") || {};\n\n let isSaveHalf = false;\n for (const halfDamage of Object.keys(saveDistro).map(Number)) {\n const fullDamage = halfDamage * 2;\n if (fullDamage > 0 && hitDistro[fullDamage]) {\n isSaveHalf = true;\n break;\n }\n }\n\n const isDCCheck = this.privateData.isDCCheck === true;\n\n const clampNonNeg = (x: number) => (x < 0 && x > -1e-15 ? 0 : x);\n\n // Process each face value\n for (const [faceStr, faceCountRaw] of Object.entries(this.getFaceMap())) {\n const face = Number(faceStr);\n const faceCount = Number(faceCountRaw);\n\n // Skip structurally present but empty bins early\n if (faceCount <= 0) continue;\n\n let p = faceCount / total;\n p = clampNonNeg(p);\n\n // Always drop exact zeros to keep PMF semantics clean\n if (!(p > 0)) continue;\n\n // Optional pruning only when epsilon is enabled\n if (numEpsilon >= 0 && p < numEpsilon) continue;\n\n const count: OutcomeLabelMap = {};\n const attr: OutcomeLabelMap = {};\n\n // Add distribution counts and attributions\n if (hitDistro[face]) {\n const c = clampNonNeg(hitDistro[face] / total);\n if (c > 0) {\n if (isSaveHalf || isDCCheck) {\n count.saveFail = c; // full damage on failed save\n attr.saveFail = clampNonNeg((face * hitDistro[face]) / total);\n } else {\n count.hit = c;\n attr.hit = clampNonNeg((face * hitDistro[face]) / total);\n }\n }\n }\n\n if (critDistro[face]) {\n const c = clampNonNeg(critDistro[face] / total);\n if (c > 0) {\n count.crit = c;\n attr.crit = clampNonNeg((face * critDistro[face]) / total);\n }\n }\n\n if (missDistro[face]) {\n const c = clampNonNeg(missDistro[face] / total);\n if (c > 0) {\n count.missDamage = c;\n attr.missDamage = clampNonNeg((face * missDistro[face]) / total);\n }\n }\n\n if (saveDistro[face]) {\n const c = clampNonNeg(saveDistro[face] / total);\n if (c > 0) {\n if (isSaveHalf) {\n count.saveHalf = c; // half damage on successful save\n attr.saveHalf = clampNonNeg((face * saveDistro[face]) / total);\n } else {\n count.saveFail = (count.saveFail ?? 0) + c; // regular fail\n attr.saveFail = clampNonNeg(\n (attr.saveFail ?? 0) + (face * saveDistro[face]) / total\n );\n }\n }\n }\n\n if (pcDistro[face]) {\n const c = clampNonNeg(pcDistro[face] / total);\n if (c > 0) {\n count.pc = c;\n attr.pc = clampNonNeg((face * pcDistro[face]) / total);\n }\n }\n\n // Handle faces with no specific distribution (missNone) for non-save and non-DC checks\n if (!isSaveHalf && !isDCCheck) {\n const distroCountRaw =\n (hitDistro[face] || 0) +\n (critDistro[face] || 0) +\n (missDistro[face] || 0) +\n (saveDistro[face] || 0) +\n (pcDistro[face] || 0);\n\n const unaccountedCount = clampNonNeg(faceCount - distroCountRaw);\n if (unaccountedCount > 0) {\n const frac = clampNonNeg(unaccountedCount / total);\n if (frac > 0) {\n count.missNone = (count.missNone ?? 0) + frac;\n // missNone does 0 damage, so no attr contribution\n }\n }\n }\n\n const bin: Bin = { p, count };\n if (Object.keys(attr).length > 0) {\n bin.attr = attr;\n }\n\n map.set(face, bin);\n }\n\n const identifier = this.identifier || \"ERROR\";\n if (identifier === \"ERROR\") {\n console.error(\"Dice identifier is undefined\", this);\n }\n\n // Normalize, drop zeros again if any snuck in, then compaction and pruning\n return new PMF(map, numEpsilon, true, identifier).compact(numEpsilon, true);\n }\n}\n\nexport type _DiceInternal = never;\n","import { LRUCache } from \"../common/lru-cache\";\nimport type { OutcomeType } from \"../common/types\";\nimport type { PMF } from \"../pmf/pmf\";\nimport { Dice } from \"./dice\";\n\ntype DiceOperation = ((this: Dice, other: Dice | number) => Dice) & {\n unary?: boolean;\n};\n\n/**\n * Internal parse cache for PMFs produced from string expressions.\n * Keyed by cleaned expression (spaces stripped, lowercased) and optional `n` value.\n */\nconst parseCache = new LRUCache<string, PMF>(1000);\n\nlet cachingEnabled = true;\n\n/** Enable or disable the internal parse cache. */\nexport function setCachingEnabled(enabled: boolean): void {\n cachingEnabled = enabled;\n if (!enabled) clearParserCache();\n}\n\n/** Returns whether the internal parse cache is currently enabled. */\nexport function getCachingEnabled(): boolean {\n return cachingEnabled;\n}\n\n/** Clears the internal parse cache. */\nexport function clearParserCache(): void {\n parseCache.clear();\n}\n\n/**\n * Parse a dice expression into a PMF.\n *\n * - Expression is case-insensitive and ignores spaces.\n */\nexport function parse(expression: string, n: number = 0): PMF {\n // Check cache first if enabled\n const cleaned = expression.replace(/ /g, \"\").toLowerCase();\n\n if (cachingEnabled) {\n const cacheKey = `${cleaned}:${n}`;\n const cached = parseCache.get(cacheKey);\n if (cached) return cached;\n }\n\n const chars = [...cleaned];\n\n let result: Dice | undefined = undefined;\n try {\n result = parseExpression(chars, n);\n } catch (error) {\n throw new Error(`Cannot parse dice expression [${expression}]: ${error}`);\n }\n\n try {\n (result as any).privateData = (result as any).privateData || {};\n result.identifier = cleaned;\n } catch {}\n\n if (chars.length > 0) {\n throw new Error(\n `Unexpected token: '${chars[0]}' from expression: '${expression}'`\n );\n }\n\n // When creating the PMF, do not epsilon prune\n const resultPMF = result.toPMF(-1);\n if (cachingEnabled) {\n // store using the same cleaned key we used for lookup\n const cacheKey = `${cleaned}:${n}`;\n parseCache.set(cacheKey, resultPMF);\n }\n\n return resultPMF;\n}\n\nfunction combineDiceWithNormalization(\n dice: Dice,\n normValue: number,\n outcomeType: OutcomeType,\n currentNorm: number,\n finalResult: Dice\n): { newNorm: number; updatedResult: Dice } {\n dice = dice.normalize(currentNorm);\n finalResult = finalResult.normalize(normValue);\n finalResult.setOutcomeDistribution(outcomeType, dice.getFaceMap());\n finalResult = finalResult.combine(dice);\n return { newNorm: currentNorm * normValue, updatedResult: finalResult };\n}\n\nfunction parseExpression(arr: string[], n: number): Dice {\n const result = (() => {\n const res = parseArgument(arr, n);\n return typeof res === \"number\" ? Dice.scalar(res) : res;\n })();\n\n let op = parseOperation(arr);\n let finalResult = result;\n\n while (op != null) {\n const arg = !op.unary ? parseArgument(arr, n) : finalResult;\n\n // Handle crit (e.g. xcrit, crit)\n let crit: Dice | undefined;\n let critNorm = 1;\n if (arr[0] === \"x\" || arr[0] === \"c\") {\n const isXcrit = arr[0] === \"x\";\n if (isXcrit) assertToken(arr, \"x\");\n assertToken(arr, \"c\");\n assertToken(arr, \"r\");\n assertToken(arr, \"i\");\n assertToken(arr, \"t\");\n\n const count = isXcrit ? parseNumber(arr, n) : 1;\n\n crit = new Dice();\n for (let i = 0; i < count; i++) {\n const max = finalResult.maxFace();\n crit.setFace(max, finalResult.get(max));\n finalResult = finalResult.deleteFace(max);\n }\n\n critNorm = crit.total();\n crit = op.call(crit, parseBinaryArgument(arg, arr, n));\n\n critNorm = crit && critNorm ? crit.total() / critNorm : 1;\n }\n\n // Handle save\n let save: Dice | undefined;\n let saveNorm = 1;\n if (arr[0] === \"s\") {\n assertToken(arr, \"s\");\n assertToken(arr, \"a\");\n assertToken(arr, \"v\");\n assertToken(arr, \"e\");\n\n save = new Dice();\n const min = finalResult.minFace();\n save.increment(min > 0 ? min : 1, finalResult.get(min));\n\n saveNorm = save.total();\n finalResult = finalResult.deleteFace(min);\n save = op.call(save, parseBinaryArgument(arg, arr, n));\n saveNorm = save && saveNorm ? save.total() / saveNorm : 1;\n }\n\n // Handle half damage on hit (potent cantrip)\n let pc: Dice | undefined;\n let pcNorm = 1;\n\n if (arr.length >= 2 && arr[0] === \"p\" && arr[1] === \"c\") {\n assertToken(arr, \"p\");\n assertToken(arr, \"c\");\n\n pc = new Dice();\n const min = finalResult.minFace();\n pc.increment(min > 0 ? min : 1, finalResult.get(min));\n\n const missBefore = pc.total();\n finalResult = finalResult.deleteFace(min);\n\n pc = op.call(pc, parseBinaryArgument(arg, arr, n)).divideRoundDown(2); // parse the damage\n\n const missAfter = pc ? pc.total() : 0;\n pcNorm = missBefore ? missAfter / missBefore : 1;\n }\n\n // Handle miss\n let miss: Dice | undefined;\n let missNorm = 1;\n\n if (arr[0] === \"m\") {\n assertToken(arr, \"m\");\n assertToken(arr, \"i\");\n assertToken(arr, \"s\");\n assertToken(arr, \"s\");\n\n miss = new Dice();\n const min = finalResult.minFace();\n miss.increment(min > 0 ? min : 1, finalResult.get(min));\n\n missNorm = miss.total();\n finalResult = finalResult.deleteFace(min);\n\n miss = op.call(miss, parseBinaryArgument(arg, arr, n));\n missNorm = miss && missNorm ? miss.total() / missNorm : 1;\n }\n\n let norm = finalResult.total();\n\n finalResult = op.call(finalResult, arg);\n norm = norm ? finalResult.total() / norm : 1;\n\n // Combine dice with normalization\n if (crit) {\n const result = combineDiceWithNormalization(\n crit,\n critNorm,\n \"crit\",\n norm,\n finalResult\n );\n norm = result.newNorm;\n finalResult = result.updatedResult;\n }\n\n if (save) {\n const result = combineDiceWithNormalization(\n save,\n saveNorm,\n \"saveHalf\",\n norm,\n finalResult\n );\n norm = result.newNorm;\n finalResult = result.updatedResult;\n }\n\n if (miss) {\n const result = combineDiceWithNormalization(\n miss,\n missNorm,\n \"missDamage\",\n norm,\n finalResult\n );\n norm = result.newNorm;\n finalResult = result.updatedResult;\n }\n\n if (pc) {\n const result = combineDiceWithNormalization(\n pc,\n pcNorm,\n \"pc\",\n norm,\n finalResult\n );\n norm = result.newNorm;\n finalResult = result.updatedResult;\n }\n\n op = parseOperation(arr);\n }\n\n return finalResult;\n}\n\nfunction parseArgument(s: string[], n: number): Dice | number {\n let result = parseArgumentInternal(s, n);\n\n while (true) {\n const next = parseArgumentInternal(s, n);\n if (next === undefined) break;\n\n result = multiplyDiceByDice(result as Dice | number, next);\n }\n\n return result as Dice | number;\n}\n\nfunction multiplyDiceByDice(d1: Dice | number, d2: Dice | number): Dice {\n if (typeof d1 === \"number\") d1 = Dice.scalar(d1);\n if (typeof d2 === \"number\") d2 = Dice.scalar(d2);\n\n const result = new Dice();\n const faces: Record<number, Dice> = {};\n let normalizationFactor = 1;\n\n for (const key of d1.keys()) {\n let face: Dice;\n\n if (typeof key !== \"number\") {\n continue; // Skip invalid scalar\n }\n\n if (d2.privateData.keep) {\n // Repeat dice2 \"key\" times and apply keep\n const repeat: Dice[] = Array(key).fill(d2);\n face = opDice(repeat, d2.privateData.keep);\n } else {\n face = multiplyDice(key, d2);\n }\n\n normalizationFactor *= face.total();\n faces[key] = face;\n }\n\n for (const key of Object.keys(faces)) {\n const k = parseFloat(key); // keys from object are strings\n const face = faces[k];\n const count = d1.get(k);\n result.combineInPlace(\n face.normalize((count * normalizationFactor) / face.total())\n );\n }\n\n result.privateData.except = {};\n return result;\n}\n\nfunction multiplyDice(n: number, d: Dice): Dice {\n if (n === 0) return new Dice(0);\n if (n === 1) return d;\n\n const half = Math.floor(n / 2);\n let result = multiplyDice(half, d);\n result = result.add(result);\n\n if (n % 2 === 1) {\n result = result.add(d);\n }\n\n return result;\n}\n\nfunction opDice(diceList: Dice[], keepFn: (values: number[]) => number): Dice {\n return opDiceInternal(diceList, new Dice(), 0, [], 1, keepFn);\n}\n\nfunction opDiceInternal(\n diceList: Dice[],\n result: Dice,\n index: number,\n values: number[],\n weight: number,\n combineFn: (values: number[]) => number\n): Dice {\n if (index === diceList.length) {\n return result.combine(Dice.scalar(combineFn(values)).normalize(weight));\n }\n\n const currentDice = diceList[index];\n for (const face of currentDice.keys()) {\n values.push(face as number);\n result = opDiceInternal(\n diceList,\n result,\n index + 1,\n values,\n weight * currentDice.get(face),\n combineFn\n );\n values.pop();\n }\n\n return result;\n}\n\nfunction parseArgumentInternal(\n s: string[],\n n: number\n): Dice | number | undefined {\n if (s.length === 0) return;\n\n const c = s[0];\n\n switch (c) {\n case \"(\":\n s.shift();\n return assertToken(s, \")\", parseExpression(s, n));\n\n case \"h\":\n case \"d\":\n return parseDice(s, n);\n\n case \"k\":\n assertToken(s, \"k\");\n return parseKeep(s, n);\n\n case \"n\":\n return parseNumber(s, n);\n\n default:\n if (isDigit(c)) return parseNumber(s, n);\n return;\n }\n}\n\nfunction parseBinaryArgument(\n arg: Dice | number,\n arr: string[],\n n: number\n): Dice {\n if (arr.length >= 4 && arr[0] === \"h\" && peek(arr, \"half\")) {\n assertToken(arr, \"half\");\n\n const diceArg = typeof arg === \"number\" ? Dice.scalar(arg) : arg;\n return diceArg.divideRoundDown(2);\n }\n\n const parsed = parseArgument(arr, n);\n return typeof parsed === \"number\" ? Dice.scalar(parsed) : parsed;\n}\n\nfunction assertToken<T>(s: string[], expected: string, ret?: T): T | undefined {\n for (const ch of expected) {\n const found = s.shift();\n if (found !== ch) {\n throw new Error(`Expected character '${ch}', found '${found}'`);\n }\n }\n return ret;\n}\n\nfunction parseDice(s: string[], n: number): Dice | undefined {\n let rerollOne = false;\n\n if (peek(s, \"hd\") && peekIsNumber(s, 2)) {\n assertToken(s, \"h\");\n assertToken(s, \"d\");\n rerollOne = true;\n } else if (peek(s, \"d\") && peekIsNumber(s, 1)) {\n assertToken(s, \"d\");\n } else {\n return;\n }\n\n const sides = parseNumber(s, n);\n let result = new Dice(sides);\n\n if (rerollOne) {\n result = result.deleteFace(1).combine(result);\n }\n\n return result;\n}\n\nfunction peek(arr: string[], expected: string): boolean {\n if (expected.length > arr.length) return false;\n\n for (let i = 0; i < expected.length; i++) {\n if (arr[i] !== expected.charAt(i)) return false;\n }\n\n return true;\n}\n\nfunction peekIsNumber(arr: string[], index: number): boolean {\n if (index >= arr.length) return false;\n return isDigit(arr[index]) || arr[index] === \"n\";\n}\n\nfunction parseNumber(s: string[], n: number): number {\n let ret = \"\";\n\n while (s.length > 0 && (isDigit(s[0]) || s[0] === \"n\")) {\n const ch = s.shift()!;\n ret += ch === \"n\" ? n.toString() : ch;\n }\n\n if (ret.length === 0) {\n throw new Error(`Expected number, found: '${s[0]}'`);\n }\n\n return parseInt(ret, 10);\n}\n\nfunction isDigit(c: string): boolean {\n return c >= \"0\" && c <= \"9\";\n}\n\nfunction parseKeep(s: string[], n: number): Dice | undefined {\n let keepLowest = false;\n\n if (peek(s, \"l\")) {\n assertToken(s, \"l\");\n keepLowest = true;\n } else if (peek(s, \"h\")) {\n assertToken(s, \"h\");\n keepLowest = false;\n } else {\n return;\n }\n\n const keepCount = parseNumber(s, n);\n const result = parseArgumentInternal(s, n);\n\n if (result instanceof Dice) {\n result.privateData.keep = keepN(keepCount, keepLowest);\n return result;\n }\n\n throw new Error(\"Expected Dice after keep modifier\");\n}\n\nfunction keepN(n: number, low: boolean): (values: number[]) => number {\n return (values: number[]): number => {\n const sorted = [...values].sort((a, b) => (low ? a - b : b - a));\n return sorted.slice(0, n).reduce((sum, val) => sum + val, 0);\n };\n}\n\nfunction parseOperation(s: string[]): DiceOperation | undefined {\n switch (s[0]) {\n case \")\":\n return;\n\n case \"a\":\n assertToken(s, \"ac\");\n return Dice.prototype.ac;\n\n case \"d\":\n assertToken(s, \"dc\");\n return Dice.prototype.dc;\n\n case \"!\":\n assertToken(s, \"!\");\n const adv = Dice.prototype.advantage as DiceOperation;\n adv.unary = true;\n return adv;\n\n case \">\":\n assertToken(s, \">\");\n return Dice.prototype.max;\n\n case \"<\":\n assertToken(s, \"<\");\n return Dice.prototype.min;\n\n case \"+\":\n assertToken(s, \"+\");\n return Dice.prototype.addNonZero;\n\n case \"~\":\n assertToken(s, \"~\");\n assertToken(s, \"+\");\n return Dice.prototype.add;\n\n case \"-\":\n assertToken(s, \"-\");\n return Dice.prototype.subtract;\n\n case \"&\":\n assertToken(s, \"&\");\n return Dice.prototype.combine;\n\n case \"r\":\n assertToken(s, \"reroll\");\n return Dice.prototype.reroll;\n\n case \"*\":\n assertToken(s, \"*\");\n\n if (peek(s, \"*\")) {\n assertToken(s, \"*\");\n return Dice.prototype.multiply;\n }\n\n return Dice.prototype.conditionalApply;\n\n case \"/\":\n assertToken(s, \"/\");\n if (s[0] === \"/\") {\n assertToken(s, \"/\");\n return Dice.prototype.divideRoundDown;\n }\n return Dice.prototype.divideRoundUp;\n\n case \"=\":\n assertToken(s, \"=\");\n return Dice.prototype.eq;\n }\n\n return;\n}\n","import type { Bin } from \"../common/types\";\nimport { EPS } from \"../common/types\";\nimport { PMF } from \"./pmf\";\n\ntype BinEntries = Iterable<[number, Bin]>;\n\n/** A labeled mixture builder that preserves provenance in Bin.count. */\nexport class Mixture<L extends string = string> {\n private readonly totals = new Map<number, number>(); // raw mass per outcome (pre-normalization)\n private readonly labelMass = new Map<number, Record<L, number>>(); // raw mass per outcome per label\n private readonly eps: number;\n\n constructor(eps: number = EPS) {\n this.eps = Number.isFinite(eps) ? eps : EPS;\n }\n\n /** Remove all accumulated state. */\n clear(): this {\n this.totals.clear();\n this.labelMass.clear();\n return this;\n }\n\n /** Number of distinct outcome values currently accumulated. */\n size(): number {\n return this.totals.size;\n }\n\n /** Whether a label was ever added. */\n hasLabel(label: L): boolean {\n for (const bag of this.labelMass.values()) if (bag[label]) return true;\n return false;\n }\n\n /**\n * Add a labeled component with a mixture weight.\n * Weight can be any positive finite number. Very small contributions are pruned by eps.\n */\n add(label: L, pmf: PMF, weight = 1): this {\n if (!Number.isFinite(weight) || weight <= 0) return this;\n\n // Stream probabilities. Works whether PMF iterates as [v, p] or [v, Bin].\n for (const [v, binOrNumber] of pmf as any as BinEntries) {\n const isNumber = typeof binOrNumber === \"number\";\n const p = isNumber ? binOrNumber : binOrNumber?.p ?? 0;\n if (p <= 0) continue;\n\n const add = weight * p;\n if (!Number.isFinite(add) || Math.abs(add) < this.eps) continue;\n\n this.totals.set(v, (this.totals.get(v) ?? 0) + add);\n const bag = this.labelMass.get(v) ?? ({} as Record<L, number>);\n bag[label] = (bag[label] ?? 0) + add;\n this.labelMass.set(v, bag);\n }\n\n return this;\n }\n\n buildPMF(eps: number = EPS): PMF {\n // Kahan sum for robustness.\n let grand = 0;\n let c = 0;\n for (const m of this.totals.values()) {\n const y = m - c;\n const t = grand + y;\n c = t - grand - y;\n grand = t;\n }\n if (!(grand > 0)) throw new Error(\"Mixture: zero total mass\");\n\n const internal = new Map<number, Bin>();\n for (const [v, m] of this.totals) {\n if (m <= 0 || Math.abs(m) < this.eps) continue;\n const count = this.labelMass.get(v) ?? {};\n internal.set(v, { p: m / grand, count });\n }\n return new PMF(internal, eps);\n }\n\n /**\n * Produce normalized *per-label* PMFs (labels independent).\n * These are unlabeled PMFs built from the raw mass of that label alone.\n */\n byOutcome(): Record<L, PMF> {\n // Collect the set of labels present.\n const labels = new Set<L>();\n for (const bag of this.labelMass.values()) {\n for (const k of Object.keys(bag) as L[]) labels.add(k);\n }\n\n const out = {} as Record<L, PMF>;\n for (const label of labels) {\n const m = new Map<number, number>();\n for (const [v, bag] of this.labelMass) {\n const w = bag[label];\n if (w && Math.abs(w) >= this.eps) m.set(v, w);\n }\n if (m.size > 0) out[label] = PMF.fromMap(m, this.eps);\n }\n return out;\n }\n\n /**\n * Mixture weights per label, normalized to sum to 1 over labels that appeared.\n * Uses raw mass before per-outcome normalization.\n */\n weights(): Record<L, number> {\n const res = {} as Record<L, number>;\n for (const [, bag] of this.labelMass) {\n for (const [lab, w] of Object.entries(bag) as [L, number][]) {\n if (!Number.isFinite(w) || w <= 0) continue;\n res[lab] = (res[lab] ?? 0) + w;\n }\n }\n // Normalize\n let total = 0;\n let c = 0;\n for (const v of Object.values(res)) {\n const y = (v as number) - c;\n const t = total + y;\n c = t - total - y;\n total = t;\n }\n if (total > 0) {\n for (const k in res) res[k as L] = res[k as L] / total;\n }\n return res;\n }\n\n toJSON(): {\n totals: Array<[number, number]>;\n labels: Array<[number, Record<L, number>]>;\n eps: number;\n } {\n return {\n totals: Array.from(this.totals.entries()).sort((a, b) => a[0] - b[0]),\n labels: Array.from(this.labelMass.entries()).sort((a, b) => a[0] - b[0]),\n eps: this.eps,\n };\n }\n\n static mix<L extends string = string>(\n items: Array<[label: L, pmf: PMF, weight: number]>,\n eps: number = EPS\n ): PMF {\n const mix = new Mixture<L>(eps);\n for (const [lab, pmf, w] of items) mix.add(lab, pmf, w);\n return mix.buildPMF();\n }\n}\n"]}