@swrpg-online/dice 0.0.0-development
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +136 -0
- package/dist/bundle.cjs.js +2 -0
- package/dist/bundle.cjs.js.map +1 -0
- package/dist/bundle.esm.js +2 -0
- package/dist/bundle.esm.js.map +1 -0
- package/dist/bundle.umd.js +2 -0
- package/dist/bundle.umd.js.map +1 -0
- package/dist/cli.d.ts +5 -0
- package/dist/cli.js +168 -0
- package/dist/dice.d.ts +16 -0
- package/dist/dice.js +695 -0
- package/dist/hints.d.ts +11 -0
- package/dist/hints.js +251 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +10 -0
- package/dist/pools.d.ts +32 -0
- package/dist/pools.js +53 -0
- package/dist/types.d.ts +60 -0
- package/dist/types.js +13 -0
- package/package.json +98 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023 SWRPG Dice
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
# dice
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+

|
|
5
|
+
[](https://codecov.io/gh/swrpg-online/dice)
|
|
6
|
+
[](https://github.com/semantic-release/semantic-release)
|
|
7
|
+
|
|
8
|
+
A TypeScript library that creates dice rolls using the [narrative dice system](https://star-wars-rpg-ffg.fandom.com/wiki/Narrative_Dice) for the Star Wars Roleplaying Game by [Fantasy Flight Games](https://www.fantasyflightgames.com/en/starwarsrpg/) and [Edge Studio](https://www.edge-studio.net/categories-games/starwarsrpg/).
|
|
9
|
+
|
|
10
|
+
## Features
|
|
11
|
+
|
|
12
|
+
- Complete narrative dice system implementation
|
|
13
|
+
- Detailed roll breakdown for each die
|
|
14
|
+
- Action hints to suggest possible uses for advantages, triumphs, etc.
|
|
15
|
+
- Roll results include:
|
|
16
|
+
- Successes / Failures
|
|
17
|
+
- Advantages / Threats
|
|
18
|
+
- Triumphs / Despairs
|
|
19
|
+
- Light / Dark Side Points (Force dice)
|
|
20
|
+
- Comprehensive Test Coverage
|
|
21
|
+
- The safety of TypeScript
|
|
22
|
+
- CLI Support
|
|
23
|
+
|
|
24
|
+
## Installation
|
|
25
|
+
|
|
26
|
+
### As a CLI Tool
|
|
27
|
+
|
|
28
|
+
To use the dice roller from the command line:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
npm i -g @swrpg-online/dice
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### As a project dependency
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
npm i @swrpg-online/dice
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## CLI Usage
|
|
41
|
+
|
|
42
|
+
```
|
|
43
|
+
swrpg-dice <dice-notation> [options]
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Example:
|
|
47
|
+
|
|
48
|
+
```
|
|
49
|
+
swrpg-dice 2y 1g 1p 1b 1sb --hints
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Output:
|
|
53
|
+
|
|
54
|
+
```
|
|
55
|
+
1 Success(es), 4 Advantage(s), 1 Threat(s)
|
|
56
|
+
|
|
57
|
+
Possible actions:
|
|
58
|
+
• 1 Advantage or 1 Triumph - Recover one strain (may be applied more than once).
|
|
59
|
+
• 1 Advantage or 1 Triumph - Add a boost die to the next allied active character's check.
|
|
60
|
+
• 1 Advantage or 1 Triumph - Notice a single important point in the ongoing conflict, such as the location of a blast door's control panel or
|
|
61
|
+
...
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Dice Options:
|
|
65
|
+
|
|
66
|
+
- y/pro = Yellow / Proficiency
|
|
67
|
+
- g/a = Green / Ability
|
|
68
|
+
- b/boo = Blue / Boost
|
|
69
|
+
- r/c = Red / Challenge
|
|
70
|
+
- p/diff = Purple / Difficulty
|
|
71
|
+
- blk/k/sb/s = Black / Setback
|
|
72
|
+
- w/f = White / Force
|
|
73
|
+
|
|
74
|
+
## Programmatic Usage
|
|
75
|
+
|
|
76
|
+
```typescript
|
|
77
|
+
import { roll, DicePool } from '@swrpg-online/dice';
|
|
78
|
+
|
|
79
|
+
const pool: DicePool = {
|
|
80
|
+
abilityDice: 2,
|
|
81
|
+
proficiencyDice: 1,
|
|
82
|
+
difficultyDice: 1,
|
|
83
|
+
challengeDice: 1
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
const result = roll(pool);
|
|
87
|
+
|
|
88
|
+
console.log(result.results);
|
|
89
|
+
console.log(result.summary);
|
|
90
|
+
|
|
91
|
+
=> {
|
|
92
|
+
"results": [
|
|
93
|
+
{
|
|
94
|
+
"type": "ability",
|
|
95
|
+
"roll": 5,
|
|
96
|
+
"result": {
|
|
97
|
+
"successes": 0,
|
|
98
|
+
"failures": 0,
|
|
99
|
+
"advantages": 1,
|
|
100
|
+
"threats": 0,
|
|
101
|
+
"triumphs": 0,
|
|
102
|
+
"despair": 0
|
|
103
|
+
}
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
"type": "proficiency",
|
|
107
|
+
"roll": 10,
|
|
108
|
+
"result": {
|
|
109
|
+
"successes": 0,
|
|
110
|
+
"failures": 0,
|
|
111
|
+
"advantages": 2,
|
|
112
|
+
"threats": 0,
|
|
113
|
+
"triumphs": 0,
|
|
114
|
+
"despair": 0
|
|
115
|
+
}
|
|
116
|
+
},
|
|
117
|
+
...
|
|
118
|
+
],
|
|
119
|
+
"summary": {
|
|
120
|
+
"successes": 0,
|
|
121
|
+
"failures": 0,
|
|
122
|
+
"advantages": 3,
|
|
123
|
+
"threats": 2,
|
|
124
|
+
"triumphs": 0,
|
|
125
|
+
"despair": 0
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
# License
|
|
131
|
+
|
|
132
|
+
This project is licensed under the MIT License.
|
|
133
|
+
|
|
134
|
+
# Contribution
|
|
135
|
+
|
|
136
|
+
This is a new library for a game with not a lot of open source tooling available - feedback and pull requests welcome!
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});const e="ADVANTAGE",s="THREAT",t="TRIUMPH",a="DESPAIR",r=[{description:"Recover one strain (may be applied more than once).",cost:{[e]:1,[t]:1}},{description:"Add a boost die to the next allied active character's check.",cost:{[e]:1,[t]:1}},{description:"Notice a single important point in the ongoing conflict, such as the location of a blast door's control panel or a weak point on an attack speeder.",cost:{[e]:1,[t]:1}},{description:"Inflict a Critical Injury with a successful attack that deals damage past soak (Advantage cost may vary).",cost:{[e]:1,[t]:1}},{description:"Activate a weapon quality (Advantage cost may vary).",cost:{[e]:1,[t]:1}},{description:"Perform an immediate free maneuver that does not exceed the two maneuver per turn limit.",cost:{[e]:2,[t]:1}},{description:"Add a setback die to the targeted character's next check.",cost:{[e]:2,[t]:1}},{description:"Add a boost die to any allied character's next check, including that of the active character.",cost:{[e]:2,[t]:1}},{description:"Negate the targeted enemy's defensive bonuses (such as the defense gained from cover, equipment, or performing the Guarded Stance maneuver) util the end of the current round.",cost:{[e]:3,[t]:1}},{description:"Ignore penalizing environmental effects such as inclement weather, zero gravity, or similar circumstances until the end of the active character's next turn.",cost:{[e]:3,[t]:1}},{description:"When dealing damage to a target, have the attack disable the opponent or one piece of gear rather than dealing wounds or strain. This could include hobbling them temporarily with a shot to the leg, or disabling their comlink. This should be agreed upon by the player and the GM, and the effects are up to the GM (although Table 6-10: Critical Injury Result is a god resource to consult for possible effects). The effects should be temporary and not too excessive.",cost:{[e]:3,[t]:1}},{description:"Gain + 1 melee or ranged defense until the end of the active character's next turn.",cost:{[e]:3,[t]:1}},{description:"Force the target to drop a melee or ranged weapon they are wielding.",cost:{[e]:3,[t]:1}},{description:"Upgrade the difficulty of the targeted character's next check.",cost:{[t]:1}},{description:"Do something vital, such as shooting the controls to the nearby blast doors to seal them shut.",cost:{[t]:1}},{description:"Upgrade any allied character's next check, including that of the current active character.",cost:{[t]:1}},{description:"When dealing damage to a target, have the attack destroy a piece of equipment the target is using, such as blowing up his blaster or destroying a personal shield generator.",cost:{[t]:2}},{description:"The active character suffers 1 strain.",cost:{[s]:1,[a]:1}},{description:"The active character loses the benefits of a prior maneuver (such as from taking cover or assuming a Guarded Stance) until they perform the maneuver again.",cost:{[s]:1,[a]:1}},{description:"An opponent may immediately perform one free maneuver in response to the active character's check.",cost:{[s]:2,[a]:1}},{description:"Add a boost die to the targeted character's next check.",cost:{[s]:1,[a]:1}},{description:"The active character or an allied character suffers a setback die on their next action.",cost:{[s]:2,[a]:1}},{description:"The active character falls prone.",cost:{[s]:3,[a]:1}},{description:"The active character grants the enemy a significant advantage in the ongoing encounter, such as accidentally blasting the controls to a bridge the active character was planning to use for their escape.",cost:{[s]:3,[a]:1}},{description:"The character's ranged weapon imediately runs out of ammunition and may not be used for the remainder of the encounter.",cost:{[a]:1}},{description:"Upgrade the difficulty of an allied character's next check, including that of the current active character.",cost:{[a]:1}},{description:"The tool or melee weapon the character is using becomes damaged.",cost:{[a]:1}}];const i=e=>Math.floor(Math.random()*e)+1,c=e=>{switch(e){case 3:return{successes:1,failures:0,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};case 4:return{successes:1,failures:0,advantages:1,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};case 5:return{successes:0,failures:0,advantages:2,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};case 6:return{successes:0,failures:0,advantages:1,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};default:return{successes:0,failures:0,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0}}},d=e=>{switch(e){case 3:case 4:return{successes:0,failures:1,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};case 5:case 6:return{successes:0,failures:0,advantages:0,threats:1,triumphs:0,despair:0,lightSide:0,darkSide:0};default:return{successes:0,failures:0,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0}}},n=e=>{switch(e){case 2:case 3:return{successes:1,failures:0,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};case 4:return{successes:2,failures:0,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};case 5:case 6:return{successes:0,failures:0,advantages:1,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};case 7:return{successes:1,failures:0,advantages:1,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};case 8:return{successes:0,failures:0,advantages:2,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};default:return{successes:0,failures:0,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0}}},h=e=>{switch(e){case 2:return{successes:0,failures:1,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};case 3:return{successes:0,failures:2,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};case 4:case 5:case 6:return{successes:0,failures:0,advantages:0,threats:1,triumphs:0,despair:0,lightSide:0,darkSide:0};case 7:return{successes:0,failures:0,advantages:0,threats:2,triumphs:0,despair:0,lightSide:0,darkSide:0};case 8:return{successes:0,failures:1,advantages:0,threats:1,triumphs:0,despair:0,lightSide:0,darkSide:0};default:return{successes:0,failures:0,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0}}},o=e=>{switch(e){case 2:case 3:return{successes:1,failures:0,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};case 4:case 5:return{successes:2,failures:0,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};case 6:return{successes:0,failures:0,advantages:1,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};case 7:case 8:case 9:return{successes:1,failures:0,advantages:1,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};case 10:case 11:return{successes:0,failures:0,advantages:2,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};case 12:return{successes:0,failures:0,advantages:0,threats:0,triumphs:1,despair:0,lightSide:0,darkSide:0};default:return{successes:0,failures:0,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0}}},u=e=>{switch(e){case 2:case 3:return{successes:0,failures:1,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};case 4:case 5:return{successes:0,failures:2,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};case 6:case 7:return{successes:0,failures:0,advantages:0,threats:1,triumphs:0,despair:0,lightSide:0,darkSide:0};case 8:case 9:return{successes:0,failures:1,advantages:0,threats:1,triumphs:0,despair:0,lightSide:0,darkSide:0};case 10:case 11:return{successes:0,failures:0,advantages:0,threats:2,triumphs:0,despair:0,lightSide:0,darkSide:0};case 12:return{successes:0,failures:0,advantages:0,threats:0,triumphs:0,despair:1,lightSide:0,darkSide:0};default:return{successes:0,failures:0,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0}}},l=e=>{switch(e){case 1:case 2:case 3:case 4:case 5:return{successes:0,failures:0,advantages:0,threats:0,triumphs:0,despair:0,lightSide:1,darkSide:0};case 6:case 7:return{successes:0,failures:0,advantages:0,threats:0,triumphs:0,despair:0,lightSide:2,darkSide:0};case 8:case 9:case 10:case 11:return{successes:0,failures:0,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:1};case 12:return{successes:0,failures:0,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:2};default:return{successes:0,failures:0,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0}}};exports.createCombatCheck=(e,s,t=0)=>({abilityDice:Math.max(0,e),proficiencyDice:Math.max(0,s),boostDice:Math.max(0,t)}),exports.createDifficultyPool=(e,s=0)=>({difficultyDice:Math.max(0,e),challengeDice:Math.max(0,s)}),exports.createOpposedCheck=(e,s,t,a=0)=>({abilityDice:Math.max(0,e),proficiencyDice:Math.max(0,s),difficultyDice:Math.max(0,t),challengeDice:Math.max(0,a)}),exports.createSkillCheck=(e,s)=>({abilityDice:Math.max(0,e),proficiencyDice:Math.max(0,s)}),exports.roll=(e,s)=>{var t,a,p,g,f,m,v,S,k;const y=null!==(t=e.boostDice)&&void 0!==t?t:0,b=null!==(a=e.abilityDice)&&void 0!==a?a:0,x=null!==(p=e.proficiencyDice)&&void 0!==p?p:0,M=null!==(g=e.setBackDice)&&void 0!==g?g:0,w=null!==(f=e.difficultyDice)&&void 0!==f?f:0,D=null!==(m=e.challengeDice)&&void 0!==m?m:0,T=null!==(v=e.forceDice)&&void 0!==v?v:0,$=null!==(S=null==s?void 0:s.maxDicePerType)&&void 0!==S?S:100,A=null!==(k=null==s?void 0:s.maxTotalDice)&&void 0!==k?k:500,C=Math.max(0,Math.min(y,$)),j=Math.max(0,Math.min(b,$)),O=Math.max(0,Math.min(x,$)),P=Math.max(0,Math.min(M,$)),E=Math.max(0,Math.min(w,$)),G=Math.max(0,Math.min(D,$)),I=Math.max(0,Math.min(T,$)),R=y>$||b>$||x>$||M>$||w>$||D>$||T>$,N=C+j+O+P+E+G+I;if(N>A)throw new Error(`Total dice count (${N}) exceeds maximum allowed (${A}). Please reduce the number of dice in your pool.`);if(R&&(null==s?void 0:s.throwOnLimitExceeded)){const e=[];throw y>$&&e.push(`boost: ${y}`),b>$&&e.push(`ability: ${b}`),x>$&&e.push(`proficiency: ${x}`),M>$&&e.push(`setback: ${M}`),w>$&&e.push(`difficulty: ${w}`),D>$&&e.push(`challenge: ${D}`),T>$&&e.push(`force: ${T}`),new Error(`Dice counts exceed per-type limit (${$}): ${e.join(", ")}. Dice counts have been capped to the maximum.`)}const U=[];for(let e=0;e<C;e++){const e=i(6);U.push({type:"boost",roll:e,result:c(e)})}for(let e=0;e<j;e++){const e=i(8);U.push({type:"ability",roll:e,result:n(e)})}for(let e=0;e<O;e++){const e=i(12);U.push({type:"proficiency",roll:e,result:o(e)})}for(let e=0;e<P;e++){const e=i(6);U.push({type:"setback",roll:e,result:d(e)})}for(let e=0;e<E;e++){const e=i(8);U.push({type:"difficulty",roll:e,result:h(e)})}for(let e=0;e<G;e++){const e=i(12);U.push({type:"challenge",roll:e,result:u(e)})}for(let e=0;e<I;e++){const e=i(12);U.push({type:"force",roll:e,result:l(e)})}const q=(e=>{const s=e.reduce((e,s)=>({successes:e.successes+s.successes,failures:e.failures+s.failures,advantages:e.advantages+s.advantages,threats:e.threats+s.threats,triumphs:e.triumphs+s.triumphs,despair:e.despair+s.despair,lightSide:e.lightSide+(s.lightSide||0),darkSide:e.darkSide+(s.darkSide||0)}),{successes:0,failures:0,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0});let t=0,a=0;return s.successes===s.failures?(t=0,a=0):s.successes>s.failures?t=s.successes-s.failures:a=s.failures-s.successes,{successes:t,failures:a,advantages:s.advantages,threats:s.threats,triumphs:s.triumphs,despair:s.despair,lightSide:s.lightSide,darkSide:s.darkSide}})(U.map(e=>e.result));if(null==s?void 0:s.hints){const e=r.filter(e=>{const{cost:s}=e;return Object.entries(s).some(([e,s])=>{const t=e.toLowerCase()+"s",a=q[t];return"number"==typeof a&&(void 0!==s&&s>0&&a>=s)})});q.hints=e.map(e=>`${function(e){if(!e.cost||0===Object.keys(e.cost).length)return"No cost";const s=Object.entries(e.cost).filter(([e,s])=>s&&s>0).map(([e,s])=>`${s} ${e.charAt(0).toUpperCase()+e.toLowerCase().slice(1)}${s>1?"s":""}`);return s.length>1?s.join(" OR "):s.length>0?s[0]:"No cost"}(e)} - ${e.description}`)}return{results:U,summary:q}};
|
|
2
|
+
//# sourceMappingURL=bundle.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bundle.cjs.js","sources":["../src/types.ts","../src/hints.ts","../src/dice.ts","../src/pools.ts"],"sourcesContent":["export type DicePool = {\n boostDice?: number;\n abilityDice?: number;\n proficiencyDice?: number;\n setBackDice?: number;\n difficultyDice?: number;\n challengeDice?: number;\n forceDice?: number;\n};\n\nexport type DiceResult = {\n successes: number;\n failures: number;\n advantages: number;\n threats: number;\n triumphs: number;\n despair: number;\n lightSide: number;\n darkSide: number;\n hints?: string[];\n};\n\nexport type DieType =\n | \"boost\"\n | \"ability\"\n | \"proficiency\"\n | \"setback\"\n | \"difficulty\"\n | \"challenge\"\n | \"force\";\n\nexport type DetailedDieResult = {\n type: DieType;\n roll: number;\n result: DiceResult;\n};\n\nexport type RollResult = {\n results: DetailedDieResult[];\n summary: DiceResult;\n};\n\nexport const SYMBOLS = {\n SUCCESS: \"SUCCESS\" as const,\n FAILURE: \"FAILURE\" as const,\n ADVANTAGE: \"ADVANTAGE\" as const,\n THREAT: \"THREAT\" as const,\n TRIUMPH: \"TRIUMPH\" as const,\n DESPAIR: \"DESPAIR\" as const,\n LIGHT: \"LIGHT\" as const,\n DARK: \"DARK\" as const,\n} as const;\n\nexport type Symbol = keyof typeof SYMBOLS;\n\nexport type RollOptions = {\n hints?: boolean;\n /**\n * Maximum number of dice allowed per die type.\n * Default: 100\n */\n maxDicePerType?: number;\n /**\n * Maximum total number of dice allowed in a single roll.\n * Default: 500\n */\n maxTotalDice?: number;\n /**\n * Whether to throw an error when dice limits are exceeded.\n * If false, dice counts will be silently capped to the maximum.\n * Default: false\n */\n throwOnLimitExceeded?: boolean;\n};\n","import { SYMBOLS, type Symbol } from \"./types\";\n\n// 1 advantage or 1 triumph\nconst recoverOneStrain = \"Recover one strain (may be applied more than once).\";\nconst addBoostDieToActiveAlly =\n \"Add a boost die to the next allied active character's check.\";\nconst noticeImportantPoint =\n \"Notice a single important point in the ongoing conflict, such as the location of a blast door's control panel or a weak point on an attack speeder.\";\nconst inflictCriticalInjury =\n \"Inflict a Critical Injury with a successful attack that deals damage past soak (Advantage cost may vary).\";\nconst activateWeaponQuality =\n \"Activate a weapon quality (Advantage cost may vary).\";\n\n// 2 advantage or 1 triumph\nconst performManeuver =\n \"Perform an immediate free maneuver that does not exceed the two maneuver per turn limit.\";\nconst addSetbackDie =\n \"Add a setback die to the targeted character's next check.\";\nconst addBoostDieToAnyAlly =\n \"Add a boost die to any allied character's next check, including that of the active character.\";\n\n// 3 advantage or 1 triumph\nconst negateEnemy =\n \"Negate the targeted enemy's defensive bonuses (such as the defense gained from cover, equipment, or performing the Guarded Stance maneuver) util the end of the current round.\";\nconst ignoreEnvironment =\n \"Ignore penalizing environmental effects such as inclement weather, zero gravity, or similar circumstances until the end of the active character's next turn.\";\nconst disableOpponent =\n \"When dealing damage to a target, have the attack disable the opponent or one piece of gear rather than dealing wounds or strain. This could include hobbling them temporarily with a shot to the leg, or disabling their comlink. This should be agreed upon by the player and the GM, and the effects are up to the GM (although Table 6-10: Critical Injury Result is a god resource to consult for possible effects). The effects should be temporary and not too excessive.\";\nconst gainDefense =\n \"Gain + 1 melee or ranged defense until the end of the active character's next turn.\";\nconst dropWeapon =\n \"Force the target to drop a melee or ranged weapon they are wielding.\";\n\n// 1 triumph\nconst upgradeDifficultyTargetedCharacter =\n \"Upgrade the difficulty of the targeted character's next check.\";\nconst doSomethingVital =\n \"Do something vital, such as shooting the controls to the nearby blast doors to seal them shut.\";\nconst upgradeAnyAllyCheck =\n \"Upgrade any allied character's next check, including that of the current active character.\";\n\n// 2 triumph\nconst destroyEquipment =\n \"When dealing damage to a target, have the attack destroy a piece of equipment the target is using, such as blowing up his blaster or destroying a personal shield generator.\";\n\n// 1 threat or 1 despair\nconst sufferStrain = \"The active character suffers 1 strain.\";\nconst loseManeuverBenefit =\n \"The active character loses the benefits of a prior maneuver (such as from taking cover or assuming a Guarded Stance) until they perform the maneuver again.\";\n\n// 2 threat or 1 despair\nconst freeManeuver =\n \"An opponent may immediately perform one free maneuver in response to the active character's check.\";\nconst addBoostDieToTargetedCharacter =\n \"Add a boost die to the targeted character's next check.\";\nconst sufferSetback =\n \"The active character or an allied character suffers a setback die on their next action.\";\n\n// 3 threat or 1 despair\nconst fallProne = \"The active character falls prone.\";\nconst gainSignificantAdvantage =\n \"The active character grants the enemy a significant advantage in the ongoing encounter, such as accidentally blasting the controls to a bridge the active character was planning to use for their escape.\";\n\n// 1 despair\nconst outOfAmmo =\n \"The character's ranged weapon imediately runs out of ammunition and may not be used for the remainder of the encounter.\";\nconst upgradeDifficultyAlliedCharacter =\n \"Upgrade the difficulty of an allied character's next check, including that of the current active character.\";\nconst damagedItem =\n \"The tool or melee weapon the character is using becomes damaged.\";\n\nexport type CostType = {\n [key in Symbol]?: number;\n};\n\ntype Hint = {\n description: string;\n cost: CostType;\n};\n\nexport const hints: Hint[] = [\n // 1 advantage or 1 triumph\n {\n description: recoverOneStrain,\n cost: {\n [SYMBOLS.ADVANTAGE]: 1,\n [SYMBOLS.TRIUMPH]: 1,\n },\n },\n {\n description: addBoostDieToActiveAlly,\n cost: {\n [SYMBOLS.ADVANTAGE]: 1,\n [SYMBOLS.TRIUMPH]: 1,\n },\n },\n {\n description: noticeImportantPoint,\n cost: {\n [SYMBOLS.ADVANTAGE]: 1,\n [SYMBOLS.TRIUMPH]: 1,\n },\n },\n {\n description: inflictCriticalInjury,\n cost: {\n [SYMBOLS.ADVANTAGE]: 1,\n [SYMBOLS.TRIUMPH]: 1,\n },\n },\n {\n description: activateWeaponQuality,\n cost: {\n [SYMBOLS.ADVANTAGE]: 1,\n [SYMBOLS.TRIUMPH]: 1,\n },\n },\n // 2 advantage or 1 triumph\n {\n description: performManeuver,\n cost: {\n [SYMBOLS.ADVANTAGE]: 2,\n [SYMBOLS.TRIUMPH]: 1,\n },\n },\n {\n description: addSetbackDie,\n cost: {\n [SYMBOLS.ADVANTAGE]: 2,\n [SYMBOLS.TRIUMPH]: 1,\n },\n },\n {\n description: addBoostDieToAnyAlly,\n cost: {\n [SYMBOLS.ADVANTAGE]: 2,\n [SYMBOLS.TRIUMPH]: 1,\n },\n },\n // 3 advantage or 1 triumph\n {\n description: negateEnemy,\n cost: {\n [SYMBOLS.ADVANTAGE]: 3,\n [SYMBOLS.TRIUMPH]: 1,\n },\n },\n {\n description: ignoreEnvironment,\n cost: {\n [SYMBOLS.ADVANTAGE]: 3,\n [SYMBOLS.TRIUMPH]: 1,\n },\n },\n {\n description: disableOpponent,\n cost: {\n [SYMBOLS.ADVANTAGE]: 3,\n [SYMBOLS.TRIUMPH]: 1,\n },\n },\n {\n description: gainDefense,\n cost: {\n [SYMBOLS.ADVANTAGE]: 3,\n [SYMBOLS.TRIUMPH]: 1,\n },\n },\n {\n description: dropWeapon,\n cost: {\n [SYMBOLS.ADVANTAGE]: 3,\n [SYMBOLS.TRIUMPH]: 1,\n },\n },\n // 1 triumph\n {\n description: upgradeDifficultyTargetedCharacter,\n cost: {\n [SYMBOLS.TRIUMPH]: 1,\n },\n },\n {\n description: doSomethingVital,\n cost: {\n [SYMBOLS.TRIUMPH]: 1,\n },\n },\n {\n description: upgradeAnyAllyCheck,\n cost: {\n [SYMBOLS.TRIUMPH]: 1,\n },\n },\n // 2 triumph\n {\n description: destroyEquipment,\n cost: {\n [SYMBOLS.TRIUMPH]: 2,\n },\n },\n // 1 threat or 1 despair\n {\n description: sufferStrain,\n cost: {\n [SYMBOLS.THREAT]: 1,\n [SYMBOLS.DESPAIR]: 1,\n },\n },\n {\n description: loseManeuverBenefit,\n cost: {\n [SYMBOLS.THREAT]: 1,\n [SYMBOLS.DESPAIR]: 1,\n },\n },\n // 2 threat or 1 despair\n {\n description: freeManeuver,\n cost: {\n [SYMBOLS.THREAT]: 2,\n [SYMBOLS.DESPAIR]: 1,\n },\n },\n {\n description: addBoostDieToTargetedCharacter,\n cost: {\n [SYMBOLS.THREAT]: 1,\n [SYMBOLS.DESPAIR]: 1,\n },\n },\n {\n description: sufferSetback,\n cost: {\n [SYMBOLS.THREAT]: 2,\n [SYMBOLS.DESPAIR]: 1,\n },\n },\n // 3 threat or 1 despair\n {\n description: fallProne,\n cost: {\n [SYMBOLS.THREAT]: 3,\n [SYMBOLS.DESPAIR]: 1,\n },\n },\n {\n description: gainSignificantAdvantage,\n cost: {\n [SYMBOLS.THREAT]: 3,\n [SYMBOLS.DESPAIR]: 1,\n },\n },\n // 1 despair\n {\n description: outOfAmmo,\n cost: {\n [SYMBOLS.DESPAIR]: 1,\n },\n },\n {\n description: upgradeDifficultyAlliedCharacter,\n cost: {\n [SYMBOLS.DESPAIR]: 1,\n },\n },\n {\n description: damagedItem,\n cost: {\n [SYMBOLS.DESPAIR]: 1,\n },\n },\n];\n\nexport function hintCostDisplayText(hint: Hint): string {\n if (!hint.cost || Object.keys(hint.cost).length === 0) {\n return \"No cost\";\n }\n const parts = Object.entries(hint.cost)\n .filter(([_, count]) => count && count > 0)\n .map(([symbol, count]) => {\n const symbolName =\n symbol.charAt(0).toUpperCase() + symbol.toLowerCase().slice(1);\n const plural = count > 1 ? \"s\" : \"\";\n return `${count} ${symbolName}${plural}`;\n });\n\n // Use \"OR\" in uppercase for clarity when multiple options exist\n if (parts.length > 1) {\n return parts.join(\" OR \");\n }\n return parts.length > 0 ? parts[0] : \"No cost\";\n}\n","import { hintCostDisplayText, hints } from \"./hints\";\nimport {\n DicePool,\n RollResult,\n DiceResult,\n DetailedDieResult,\n RollOptions,\n} from \"./types\";\n\n// Default dice limits for performance and security\nexport const DEFAULT_MAX_DICE_PER_TYPE = 100;\nexport const DEFAULT_MAX_TOTAL_DICE = 500;\n\nconst rollDie = (sides: number): number =>\n Math.floor(Math.random() * sides) + 1;\n\nconst boostDieResult = (roll: number): DiceResult => {\n switch (roll) {\n case 3:\n return {\n successes: 1,\n failures: 0,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n case 4:\n return {\n successes: 1,\n failures: 0,\n advantages: 1,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n case 5:\n return {\n successes: 0,\n failures: 0,\n advantages: 2,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n case 6:\n return {\n successes: 0,\n failures: 0,\n advantages: 1,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n default:\n return {\n successes: 0,\n failures: 0,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n }\n};\n\nconst setBackDieResult = (roll: number): DiceResult => {\n switch (roll) {\n case 3:\n case 4:\n return {\n successes: 0,\n failures: 1,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n case 5:\n case 6:\n return {\n successes: 0,\n failures: 0,\n advantages: 0,\n threats: 1,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n default:\n return {\n successes: 0,\n failures: 0,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n }\n};\n\nconst abilityDieResult = (roll: number): DiceResult => {\n switch (roll) {\n case 2:\n case 3:\n return {\n successes: 1,\n failures: 0,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n case 4:\n return {\n successes: 2,\n failures: 0,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n case 5:\n case 6:\n return {\n successes: 0,\n failures: 0,\n advantages: 1,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n case 7:\n return {\n successes: 1,\n failures: 0,\n advantages: 1,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n case 8:\n return {\n successes: 0,\n failures: 0,\n advantages: 2,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n default:\n return {\n successes: 0,\n failures: 0,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n }\n};\n\nconst difficultyDieResult = (roll: number): DiceResult => {\n switch (roll) {\n case 2:\n return {\n successes: 0,\n failures: 1,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n case 3:\n return {\n successes: 0,\n failures: 2,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n case 4:\n case 5:\n case 6:\n return {\n successes: 0,\n failures: 0,\n advantages: 0,\n threats: 1,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n case 7:\n return {\n successes: 0,\n failures: 0,\n advantages: 0,\n threats: 2,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n case 8:\n return {\n successes: 0,\n failures: 1,\n advantages: 0,\n threats: 1,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n default:\n return {\n successes: 0,\n failures: 0,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n }\n};\n\nconst proficiencyDieResult = (roll: number): DiceResult => {\n switch (roll) {\n case 2:\n case 3:\n return {\n successes: 1,\n failures: 0,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n case 4:\n case 5:\n return {\n successes: 2,\n failures: 0,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n case 6:\n return {\n successes: 0,\n failures: 0,\n advantages: 1,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n case 7:\n case 8:\n case 9:\n return {\n successes: 1,\n failures: 0,\n advantages: 1,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n case 10:\n case 11:\n return {\n successes: 0,\n failures: 0,\n advantages: 2,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n case 12:\n return {\n successes: 0,\n failures: 0,\n advantages: 0,\n threats: 0,\n triumphs: 1,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n default:\n return {\n successes: 0,\n failures: 0,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n }\n};\n\nconst challengeDieResult = (roll: number): DiceResult => {\n switch (roll) {\n case 2:\n case 3:\n return {\n successes: 0,\n failures: 1,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n case 4:\n case 5:\n return {\n successes: 0,\n failures: 2,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n case 6:\n case 7:\n return {\n successes: 0,\n failures: 0,\n advantages: 0,\n threats: 1,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n case 8:\n case 9:\n return {\n successes: 0,\n failures: 1,\n advantages: 0,\n threats: 1,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n case 10:\n case 11:\n return {\n successes: 0,\n failures: 0,\n advantages: 0,\n threats: 2,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n case 12:\n return {\n successes: 0,\n failures: 0,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 1,\n lightSide: 0,\n darkSide: 0,\n };\n default:\n return {\n successes: 0,\n failures: 0,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n }\n};\n\nconst forceDieResult = (roll: number): DiceResult => {\n switch (roll) {\n case 1:\n case 2:\n case 3:\n case 4:\n case 5:\n return {\n successes: 0,\n failures: 0,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 1,\n darkSide: 0,\n };\n case 6:\n case 7:\n return {\n successes: 0,\n failures: 0,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 2,\n darkSide: 0,\n };\n case 8:\n case 9:\n case 10:\n case 11:\n return {\n successes: 0,\n failures: 0,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 1,\n };\n case 12:\n return {\n successes: 0,\n failures: 0,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 2,\n };\n default:\n return {\n successes: 0,\n failures: 0,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n }\n};\n\nconst sumResults = (\n results: DiceResult[],\n options?: RollOptions,\n): DiceResult => {\n const sums = results.reduce(\n (acc, curr) => ({\n successes: acc.successes + curr.successes,\n failures: acc.failures + curr.failures,\n advantages: acc.advantages + curr.advantages,\n threats: acc.threats + curr.threats,\n triumphs: acc.triumphs + curr.triumphs,\n despair: acc.despair + curr.despair,\n lightSide: acc.lightSide + (curr.lightSide || 0),\n darkSide: acc.darkSide + (curr.darkSide || 0),\n }),\n {\n successes: 0,\n failures: 0,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n },\n );\n\n let netSuccesses = 0;\n let netFailures = 0;\n\n if (sums.successes === sums.failures) {\n netSuccesses = 0;\n netFailures = 0;\n } else if (sums.successes > sums.failures) {\n netSuccesses = sums.successes - sums.failures;\n } else {\n netFailures = sums.failures - sums.successes;\n }\n\n const result: DiceResult = {\n successes: netSuccesses,\n failures: netFailures,\n advantages: sums.advantages,\n threats: sums.threats,\n triumphs: sums.triumphs,\n despair: sums.despair,\n lightSide: sums.lightSide,\n darkSide: sums.darkSide,\n };\n\n return result;\n};\n\n/**\n * Rolls a dice pool and returns the results.\n *\n * @param pool - The dice pool to roll\n * @param options - Optional roll configuration including dice limits\n * @returns The roll results with detailed die information and summary\n * @throws {Error} If dice counts exceed configured limits\n *\n * Default limits:\n * - Max dice per type: 100 (configurable via options.maxDicePerType)\n * - Max total dice: 500 (configurable via options.maxTotalDice)\n */\nexport const roll = (pool: DicePool, options?: RollOptions): RollResult => {\n const boostCount = pool.boostDice ?? 0;\n const abilityCount = pool.abilityDice ?? 0;\n const proficiencyCount = pool.proficiencyDice ?? 0;\n const setBackCount = pool.setBackDice ?? 0;\n const difficultyCount = pool.difficultyDice ?? 0;\n const challengeCount = pool.challengeDice ?? 0;\n const forceCount = pool.forceDice ?? 0;\n\n // Get limits from options or use defaults\n const maxDicePerType = options?.maxDicePerType ?? DEFAULT_MAX_DICE_PER_TYPE;\n const maxTotalDice = options?.maxTotalDice ?? DEFAULT_MAX_TOTAL_DICE;\n\n // Ensure all dice counts are non-negative and apply per-type limits\n const sanitizedPool = {\n boostDice: Math.max(0, Math.min(boostCount, maxDicePerType)),\n abilityDice: Math.max(0, Math.min(abilityCount, maxDicePerType)),\n proficiencyDice: Math.max(0, Math.min(proficiencyCount, maxDicePerType)),\n setBackDice: Math.max(0, Math.min(setBackCount, maxDicePerType)),\n difficultyDice: Math.max(0, Math.min(difficultyCount, maxDicePerType)),\n challengeDice: Math.max(0, Math.min(challengeCount, maxDicePerType)),\n forceDice: Math.max(0, Math.min(forceCount, maxDicePerType)),\n };\n\n // Check if any dice counts exceeded the per-type limit\n const exceedsPerTypeLimit =\n boostCount > maxDicePerType ||\n abilityCount > maxDicePerType ||\n proficiencyCount > maxDicePerType ||\n setBackCount > maxDicePerType ||\n difficultyCount > maxDicePerType ||\n challengeCount > maxDicePerType ||\n forceCount > maxDicePerType;\n\n // Calculate total dice count\n const totalDice =\n sanitizedPool.boostDice +\n sanitizedPool.abilityDice +\n sanitizedPool.proficiencyDice +\n sanitizedPool.setBackDice +\n sanitizedPool.difficultyDice +\n sanitizedPool.challengeDice +\n sanitizedPool.forceDice;\n\n // Check total dice limit\n if (totalDice > maxTotalDice) {\n throw new Error(\n `Total dice count (${totalDice}) exceeds maximum allowed (${maxTotalDice}). ` +\n `Please reduce the number of dice in your pool.`,\n );\n }\n\n // Warn if per-type limits were exceeded (but continue with capped values)\n if (exceedsPerTypeLimit && options?.throwOnLimitExceeded) {\n const exceeded = [];\n if (boostCount > maxDicePerType) exceeded.push(`boost: ${boostCount}`);\n if (abilityCount > maxDicePerType)\n exceeded.push(`ability: ${abilityCount}`);\n if (proficiencyCount > maxDicePerType)\n exceeded.push(`proficiency: ${proficiencyCount}`);\n if (setBackCount > maxDicePerType)\n exceeded.push(`setback: ${setBackCount}`);\n if (difficultyCount > maxDicePerType)\n exceeded.push(`difficulty: ${difficultyCount}`);\n if (challengeCount > maxDicePerType)\n exceeded.push(`challenge: ${challengeCount}`);\n if (forceCount > maxDicePerType) exceeded.push(`force: ${forceCount}`);\n\n throw new Error(\n `Dice counts exceed per-type limit (${maxDicePerType}): ${exceeded.join(\", \")}. ` +\n `Dice counts have been capped to the maximum.`,\n );\n }\n\n const detailedResults: DetailedDieResult[] = [];\n\n // Roll boost dice\n for (let i = 0; i < sanitizedPool.boostDice; i++) {\n const roll = rollDie(6);\n detailedResults.push({\n type: \"boost\",\n roll,\n result: boostDieResult(roll),\n });\n }\n\n // Roll ability dice\n for (let i = 0; i < sanitizedPool.abilityDice; i++) {\n const roll = rollDie(8);\n detailedResults.push({\n type: \"ability\",\n roll,\n result: abilityDieResult(roll),\n });\n }\n\n // Roll proficiency dice\n for (let i = 0; i < sanitizedPool.proficiencyDice; i++) {\n const roll = rollDie(12);\n detailedResults.push({\n type: \"proficiency\",\n roll,\n result: proficiencyDieResult(roll),\n });\n }\n\n // Roll setback dice\n for (let i = 0; i < sanitizedPool.setBackDice; i++) {\n const roll = rollDie(6);\n detailedResults.push({\n type: \"setback\",\n roll,\n result: setBackDieResult(roll),\n });\n }\n\n // Roll difficulty dice\n for (let i = 0; i < sanitizedPool.difficultyDice; i++) {\n const roll = rollDie(8);\n detailedResults.push({\n type: \"difficulty\",\n roll,\n result: difficultyDieResult(roll),\n });\n }\n\n // Roll challenge dice\n for (let i = 0; i < sanitizedPool.challengeDice; i++) {\n const roll = rollDie(12);\n detailedResults.push({\n type: \"challenge\",\n roll,\n result: challengeDieResult(roll),\n });\n }\n\n // Roll force dice\n for (let i = 0; i < sanitizedPool.forceDice; i++) {\n const roll = rollDie(12);\n detailedResults.push({\n type: \"force\",\n roll,\n result: forceDieResult(roll),\n });\n }\n\n const summary = sumResults(detailedResults.map((r) => r.result));\n\n if (options?.hints) {\n const applicableHints = hints.filter((hint) => {\n const { cost } = hint;\n // For OR conditions: at least one option must be fully satisfied\n // Each entry in cost represents an alternative way to pay for the hint\n return Object.entries(cost).some(([symbol, required]) => {\n const summaryKey = (symbol.toLowerCase() + \"s\") as keyof typeof summary;\n const value = summary[summaryKey];\n if (typeof value !== \"number\") return false;\n // Check if we have enough of this symbol type to afford the hint\n return required !== undefined && required > 0 && value >= required;\n });\n });\n summary.hints = applicableHints.map(\n (hint) => `${hintCostDisplayText(hint)} - ${hint.description}`,\n );\n }\n\n return {\n results: detailedResults,\n summary: summary,\n };\n};\n","import { DicePool } from \"./types\";\n\n/**\n * Creates a basic skill check dice pool\n * @param ability Number of ability (green) dice\n * @param proficiency Number of proficiency (yellow) dice\n * @returns DicePool configured for a basic skill check\n */\nexport const createSkillCheck = (\n ability: number,\n proficiency: number,\n): DicePool => ({\n abilityDice: Math.max(0, ability),\n proficiencyDice: Math.max(0, proficiency),\n});\n\n/**\n * Creates a combat check dice pool with optional boost die\n * @param ability Number of ability (green) dice\n * @param proficiency Number of proficiency (yellow) dice\n * @param boost Number of boost (blue) dice\n * @returns DicePool configured for a combat check\n */\nexport const createCombatCheck = (\n ability: number,\n proficiency: number,\n boost: number = 0,\n): DicePool => ({\n abilityDice: Math.max(0, ability),\n proficiencyDice: Math.max(0, proficiency),\n boostDice: Math.max(0, boost),\n});\n\n/**\n * Creates an opposed check dice pool\n * @param ability Number of ability (green) dice\n * @param proficiency Number of proficiency (yellow) dice\n * @param difficulty Number of difficulty (purple) dice\n * @param challenge Number of challenge (red) dice\n * @returns DicePool configured for an opposed check\n */\nexport const createOpposedCheck = (\n ability: number,\n proficiency: number,\n difficulty: number,\n challenge: number = 0,\n): DicePool => ({\n abilityDice: Math.max(0, ability),\n proficiencyDice: Math.max(0, proficiency),\n difficultyDice: Math.max(0, difficulty),\n challengeDice: Math.max(0, challenge),\n});\n\n/**\n * Creates a difficulty check dice pool\n * @param difficulty Number of difficulty (purple) dice\n * @param challenge Number of challenge (red) dice\n * @returns DicePool configured for a pure difficulty check\n */\nexport const createDifficultyPool = (\n difficulty: number,\n challenge: number = 0,\n): DicePool => ({\n difficultyDice: Math.max(0, difficulty),\n challengeDice: Math.max(0, challenge),\n});\n"],"names":["SYMBOLS","hints","description","cost","SYMBOLS_ADVANTAGE","SYMBOLS_TRIUMPH","SYMBOLS_THREAT","SYMBOLS_DESPAIR","rollDie","sides","Math","floor","random","boostDieResult","roll","successes","failures","advantages","threats","triumphs","despair","lightSide","darkSide","setBackDieResult","abilityDieResult","difficultyDieResult","proficiencyDieResult","challengeDieResult","forceDieResult","ability","proficiency","boost","abilityDice","max","proficiencyDice","boostDice","difficulty","challenge","difficultyDice","challengeDice","pool","options","boostCount","_a","abilityCount","_b","proficiencyCount","_c","setBackCount","_d","setBackDice","difficultyCount","_e","challengeCount","_f","forceCount","_g","forceDice","maxDicePerType","_h","maxTotalDice","_j","sanitizedPool","min","exceedsPerTypeLimit","totalDice","Error","throwOnLimitExceeded","exceeded","push","join","detailedResults","i","type","result","summary","results","sums","reduce","acc","curr","netSuccesses","netFailures","sumResults","map","r","applicableHints","filter","hint","Object","entries","some","symbol","required","summaryKey","toLowerCase","value","undefined","keys","length","parts","_","count","charAt","toUpperCase","slice","hintCostDisplayText"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const e="ADVANTAGE",s="THREAT",t="TRIUMPH",a="DESPAIR",r=[{description:"Recover one strain (may be applied more than once).",cost:{[e]:1,[t]:1}},{description:"Add a boost die to the next allied active character's check.",cost:{[e]:1,[t]:1}},{description:"Notice a single important point in the ongoing conflict, such as the location of a blast door's control panel or a weak point on an attack speeder.",cost:{[e]:1,[t]:1}},{description:"Inflict a Critical Injury with a successful attack that deals damage past soak (Advantage cost may vary).",cost:{[e]:1,[t]:1}},{description:"Activate a weapon quality (Advantage cost may vary).",cost:{[e]:1,[t]:1}},{description:"Perform an immediate free maneuver that does not exceed the two maneuver per turn limit.",cost:{[e]:2,[t]:1}},{description:"Add a setback die to the targeted character's next check.",cost:{[e]:2,[t]:1}},{description:"Add a boost die to any allied character's next check, including that of the active character.",cost:{[e]:2,[t]:1}},{description:"Negate the targeted enemy's defensive bonuses (such as the defense gained from cover, equipment, or performing the Guarded Stance maneuver) util the end of the current round.",cost:{[e]:3,[t]:1}},{description:"Ignore penalizing environmental effects such as inclement weather, zero gravity, or similar circumstances until the end of the active character's next turn.",cost:{[e]:3,[t]:1}},{description:"When dealing damage to a target, have the attack disable the opponent or one piece of gear rather than dealing wounds or strain. This could include hobbling them temporarily with a shot to the leg, or disabling their comlink. This should be agreed upon by the player and the GM, and the effects are up to the GM (although Table 6-10: Critical Injury Result is a god resource to consult for possible effects). The effects should be temporary and not too excessive.",cost:{[e]:3,[t]:1}},{description:"Gain + 1 melee or ranged defense until the end of the active character's next turn.",cost:{[e]:3,[t]:1}},{description:"Force the target to drop a melee or ranged weapon they are wielding.",cost:{[e]:3,[t]:1}},{description:"Upgrade the difficulty of the targeted character's next check.",cost:{[t]:1}},{description:"Do something vital, such as shooting the controls to the nearby blast doors to seal them shut.",cost:{[t]:1}},{description:"Upgrade any allied character's next check, including that of the current active character.",cost:{[t]:1}},{description:"When dealing damage to a target, have the attack destroy a piece of equipment the target is using, such as blowing up his blaster or destroying a personal shield generator.",cost:{[t]:2}},{description:"The active character suffers 1 strain.",cost:{[s]:1,[a]:1}},{description:"The active character loses the benefits of a prior maneuver (such as from taking cover or assuming a Guarded Stance) until they perform the maneuver again.",cost:{[s]:1,[a]:1}},{description:"An opponent may immediately perform one free maneuver in response to the active character's check.",cost:{[s]:2,[a]:1}},{description:"Add a boost die to the targeted character's next check.",cost:{[s]:1,[a]:1}},{description:"The active character or an allied character suffers a setback die on their next action.",cost:{[s]:2,[a]:1}},{description:"The active character falls prone.",cost:{[s]:3,[a]:1}},{description:"The active character grants the enemy a significant advantage in the ongoing encounter, such as accidentally blasting the controls to a bridge the active character was planning to use for their escape.",cost:{[s]:3,[a]:1}},{description:"The character's ranged weapon imediately runs out of ammunition and may not be used for the remainder of the encounter.",cost:{[a]:1}},{description:"Upgrade the difficulty of an allied character's next check, including that of the current active character.",cost:{[a]:1}},{description:"The tool or melee weapon the character is using becomes damaged.",cost:{[a]:1}}];const i=e=>Math.floor(Math.random()*e)+1,c=e=>{switch(e){case 3:return{successes:1,failures:0,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};case 4:return{successes:1,failures:0,advantages:1,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};case 5:return{successes:0,failures:0,advantages:2,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};case 6:return{successes:0,failures:0,advantages:1,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};default:return{successes:0,failures:0,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0}}},d=e=>{switch(e){case 3:case 4:return{successes:0,failures:1,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};case 5:case 6:return{successes:0,failures:0,advantages:0,threats:1,triumphs:0,despair:0,lightSide:0,darkSide:0};default:return{successes:0,failures:0,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0}}},n=e=>{switch(e){case 2:case 3:return{successes:1,failures:0,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};case 4:return{successes:2,failures:0,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};case 5:case 6:return{successes:0,failures:0,advantages:1,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};case 7:return{successes:1,failures:0,advantages:1,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};case 8:return{successes:0,failures:0,advantages:2,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};default:return{successes:0,failures:0,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0}}},h=e=>{switch(e){case 2:return{successes:0,failures:1,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};case 3:return{successes:0,failures:2,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};case 4:case 5:case 6:return{successes:0,failures:0,advantages:0,threats:1,triumphs:0,despair:0,lightSide:0,darkSide:0};case 7:return{successes:0,failures:0,advantages:0,threats:2,triumphs:0,despair:0,lightSide:0,darkSide:0};case 8:return{successes:0,failures:1,advantages:0,threats:1,triumphs:0,despair:0,lightSide:0,darkSide:0};default:return{successes:0,failures:0,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0}}},u=e=>{switch(e){case 2:case 3:return{successes:1,failures:0,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};case 4:case 5:return{successes:2,failures:0,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};case 6:return{successes:0,failures:0,advantages:1,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};case 7:case 8:case 9:return{successes:1,failures:0,advantages:1,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};case 10:case 11:return{successes:0,failures:0,advantages:2,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};case 12:return{successes:0,failures:0,advantages:0,threats:0,triumphs:1,despair:0,lightSide:0,darkSide:0};default:return{successes:0,failures:0,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0}}},o=e=>{switch(e){case 2:case 3:return{successes:0,failures:1,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};case 4:case 5:return{successes:0,failures:2,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};case 6:case 7:return{successes:0,failures:0,advantages:0,threats:1,triumphs:0,despair:0,lightSide:0,darkSide:0};case 8:case 9:return{successes:0,failures:1,advantages:0,threats:1,triumphs:0,despair:0,lightSide:0,darkSide:0};case 10:case 11:return{successes:0,failures:0,advantages:0,threats:2,triumphs:0,despair:0,lightSide:0,darkSide:0};case 12:return{successes:0,failures:0,advantages:0,threats:0,triumphs:0,despair:1,lightSide:0,darkSide:0};default:return{successes:0,failures:0,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0}}},l=e=>{switch(e){case 1:case 2:case 3:case 4:case 5:return{successes:0,failures:0,advantages:0,threats:0,triumphs:0,despair:0,lightSide:1,darkSide:0};case 6:case 7:return{successes:0,failures:0,advantages:0,threats:0,triumphs:0,despair:0,lightSide:2,darkSide:0};case 8:case 9:case 10:case 11:return{successes:0,failures:0,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:1};case 12:return{successes:0,failures:0,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:2};default:return{successes:0,failures:0,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0}}},p=(e,s)=>{var t,a,p,g,f,m,v,S,k;const y=null!==(t=e.boostDice)&&void 0!==t?t:0,b=null!==(a=e.abilityDice)&&void 0!==a?a:0,x=null!==(p=e.proficiencyDice)&&void 0!==p?p:0,M=null!==(g=e.setBackDice)&&void 0!==g?g:0,w=null!==(f=e.difficultyDice)&&void 0!==f?f:0,D=null!==(m=e.challengeDice)&&void 0!==m?m:0,T=null!==(v=e.forceDice)&&void 0!==v?v:0,$=null!==(S=null==s?void 0:s.maxDicePerType)&&void 0!==S?S:100,A=null!==(k=null==s?void 0:s.maxTotalDice)&&void 0!==k?k:500,j=Math.max(0,Math.min(y,$)),E=Math.max(0,Math.min(b,$)),G=Math.max(0,Math.min(x,$)),I=Math.max(0,Math.min(M,$)),R=Math.max(0,Math.min(w,$)),C=Math.max(0,Math.min(D,$)),N=Math.max(0,Math.min(T,$)),O=y>$||b>$||x>$||M>$||w>$||D>$||T>$,P=j+E+G+I+R+C+N;if(P>A)throw new Error(`Total dice count (${P}) exceeds maximum allowed (${A}). Please reduce the number of dice in your pool.`);if(O&&(null==s?void 0:s.throwOnLimitExceeded)){const e=[];throw y>$&&e.push(`boost: ${y}`),b>$&&e.push(`ability: ${b}`),x>$&&e.push(`proficiency: ${x}`),M>$&&e.push(`setback: ${M}`),w>$&&e.push(`difficulty: ${w}`),D>$&&e.push(`challenge: ${D}`),T>$&&e.push(`force: ${T}`),new Error(`Dice counts exceed per-type limit (${$}): ${e.join(", ")}. Dice counts have been capped to the maximum.`)}const U=[];for(let e=0;e<j;e++){const e=i(6);U.push({type:"boost",roll:e,result:c(e)})}for(let e=0;e<E;e++){const e=i(8);U.push({type:"ability",roll:e,result:n(e)})}for(let e=0;e<G;e++){const e=i(12);U.push({type:"proficiency",roll:e,result:u(e)})}for(let e=0;e<I;e++){const e=i(6);U.push({type:"setback",roll:e,result:d(e)})}for(let e=0;e<R;e++){const e=i(8);U.push({type:"difficulty",roll:e,result:h(e)})}for(let e=0;e<C;e++){const e=i(12);U.push({type:"challenge",roll:e,result:o(e)})}for(let e=0;e<N;e++){const e=i(12);U.push({type:"force",roll:e,result:l(e)})}const q=(e=>{const s=e.reduce((e,s)=>({successes:e.successes+s.successes,failures:e.failures+s.failures,advantages:e.advantages+s.advantages,threats:e.threats+s.threats,triumphs:e.triumphs+s.triumphs,despair:e.despair+s.despair,lightSide:e.lightSide+(s.lightSide||0),darkSide:e.darkSide+(s.darkSide||0)}),{successes:0,failures:0,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0});let t=0,a=0;return s.successes===s.failures?(t=0,a=0):s.successes>s.failures?t=s.successes-s.failures:a=s.failures-s.successes,{successes:t,failures:a,advantages:s.advantages,threats:s.threats,triumphs:s.triumphs,despair:s.despair,lightSide:s.lightSide,darkSide:s.darkSide}})(U.map(e=>e.result));if(null==s?void 0:s.hints){const e=r.filter(e=>{const{cost:s}=e;return Object.entries(s).some(([e,s])=>{const t=e.toLowerCase()+"s",a=q[t];return"number"==typeof a&&(void 0!==s&&s>0&&a>=s)})});q.hints=e.map(e=>`${function(e){if(!e.cost||0===Object.keys(e.cost).length)return"No cost";const s=Object.entries(e.cost).filter(([e,s])=>s&&s>0).map(([e,s])=>`${s} ${e.charAt(0).toUpperCase()+e.toLowerCase().slice(1)}${s>1?"s":""}`);return s.length>1?s.join(" OR "):s.length>0?s[0]:"No cost"}(e)} - ${e.description}`)}return{results:U,summary:q}},g=(e,s)=>({abilityDice:Math.max(0,e),proficiencyDice:Math.max(0,s)}),f=(e,s,t=0)=>({abilityDice:Math.max(0,e),proficiencyDice:Math.max(0,s),boostDice:Math.max(0,t)}),m=(e,s,t,a=0)=>({abilityDice:Math.max(0,e),proficiencyDice:Math.max(0,s),difficultyDice:Math.max(0,t),challengeDice:Math.max(0,a)}),v=(e,s=0)=>({difficultyDice:Math.max(0,e),challengeDice:Math.max(0,s)});export{f as createCombatCheck,v as createDifficultyPool,m as createOpposedCheck,g as createSkillCheck,p as roll};
|
|
2
|
+
//# sourceMappingURL=bundle.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bundle.esm.js","sources":["../src/types.ts","../src/hints.ts","../src/dice.ts","../src/pools.ts"],"sourcesContent":["export type DicePool = {\n boostDice?: number;\n abilityDice?: number;\n proficiencyDice?: number;\n setBackDice?: number;\n difficultyDice?: number;\n challengeDice?: number;\n forceDice?: number;\n};\n\nexport type DiceResult = {\n successes: number;\n failures: number;\n advantages: number;\n threats: number;\n triumphs: number;\n despair: number;\n lightSide: number;\n darkSide: number;\n hints?: string[];\n};\n\nexport type DieType =\n | \"boost\"\n | \"ability\"\n | \"proficiency\"\n | \"setback\"\n | \"difficulty\"\n | \"challenge\"\n | \"force\";\n\nexport type DetailedDieResult = {\n type: DieType;\n roll: number;\n result: DiceResult;\n};\n\nexport type RollResult = {\n results: DetailedDieResult[];\n summary: DiceResult;\n};\n\nexport const SYMBOLS = {\n SUCCESS: \"SUCCESS\" as const,\n FAILURE: \"FAILURE\" as const,\n ADVANTAGE: \"ADVANTAGE\" as const,\n THREAT: \"THREAT\" as const,\n TRIUMPH: \"TRIUMPH\" as const,\n DESPAIR: \"DESPAIR\" as const,\n LIGHT: \"LIGHT\" as const,\n DARK: \"DARK\" as const,\n} as const;\n\nexport type Symbol = keyof typeof SYMBOLS;\n\nexport type RollOptions = {\n hints?: boolean;\n /**\n * Maximum number of dice allowed per die type.\n * Default: 100\n */\n maxDicePerType?: number;\n /**\n * Maximum total number of dice allowed in a single roll.\n * Default: 500\n */\n maxTotalDice?: number;\n /**\n * Whether to throw an error when dice limits are exceeded.\n * If false, dice counts will be silently capped to the maximum.\n * Default: false\n */\n throwOnLimitExceeded?: boolean;\n};\n","import { SYMBOLS, type Symbol } from \"./types\";\n\n// 1 advantage or 1 triumph\nconst recoverOneStrain = \"Recover one strain (may be applied more than once).\";\nconst addBoostDieToActiveAlly =\n \"Add a boost die to the next allied active character's check.\";\nconst noticeImportantPoint =\n \"Notice a single important point in the ongoing conflict, such as the location of a blast door's control panel or a weak point on an attack speeder.\";\nconst inflictCriticalInjury =\n \"Inflict a Critical Injury with a successful attack that deals damage past soak (Advantage cost may vary).\";\nconst activateWeaponQuality =\n \"Activate a weapon quality (Advantage cost may vary).\";\n\n// 2 advantage or 1 triumph\nconst performManeuver =\n \"Perform an immediate free maneuver that does not exceed the two maneuver per turn limit.\";\nconst addSetbackDie =\n \"Add a setback die to the targeted character's next check.\";\nconst addBoostDieToAnyAlly =\n \"Add a boost die to any allied character's next check, including that of the active character.\";\n\n// 3 advantage or 1 triumph\nconst negateEnemy =\n \"Negate the targeted enemy's defensive bonuses (such as the defense gained from cover, equipment, or performing the Guarded Stance maneuver) util the end of the current round.\";\nconst ignoreEnvironment =\n \"Ignore penalizing environmental effects such as inclement weather, zero gravity, or similar circumstances until the end of the active character's next turn.\";\nconst disableOpponent =\n \"When dealing damage to a target, have the attack disable the opponent or one piece of gear rather than dealing wounds or strain. This could include hobbling them temporarily with a shot to the leg, or disabling their comlink. This should be agreed upon by the player and the GM, and the effects are up to the GM (although Table 6-10: Critical Injury Result is a god resource to consult for possible effects). The effects should be temporary and not too excessive.\";\nconst gainDefense =\n \"Gain + 1 melee or ranged defense until the end of the active character's next turn.\";\nconst dropWeapon =\n \"Force the target to drop a melee or ranged weapon they are wielding.\";\n\n// 1 triumph\nconst upgradeDifficultyTargetedCharacter =\n \"Upgrade the difficulty of the targeted character's next check.\";\nconst doSomethingVital =\n \"Do something vital, such as shooting the controls to the nearby blast doors to seal them shut.\";\nconst upgradeAnyAllyCheck =\n \"Upgrade any allied character's next check, including that of the current active character.\";\n\n// 2 triumph\nconst destroyEquipment =\n \"When dealing damage to a target, have the attack destroy a piece of equipment the target is using, such as blowing up his blaster or destroying a personal shield generator.\";\n\n// 1 threat or 1 despair\nconst sufferStrain = \"The active character suffers 1 strain.\";\nconst loseManeuverBenefit =\n \"The active character loses the benefits of a prior maneuver (such as from taking cover or assuming a Guarded Stance) until they perform the maneuver again.\";\n\n// 2 threat or 1 despair\nconst freeManeuver =\n \"An opponent may immediately perform one free maneuver in response to the active character's check.\";\nconst addBoostDieToTargetedCharacter =\n \"Add a boost die to the targeted character's next check.\";\nconst sufferSetback =\n \"The active character or an allied character suffers a setback die on their next action.\";\n\n// 3 threat or 1 despair\nconst fallProne = \"The active character falls prone.\";\nconst gainSignificantAdvantage =\n \"The active character grants the enemy a significant advantage in the ongoing encounter, such as accidentally blasting the controls to a bridge the active character was planning to use for their escape.\";\n\n// 1 despair\nconst outOfAmmo =\n \"The character's ranged weapon imediately runs out of ammunition and may not be used for the remainder of the encounter.\";\nconst upgradeDifficultyAlliedCharacter =\n \"Upgrade the difficulty of an allied character's next check, including that of the current active character.\";\nconst damagedItem =\n \"The tool or melee weapon the character is using becomes damaged.\";\n\nexport type CostType = {\n [key in Symbol]?: number;\n};\n\ntype Hint = {\n description: string;\n cost: CostType;\n};\n\nexport const hints: Hint[] = [\n // 1 advantage or 1 triumph\n {\n description: recoverOneStrain,\n cost: {\n [SYMBOLS.ADVANTAGE]: 1,\n [SYMBOLS.TRIUMPH]: 1,\n },\n },\n {\n description: addBoostDieToActiveAlly,\n cost: {\n [SYMBOLS.ADVANTAGE]: 1,\n [SYMBOLS.TRIUMPH]: 1,\n },\n },\n {\n description: noticeImportantPoint,\n cost: {\n [SYMBOLS.ADVANTAGE]: 1,\n [SYMBOLS.TRIUMPH]: 1,\n },\n },\n {\n description: inflictCriticalInjury,\n cost: {\n [SYMBOLS.ADVANTAGE]: 1,\n [SYMBOLS.TRIUMPH]: 1,\n },\n },\n {\n description: activateWeaponQuality,\n cost: {\n [SYMBOLS.ADVANTAGE]: 1,\n [SYMBOLS.TRIUMPH]: 1,\n },\n },\n // 2 advantage or 1 triumph\n {\n description: performManeuver,\n cost: {\n [SYMBOLS.ADVANTAGE]: 2,\n [SYMBOLS.TRIUMPH]: 1,\n },\n },\n {\n description: addSetbackDie,\n cost: {\n [SYMBOLS.ADVANTAGE]: 2,\n [SYMBOLS.TRIUMPH]: 1,\n },\n },\n {\n description: addBoostDieToAnyAlly,\n cost: {\n [SYMBOLS.ADVANTAGE]: 2,\n [SYMBOLS.TRIUMPH]: 1,\n },\n },\n // 3 advantage or 1 triumph\n {\n description: negateEnemy,\n cost: {\n [SYMBOLS.ADVANTAGE]: 3,\n [SYMBOLS.TRIUMPH]: 1,\n },\n },\n {\n description: ignoreEnvironment,\n cost: {\n [SYMBOLS.ADVANTAGE]: 3,\n [SYMBOLS.TRIUMPH]: 1,\n },\n },\n {\n description: disableOpponent,\n cost: {\n [SYMBOLS.ADVANTAGE]: 3,\n [SYMBOLS.TRIUMPH]: 1,\n },\n },\n {\n description: gainDefense,\n cost: {\n [SYMBOLS.ADVANTAGE]: 3,\n [SYMBOLS.TRIUMPH]: 1,\n },\n },\n {\n description: dropWeapon,\n cost: {\n [SYMBOLS.ADVANTAGE]: 3,\n [SYMBOLS.TRIUMPH]: 1,\n },\n },\n // 1 triumph\n {\n description: upgradeDifficultyTargetedCharacter,\n cost: {\n [SYMBOLS.TRIUMPH]: 1,\n },\n },\n {\n description: doSomethingVital,\n cost: {\n [SYMBOLS.TRIUMPH]: 1,\n },\n },\n {\n description: upgradeAnyAllyCheck,\n cost: {\n [SYMBOLS.TRIUMPH]: 1,\n },\n },\n // 2 triumph\n {\n description: destroyEquipment,\n cost: {\n [SYMBOLS.TRIUMPH]: 2,\n },\n },\n // 1 threat or 1 despair\n {\n description: sufferStrain,\n cost: {\n [SYMBOLS.THREAT]: 1,\n [SYMBOLS.DESPAIR]: 1,\n },\n },\n {\n description: loseManeuverBenefit,\n cost: {\n [SYMBOLS.THREAT]: 1,\n [SYMBOLS.DESPAIR]: 1,\n },\n },\n // 2 threat or 1 despair\n {\n description: freeManeuver,\n cost: {\n [SYMBOLS.THREAT]: 2,\n [SYMBOLS.DESPAIR]: 1,\n },\n },\n {\n description: addBoostDieToTargetedCharacter,\n cost: {\n [SYMBOLS.THREAT]: 1,\n [SYMBOLS.DESPAIR]: 1,\n },\n },\n {\n description: sufferSetback,\n cost: {\n [SYMBOLS.THREAT]: 2,\n [SYMBOLS.DESPAIR]: 1,\n },\n },\n // 3 threat or 1 despair\n {\n description: fallProne,\n cost: {\n [SYMBOLS.THREAT]: 3,\n [SYMBOLS.DESPAIR]: 1,\n },\n },\n {\n description: gainSignificantAdvantage,\n cost: {\n [SYMBOLS.THREAT]: 3,\n [SYMBOLS.DESPAIR]: 1,\n },\n },\n // 1 despair\n {\n description: outOfAmmo,\n cost: {\n [SYMBOLS.DESPAIR]: 1,\n },\n },\n {\n description: upgradeDifficultyAlliedCharacter,\n cost: {\n [SYMBOLS.DESPAIR]: 1,\n },\n },\n {\n description: damagedItem,\n cost: {\n [SYMBOLS.DESPAIR]: 1,\n },\n },\n];\n\nexport function hintCostDisplayText(hint: Hint): string {\n if (!hint.cost || Object.keys(hint.cost).length === 0) {\n return \"No cost\";\n }\n const parts = Object.entries(hint.cost)\n .filter(([_, count]) => count && count > 0)\n .map(([symbol, count]) => {\n const symbolName =\n symbol.charAt(0).toUpperCase() + symbol.toLowerCase().slice(1);\n const plural = count > 1 ? \"s\" : \"\";\n return `${count} ${symbolName}${plural}`;\n });\n\n // Use \"OR\" in uppercase for clarity when multiple options exist\n if (parts.length > 1) {\n return parts.join(\" OR \");\n }\n return parts.length > 0 ? parts[0] : \"No cost\";\n}\n","import { hintCostDisplayText, hints } from \"./hints\";\nimport {\n DicePool,\n RollResult,\n DiceResult,\n DetailedDieResult,\n RollOptions,\n} from \"./types\";\n\n// Default dice limits for performance and security\nexport const DEFAULT_MAX_DICE_PER_TYPE = 100;\nexport const DEFAULT_MAX_TOTAL_DICE = 500;\n\nconst rollDie = (sides: number): number =>\n Math.floor(Math.random() * sides) + 1;\n\nconst boostDieResult = (roll: number): DiceResult => {\n switch (roll) {\n case 3:\n return {\n successes: 1,\n failures: 0,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n case 4:\n return {\n successes: 1,\n failures: 0,\n advantages: 1,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n case 5:\n return {\n successes: 0,\n failures: 0,\n advantages: 2,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n case 6:\n return {\n successes: 0,\n failures: 0,\n advantages: 1,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n default:\n return {\n successes: 0,\n failures: 0,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n }\n};\n\nconst setBackDieResult = (roll: number): DiceResult => {\n switch (roll) {\n case 3:\n case 4:\n return {\n successes: 0,\n failures: 1,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n case 5:\n case 6:\n return {\n successes: 0,\n failures: 0,\n advantages: 0,\n threats: 1,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n default:\n return {\n successes: 0,\n failures: 0,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n }\n};\n\nconst abilityDieResult = (roll: number): DiceResult => {\n switch (roll) {\n case 2:\n case 3:\n return {\n successes: 1,\n failures: 0,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n case 4:\n return {\n successes: 2,\n failures: 0,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n case 5:\n case 6:\n return {\n successes: 0,\n failures: 0,\n advantages: 1,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n case 7:\n return {\n successes: 1,\n failures: 0,\n advantages: 1,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n case 8:\n return {\n successes: 0,\n failures: 0,\n advantages: 2,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n default:\n return {\n successes: 0,\n failures: 0,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n }\n};\n\nconst difficultyDieResult = (roll: number): DiceResult => {\n switch (roll) {\n case 2:\n return {\n successes: 0,\n failures: 1,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n case 3:\n return {\n successes: 0,\n failures: 2,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n case 4:\n case 5:\n case 6:\n return {\n successes: 0,\n failures: 0,\n advantages: 0,\n threats: 1,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n case 7:\n return {\n successes: 0,\n failures: 0,\n advantages: 0,\n threats: 2,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n case 8:\n return {\n successes: 0,\n failures: 1,\n advantages: 0,\n threats: 1,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n default:\n return {\n successes: 0,\n failures: 0,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n }\n};\n\nconst proficiencyDieResult = (roll: number): DiceResult => {\n switch (roll) {\n case 2:\n case 3:\n return {\n successes: 1,\n failures: 0,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n case 4:\n case 5:\n return {\n successes: 2,\n failures: 0,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n case 6:\n return {\n successes: 0,\n failures: 0,\n advantages: 1,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n case 7:\n case 8:\n case 9:\n return {\n successes: 1,\n failures: 0,\n advantages: 1,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n case 10:\n case 11:\n return {\n successes: 0,\n failures: 0,\n advantages: 2,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n case 12:\n return {\n successes: 0,\n failures: 0,\n advantages: 0,\n threats: 0,\n triumphs: 1,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n default:\n return {\n successes: 0,\n failures: 0,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n }\n};\n\nconst challengeDieResult = (roll: number): DiceResult => {\n switch (roll) {\n case 2:\n case 3:\n return {\n successes: 0,\n failures: 1,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n case 4:\n case 5:\n return {\n successes: 0,\n failures: 2,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n case 6:\n case 7:\n return {\n successes: 0,\n failures: 0,\n advantages: 0,\n threats: 1,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n case 8:\n case 9:\n return {\n successes: 0,\n failures: 1,\n advantages: 0,\n threats: 1,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n case 10:\n case 11:\n return {\n successes: 0,\n failures: 0,\n advantages: 0,\n threats: 2,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n case 12:\n return {\n successes: 0,\n failures: 0,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 1,\n lightSide: 0,\n darkSide: 0,\n };\n default:\n return {\n successes: 0,\n failures: 0,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n }\n};\n\nconst forceDieResult = (roll: number): DiceResult => {\n switch (roll) {\n case 1:\n case 2:\n case 3:\n case 4:\n case 5:\n return {\n successes: 0,\n failures: 0,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 1,\n darkSide: 0,\n };\n case 6:\n case 7:\n return {\n successes: 0,\n failures: 0,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 2,\n darkSide: 0,\n };\n case 8:\n case 9:\n case 10:\n case 11:\n return {\n successes: 0,\n failures: 0,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 1,\n };\n case 12:\n return {\n successes: 0,\n failures: 0,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 2,\n };\n default:\n return {\n successes: 0,\n failures: 0,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n }\n};\n\nconst sumResults = (\n results: DiceResult[],\n options?: RollOptions,\n): DiceResult => {\n const sums = results.reduce(\n (acc, curr) => ({\n successes: acc.successes + curr.successes,\n failures: acc.failures + curr.failures,\n advantages: acc.advantages + curr.advantages,\n threats: acc.threats + curr.threats,\n triumphs: acc.triumphs + curr.triumphs,\n despair: acc.despair + curr.despair,\n lightSide: acc.lightSide + (curr.lightSide || 0),\n darkSide: acc.darkSide + (curr.darkSide || 0),\n }),\n {\n successes: 0,\n failures: 0,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n },\n );\n\n let netSuccesses = 0;\n let netFailures = 0;\n\n if (sums.successes === sums.failures) {\n netSuccesses = 0;\n netFailures = 0;\n } else if (sums.successes > sums.failures) {\n netSuccesses = sums.successes - sums.failures;\n } else {\n netFailures = sums.failures - sums.successes;\n }\n\n const result: DiceResult = {\n successes: netSuccesses,\n failures: netFailures,\n advantages: sums.advantages,\n threats: sums.threats,\n triumphs: sums.triumphs,\n despair: sums.despair,\n lightSide: sums.lightSide,\n darkSide: sums.darkSide,\n };\n\n return result;\n};\n\n/**\n * Rolls a dice pool and returns the results.\n *\n * @param pool - The dice pool to roll\n * @param options - Optional roll configuration including dice limits\n * @returns The roll results with detailed die information and summary\n * @throws {Error} If dice counts exceed configured limits\n *\n * Default limits:\n * - Max dice per type: 100 (configurable via options.maxDicePerType)\n * - Max total dice: 500 (configurable via options.maxTotalDice)\n */\nexport const roll = (pool: DicePool, options?: RollOptions): RollResult => {\n const boostCount = pool.boostDice ?? 0;\n const abilityCount = pool.abilityDice ?? 0;\n const proficiencyCount = pool.proficiencyDice ?? 0;\n const setBackCount = pool.setBackDice ?? 0;\n const difficultyCount = pool.difficultyDice ?? 0;\n const challengeCount = pool.challengeDice ?? 0;\n const forceCount = pool.forceDice ?? 0;\n\n // Get limits from options or use defaults\n const maxDicePerType = options?.maxDicePerType ?? DEFAULT_MAX_DICE_PER_TYPE;\n const maxTotalDice = options?.maxTotalDice ?? DEFAULT_MAX_TOTAL_DICE;\n\n // Ensure all dice counts are non-negative and apply per-type limits\n const sanitizedPool = {\n boostDice: Math.max(0, Math.min(boostCount, maxDicePerType)),\n abilityDice: Math.max(0, Math.min(abilityCount, maxDicePerType)),\n proficiencyDice: Math.max(0, Math.min(proficiencyCount, maxDicePerType)),\n setBackDice: Math.max(0, Math.min(setBackCount, maxDicePerType)),\n difficultyDice: Math.max(0, Math.min(difficultyCount, maxDicePerType)),\n challengeDice: Math.max(0, Math.min(challengeCount, maxDicePerType)),\n forceDice: Math.max(0, Math.min(forceCount, maxDicePerType)),\n };\n\n // Check if any dice counts exceeded the per-type limit\n const exceedsPerTypeLimit =\n boostCount > maxDicePerType ||\n abilityCount > maxDicePerType ||\n proficiencyCount > maxDicePerType ||\n setBackCount > maxDicePerType ||\n difficultyCount > maxDicePerType ||\n challengeCount > maxDicePerType ||\n forceCount > maxDicePerType;\n\n // Calculate total dice count\n const totalDice =\n sanitizedPool.boostDice +\n sanitizedPool.abilityDice +\n sanitizedPool.proficiencyDice +\n sanitizedPool.setBackDice +\n sanitizedPool.difficultyDice +\n sanitizedPool.challengeDice +\n sanitizedPool.forceDice;\n\n // Check total dice limit\n if (totalDice > maxTotalDice) {\n throw new Error(\n `Total dice count (${totalDice}) exceeds maximum allowed (${maxTotalDice}). ` +\n `Please reduce the number of dice in your pool.`,\n );\n }\n\n // Warn if per-type limits were exceeded (but continue with capped values)\n if (exceedsPerTypeLimit && options?.throwOnLimitExceeded) {\n const exceeded = [];\n if (boostCount > maxDicePerType) exceeded.push(`boost: ${boostCount}`);\n if (abilityCount > maxDicePerType)\n exceeded.push(`ability: ${abilityCount}`);\n if (proficiencyCount > maxDicePerType)\n exceeded.push(`proficiency: ${proficiencyCount}`);\n if (setBackCount > maxDicePerType)\n exceeded.push(`setback: ${setBackCount}`);\n if (difficultyCount > maxDicePerType)\n exceeded.push(`difficulty: ${difficultyCount}`);\n if (challengeCount > maxDicePerType)\n exceeded.push(`challenge: ${challengeCount}`);\n if (forceCount > maxDicePerType) exceeded.push(`force: ${forceCount}`);\n\n throw new Error(\n `Dice counts exceed per-type limit (${maxDicePerType}): ${exceeded.join(\", \")}. ` +\n `Dice counts have been capped to the maximum.`,\n );\n }\n\n const detailedResults: DetailedDieResult[] = [];\n\n // Roll boost dice\n for (let i = 0; i < sanitizedPool.boostDice; i++) {\n const roll = rollDie(6);\n detailedResults.push({\n type: \"boost\",\n roll,\n result: boostDieResult(roll),\n });\n }\n\n // Roll ability dice\n for (let i = 0; i < sanitizedPool.abilityDice; i++) {\n const roll = rollDie(8);\n detailedResults.push({\n type: \"ability\",\n roll,\n result: abilityDieResult(roll),\n });\n }\n\n // Roll proficiency dice\n for (let i = 0; i < sanitizedPool.proficiencyDice; i++) {\n const roll = rollDie(12);\n detailedResults.push({\n type: \"proficiency\",\n roll,\n result: proficiencyDieResult(roll),\n });\n }\n\n // Roll setback dice\n for (let i = 0; i < sanitizedPool.setBackDice; i++) {\n const roll = rollDie(6);\n detailedResults.push({\n type: \"setback\",\n roll,\n result: setBackDieResult(roll),\n });\n }\n\n // Roll difficulty dice\n for (let i = 0; i < sanitizedPool.difficultyDice; i++) {\n const roll = rollDie(8);\n detailedResults.push({\n type: \"difficulty\",\n roll,\n result: difficultyDieResult(roll),\n });\n }\n\n // Roll challenge dice\n for (let i = 0; i < sanitizedPool.challengeDice; i++) {\n const roll = rollDie(12);\n detailedResults.push({\n type: \"challenge\",\n roll,\n result: challengeDieResult(roll),\n });\n }\n\n // Roll force dice\n for (let i = 0; i < sanitizedPool.forceDice; i++) {\n const roll = rollDie(12);\n detailedResults.push({\n type: \"force\",\n roll,\n result: forceDieResult(roll),\n });\n }\n\n const summary = sumResults(detailedResults.map((r) => r.result));\n\n if (options?.hints) {\n const applicableHints = hints.filter((hint) => {\n const { cost } = hint;\n // For OR conditions: at least one option must be fully satisfied\n // Each entry in cost represents an alternative way to pay for the hint\n return Object.entries(cost).some(([symbol, required]) => {\n const summaryKey = (symbol.toLowerCase() + \"s\") as keyof typeof summary;\n const value = summary[summaryKey];\n if (typeof value !== \"number\") return false;\n // Check if we have enough of this symbol type to afford the hint\n return required !== undefined && required > 0 && value >= required;\n });\n });\n summary.hints = applicableHints.map(\n (hint) => `${hintCostDisplayText(hint)} - ${hint.description}`,\n );\n }\n\n return {\n results: detailedResults,\n summary: summary,\n };\n};\n","import { DicePool } from \"./types\";\n\n/**\n * Creates a basic skill check dice pool\n * @param ability Number of ability (green) dice\n * @param proficiency Number of proficiency (yellow) dice\n * @returns DicePool configured for a basic skill check\n */\nexport const createSkillCheck = (\n ability: number,\n proficiency: number,\n): DicePool => ({\n abilityDice: Math.max(0, ability),\n proficiencyDice: Math.max(0, proficiency),\n});\n\n/**\n * Creates a combat check dice pool with optional boost die\n * @param ability Number of ability (green) dice\n * @param proficiency Number of proficiency (yellow) dice\n * @param boost Number of boost (blue) dice\n * @returns DicePool configured for a combat check\n */\nexport const createCombatCheck = (\n ability: number,\n proficiency: number,\n boost: number = 0,\n): DicePool => ({\n abilityDice: Math.max(0, ability),\n proficiencyDice: Math.max(0, proficiency),\n boostDice: Math.max(0, boost),\n});\n\n/**\n * Creates an opposed check dice pool\n * @param ability Number of ability (green) dice\n * @param proficiency Number of proficiency (yellow) dice\n * @param difficulty Number of difficulty (purple) dice\n * @param challenge Number of challenge (red) dice\n * @returns DicePool configured for an opposed check\n */\nexport const createOpposedCheck = (\n ability: number,\n proficiency: number,\n difficulty: number,\n challenge: number = 0,\n): DicePool => ({\n abilityDice: Math.max(0, ability),\n proficiencyDice: Math.max(0, proficiency),\n difficultyDice: Math.max(0, difficulty),\n challengeDice: Math.max(0, challenge),\n});\n\n/**\n * Creates a difficulty check dice pool\n * @param difficulty Number of difficulty (purple) dice\n * @param challenge Number of challenge (red) dice\n * @returns DicePool configured for a pure difficulty check\n */\nexport const createDifficultyPool = (\n difficulty: number,\n challenge: number = 0,\n): DicePool => ({\n difficultyDice: Math.max(0, difficulty),\n challengeDice: Math.max(0, challenge),\n});\n"],"names":["SYMBOLS","hints","description","cost","SYMBOLS_ADVANTAGE","SYMBOLS_TRIUMPH","SYMBOLS_THREAT","SYMBOLS_DESPAIR","rollDie","sides","Math","floor","random","boostDieResult","roll","successes","failures","advantages","threats","triumphs","despair","lightSide","darkSide","setBackDieResult","abilityDieResult","difficultyDieResult","proficiencyDieResult","challengeDieResult","forceDieResult","pool","options","boostCount","_a","boostDice","abilityCount","_b","abilityDice","proficiencyCount","_c","proficiencyDice","setBackCount","_d","setBackDice","difficultyCount","_e","difficultyDice","challengeCount","_f","challengeDice","forceCount","_g","forceDice","maxDicePerType","_h","maxTotalDice","_j","sanitizedPool","max","min","exceedsPerTypeLimit","totalDice","Error","throwOnLimitExceeded","exceeded","push","join","detailedResults","i","type","result","summary","results","sums","reduce","acc","curr","netSuccesses","netFailures","sumResults","map","r","applicableHints","filter","hint","Object","entries","some","symbol","required","summaryKey","toLowerCase","value","undefined","keys","length","parts","_","count","charAt","toUpperCase","slice","hintCostDisplayText","createSkillCheck","ability","proficiency","createCombatCheck","boost","createOpposedCheck","difficulty","challenge","createDifficultyPool"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
!function(e,s){"object"==typeof exports&&"undefined"!=typeof module?s(exports):"function"==typeof define&&define.amd?define(["exports"],s):s((e="undefined"!=typeof globalThis?globalThis:e||self).SwrpgDice={})}(this,function(e){"use strict";const s="ADVANTAGE",t="THREAT",a="TRIUMPH",r="DESPAIR",i=[{description:"Recover one strain (may be applied more than once).",cost:{[s]:1,[a]:1}},{description:"Add a boost die to the next allied active character's check.",cost:{[s]:1,[a]:1}},{description:"Notice a single important point in the ongoing conflict, such as the location of a blast door's control panel or a weak point on an attack speeder.",cost:{[s]:1,[a]:1}},{description:"Inflict a Critical Injury with a successful attack that deals damage past soak (Advantage cost may vary).",cost:{[s]:1,[a]:1}},{description:"Activate a weapon quality (Advantage cost may vary).",cost:{[s]:1,[a]:1}},{description:"Perform an immediate free maneuver that does not exceed the two maneuver per turn limit.",cost:{[s]:2,[a]:1}},{description:"Add a setback die to the targeted character's next check.",cost:{[s]:2,[a]:1}},{description:"Add a boost die to any allied character's next check, including that of the active character.",cost:{[s]:2,[a]:1}},{description:"Negate the targeted enemy's defensive bonuses (such as the defense gained from cover, equipment, or performing the Guarded Stance maneuver) util the end of the current round.",cost:{[s]:3,[a]:1}},{description:"Ignore penalizing environmental effects such as inclement weather, zero gravity, or similar circumstances until the end of the active character's next turn.",cost:{[s]:3,[a]:1}},{description:"When dealing damage to a target, have the attack disable the opponent or one piece of gear rather than dealing wounds or strain. This could include hobbling them temporarily with a shot to the leg, or disabling their comlink. This should be agreed upon by the player and the GM, and the effects are up to the GM (although Table 6-10: Critical Injury Result is a god resource to consult for possible effects). The effects should be temporary and not too excessive.",cost:{[s]:3,[a]:1}},{description:"Gain + 1 melee or ranged defense until the end of the active character's next turn.",cost:{[s]:3,[a]:1}},{description:"Force the target to drop a melee or ranged weapon they are wielding.",cost:{[s]:3,[a]:1}},{description:"Upgrade the difficulty of the targeted character's next check.",cost:{[a]:1}},{description:"Do something vital, such as shooting the controls to the nearby blast doors to seal them shut.",cost:{[a]:1}},{description:"Upgrade any allied character's next check, including that of the current active character.",cost:{[a]:1}},{description:"When dealing damage to a target, have the attack destroy a piece of equipment the target is using, such as blowing up his blaster or destroying a personal shield generator.",cost:{[a]:2}},{description:"The active character suffers 1 strain.",cost:{[t]:1,[r]:1}},{description:"The active character loses the benefits of a prior maneuver (such as from taking cover or assuming a Guarded Stance) until they perform the maneuver again.",cost:{[t]:1,[r]:1}},{description:"An opponent may immediately perform one free maneuver in response to the active character's check.",cost:{[t]:2,[r]:1}},{description:"Add a boost die to the targeted character's next check.",cost:{[t]:1,[r]:1}},{description:"The active character or an allied character suffers a setback die on their next action.",cost:{[t]:2,[r]:1}},{description:"The active character falls prone.",cost:{[t]:3,[r]:1}},{description:"The active character grants the enemy a significant advantage in the ongoing encounter, such as accidentally blasting the controls to a bridge the active character was planning to use for their escape.",cost:{[t]:3,[r]:1}},{description:"The character's ranged weapon imediately runs out of ammunition and may not be used for the remainder of the encounter.",cost:{[r]:1}},{description:"Upgrade the difficulty of an allied character's next check, including that of the current active character.",cost:{[r]:1}},{description:"The tool or melee weapon the character is using becomes damaged.",cost:{[r]:1}}];const c=e=>Math.floor(Math.random()*e)+1,d=e=>{switch(e){case 3:return{successes:1,failures:0,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};case 4:return{successes:1,failures:0,advantages:1,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};case 5:return{successes:0,failures:0,advantages:2,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};case 6:return{successes:0,failures:0,advantages:1,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};default:return{successes:0,failures:0,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0}}},n=e=>{switch(e){case 3:case 4:return{successes:0,failures:1,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};case 5:case 6:return{successes:0,failures:0,advantages:0,threats:1,triumphs:0,despair:0,lightSide:0,darkSide:0};default:return{successes:0,failures:0,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0}}},h=e=>{switch(e){case 2:case 3:return{successes:1,failures:0,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};case 4:return{successes:2,failures:0,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};case 5:case 6:return{successes:0,failures:0,advantages:1,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};case 7:return{successes:1,failures:0,advantages:1,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};case 8:return{successes:0,failures:0,advantages:2,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};default:return{successes:0,failures:0,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0}}},o=e=>{switch(e){case 2:return{successes:0,failures:1,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};case 3:return{successes:0,failures:2,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};case 4:case 5:case 6:return{successes:0,failures:0,advantages:0,threats:1,triumphs:0,despair:0,lightSide:0,darkSide:0};case 7:return{successes:0,failures:0,advantages:0,threats:2,triumphs:0,despair:0,lightSide:0,darkSide:0};case 8:return{successes:0,failures:1,advantages:0,threats:1,triumphs:0,despair:0,lightSide:0,darkSide:0};default:return{successes:0,failures:0,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0}}},u=e=>{switch(e){case 2:case 3:return{successes:1,failures:0,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};case 4:case 5:return{successes:2,failures:0,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};case 6:return{successes:0,failures:0,advantages:1,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};case 7:case 8:case 9:return{successes:1,failures:0,advantages:1,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};case 10:case 11:return{successes:0,failures:0,advantages:2,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};case 12:return{successes:0,failures:0,advantages:0,threats:0,triumphs:1,despair:0,lightSide:0,darkSide:0};default:return{successes:0,failures:0,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0}}},l=e=>{switch(e){case 2:case 3:return{successes:0,failures:1,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};case 4:case 5:return{successes:0,failures:2,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};case 6:case 7:return{successes:0,failures:0,advantages:0,threats:1,triumphs:0,despair:0,lightSide:0,darkSide:0};case 8:case 9:return{successes:0,failures:1,advantages:0,threats:1,triumphs:0,despair:0,lightSide:0,darkSide:0};case 10:case 11:return{successes:0,failures:0,advantages:0,threats:2,triumphs:0,despair:0,lightSide:0,darkSide:0};case 12:return{successes:0,failures:0,advantages:0,threats:0,triumphs:0,despair:1,lightSide:0,darkSide:0};default:return{successes:0,failures:0,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0}}},p=e=>{switch(e){case 1:case 2:case 3:case 4:case 5:return{successes:0,failures:0,advantages:0,threats:0,triumphs:0,despair:0,lightSide:1,darkSide:0};case 6:case 7:return{successes:0,failures:0,advantages:0,threats:0,triumphs:0,despair:0,lightSide:2,darkSide:0};case 8:case 9:case 10:case 11:return{successes:0,failures:0,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:1};case 12:return{successes:0,failures:0,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:2};default:return{successes:0,failures:0,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0}}};e.createCombatCheck=(e,s,t=0)=>({abilityDice:Math.max(0,e),proficiencyDice:Math.max(0,s),boostDice:Math.max(0,t)}),e.createDifficultyPool=(e,s=0)=>({difficultyDice:Math.max(0,e),challengeDice:Math.max(0,s)}),e.createOpposedCheck=(e,s,t,a=0)=>({abilityDice:Math.max(0,e),proficiencyDice:Math.max(0,s),difficultyDice:Math.max(0,t),challengeDice:Math.max(0,a)}),e.createSkillCheck=(e,s)=>({abilityDice:Math.max(0,e),proficiencyDice:Math.max(0,s)}),e.roll=(e,s)=>{var t,a,r,g,f,m,v,S,k;const y=null!==(t=e.boostDice)&&void 0!==t?t:0,b=null!==(a=e.abilityDice)&&void 0!==a?a:0,x=null!==(r=e.proficiencyDice)&&void 0!==r?r:0,M=null!==(g=e.setBackDice)&&void 0!==g?g:0,w=null!==(f=e.difficultyDice)&&void 0!==f?f:0,D=null!==(m=e.challengeDice)&&void 0!==m?m:0,T=null!==(v=e.forceDice)&&void 0!==v?v:0,$=null!==(S=null==s?void 0:s.maxDicePerType)&&void 0!==S?S:100,A=null!==(k=null==s?void 0:s.maxTotalDice)&&void 0!==k?k:500,j=Math.max(0,Math.min(y,$)),C=Math.max(0,Math.min(b,$)),O=Math.max(0,Math.min(x,$)),P=Math.max(0,Math.min(M,$)),E=Math.max(0,Math.min(w,$)),G=Math.max(0,Math.min(D,$)),I=Math.max(0,Math.min(T,$)),R=y>$||b>$||x>$||M>$||w>$||D>$||T>$,N=j+C+O+P+E+G+I;if(N>A)throw new Error(`Total dice count (${N}) exceeds maximum allowed (${A}). Please reduce the number of dice in your pool.`);if(R&&(null==s?void 0:s.throwOnLimitExceeded)){const e=[];throw y>$&&e.push(`boost: ${y}`),b>$&&e.push(`ability: ${b}`),x>$&&e.push(`proficiency: ${x}`),M>$&&e.push(`setback: ${M}`),w>$&&e.push(`difficulty: ${w}`),D>$&&e.push(`challenge: ${D}`),T>$&&e.push(`force: ${T}`),new Error(`Dice counts exceed per-type limit (${$}): ${e.join(", ")}. Dice counts have been capped to the maximum.`)}const U=[];for(let e=0;e<j;e++){const e=c(6);U.push({type:"boost",roll:e,result:d(e)})}for(let e=0;e<C;e++){const e=c(8);U.push({type:"ability",roll:e,result:h(e)})}for(let e=0;e<O;e++){const e=c(12);U.push({type:"proficiency",roll:e,result:u(e)})}for(let e=0;e<P;e++){const e=c(6);U.push({type:"setback",roll:e,result:n(e)})}for(let e=0;e<E;e++){const e=c(8);U.push({type:"difficulty",roll:e,result:o(e)})}for(let e=0;e<G;e++){const e=c(12);U.push({type:"challenge",roll:e,result:l(e)})}for(let e=0;e<I;e++){const e=c(12);U.push({type:"force",roll:e,result:p(e)})}const q=(e=>{const s=e.reduce((e,s)=>({successes:e.successes+s.successes,failures:e.failures+s.failures,advantages:e.advantages+s.advantages,threats:e.threats+s.threats,triumphs:e.triumphs+s.triumphs,despair:e.despair+s.despair,lightSide:e.lightSide+(s.lightSide||0),darkSide:e.darkSide+(s.darkSide||0)}),{successes:0,failures:0,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0});let t=0,a=0;return s.successes===s.failures?(t=0,a=0):s.successes>s.failures?t=s.successes-s.failures:a=s.failures-s.successes,{successes:t,failures:a,advantages:s.advantages,threats:s.threats,triumphs:s.triumphs,despair:s.despair,lightSide:s.lightSide,darkSide:s.darkSide}})(U.map(e=>e.result));if(null==s?void 0:s.hints){const e=i.filter(e=>{const{cost:s}=e;return Object.entries(s).some(([e,s])=>{const t=e.toLowerCase()+"s",a=q[t];return"number"==typeof a&&(void 0!==s&&s>0&&a>=s)})});q.hints=e.map(e=>`${function(e){if(!e.cost||0===Object.keys(e.cost).length)return"No cost";const s=Object.entries(e.cost).filter(([e,s])=>s&&s>0).map(([e,s])=>`${s} ${e.charAt(0).toUpperCase()+e.toLowerCase().slice(1)}${s>1?"s":""}`);return s.length>1?s.join(" OR "):s.length>0?s[0]:"No cost"}(e)} - ${e.description}`)}return{results:U,summary:q}},Object.defineProperty(e,"__esModule",{value:!0})});
|
|
2
|
+
//# sourceMappingURL=bundle.umd.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bundle.umd.js","sources":["../src/types.ts","../src/hints.ts","../src/dice.ts","../src/pools.ts"],"sourcesContent":["export type DicePool = {\n boostDice?: number;\n abilityDice?: number;\n proficiencyDice?: number;\n setBackDice?: number;\n difficultyDice?: number;\n challengeDice?: number;\n forceDice?: number;\n};\n\nexport type DiceResult = {\n successes: number;\n failures: number;\n advantages: number;\n threats: number;\n triumphs: number;\n despair: number;\n lightSide: number;\n darkSide: number;\n hints?: string[];\n};\n\nexport type DieType =\n | \"boost\"\n | \"ability\"\n | \"proficiency\"\n | \"setback\"\n | \"difficulty\"\n | \"challenge\"\n | \"force\";\n\nexport type DetailedDieResult = {\n type: DieType;\n roll: number;\n result: DiceResult;\n};\n\nexport type RollResult = {\n results: DetailedDieResult[];\n summary: DiceResult;\n};\n\nexport const SYMBOLS = {\n SUCCESS: \"SUCCESS\" as const,\n FAILURE: \"FAILURE\" as const,\n ADVANTAGE: \"ADVANTAGE\" as const,\n THREAT: \"THREAT\" as const,\n TRIUMPH: \"TRIUMPH\" as const,\n DESPAIR: \"DESPAIR\" as const,\n LIGHT: \"LIGHT\" as const,\n DARK: \"DARK\" as const,\n} as const;\n\nexport type Symbol = keyof typeof SYMBOLS;\n\nexport type RollOptions = {\n hints?: boolean;\n /**\n * Maximum number of dice allowed per die type.\n * Default: 100\n */\n maxDicePerType?: number;\n /**\n * Maximum total number of dice allowed in a single roll.\n * Default: 500\n */\n maxTotalDice?: number;\n /**\n * Whether to throw an error when dice limits are exceeded.\n * If false, dice counts will be silently capped to the maximum.\n * Default: false\n */\n throwOnLimitExceeded?: boolean;\n};\n","import { SYMBOLS, type Symbol } from \"./types\";\n\n// 1 advantage or 1 triumph\nconst recoverOneStrain = \"Recover one strain (may be applied more than once).\";\nconst addBoostDieToActiveAlly =\n \"Add a boost die to the next allied active character's check.\";\nconst noticeImportantPoint =\n \"Notice a single important point in the ongoing conflict, such as the location of a blast door's control panel or a weak point on an attack speeder.\";\nconst inflictCriticalInjury =\n \"Inflict a Critical Injury with a successful attack that deals damage past soak (Advantage cost may vary).\";\nconst activateWeaponQuality =\n \"Activate a weapon quality (Advantage cost may vary).\";\n\n// 2 advantage or 1 triumph\nconst performManeuver =\n \"Perform an immediate free maneuver that does not exceed the two maneuver per turn limit.\";\nconst addSetbackDie =\n \"Add a setback die to the targeted character's next check.\";\nconst addBoostDieToAnyAlly =\n \"Add a boost die to any allied character's next check, including that of the active character.\";\n\n// 3 advantage or 1 triumph\nconst negateEnemy =\n \"Negate the targeted enemy's defensive bonuses (such as the defense gained from cover, equipment, or performing the Guarded Stance maneuver) util the end of the current round.\";\nconst ignoreEnvironment =\n \"Ignore penalizing environmental effects such as inclement weather, zero gravity, or similar circumstances until the end of the active character's next turn.\";\nconst disableOpponent =\n \"When dealing damage to a target, have the attack disable the opponent or one piece of gear rather than dealing wounds or strain. This could include hobbling them temporarily with a shot to the leg, or disabling their comlink. This should be agreed upon by the player and the GM, and the effects are up to the GM (although Table 6-10: Critical Injury Result is a god resource to consult for possible effects). The effects should be temporary and not too excessive.\";\nconst gainDefense =\n \"Gain + 1 melee or ranged defense until the end of the active character's next turn.\";\nconst dropWeapon =\n \"Force the target to drop a melee or ranged weapon they are wielding.\";\n\n// 1 triumph\nconst upgradeDifficultyTargetedCharacter =\n \"Upgrade the difficulty of the targeted character's next check.\";\nconst doSomethingVital =\n \"Do something vital, such as shooting the controls to the nearby blast doors to seal them shut.\";\nconst upgradeAnyAllyCheck =\n \"Upgrade any allied character's next check, including that of the current active character.\";\n\n// 2 triumph\nconst destroyEquipment =\n \"When dealing damage to a target, have the attack destroy a piece of equipment the target is using, such as blowing up his blaster or destroying a personal shield generator.\";\n\n// 1 threat or 1 despair\nconst sufferStrain = \"The active character suffers 1 strain.\";\nconst loseManeuverBenefit =\n \"The active character loses the benefits of a prior maneuver (such as from taking cover or assuming a Guarded Stance) until they perform the maneuver again.\";\n\n// 2 threat or 1 despair\nconst freeManeuver =\n \"An opponent may immediately perform one free maneuver in response to the active character's check.\";\nconst addBoostDieToTargetedCharacter =\n \"Add a boost die to the targeted character's next check.\";\nconst sufferSetback =\n \"The active character or an allied character suffers a setback die on their next action.\";\n\n// 3 threat or 1 despair\nconst fallProne = \"The active character falls prone.\";\nconst gainSignificantAdvantage =\n \"The active character grants the enemy a significant advantage in the ongoing encounter, such as accidentally blasting the controls to a bridge the active character was planning to use for their escape.\";\n\n// 1 despair\nconst outOfAmmo =\n \"The character's ranged weapon imediately runs out of ammunition and may not be used for the remainder of the encounter.\";\nconst upgradeDifficultyAlliedCharacter =\n \"Upgrade the difficulty of an allied character's next check, including that of the current active character.\";\nconst damagedItem =\n \"The tool or melee weapon the character is using becomes damaged.\";\n\nexport type CostType = {\n [key in Symbol]?: number;\n};\n\ntype Hint = {\n description: string;\n cost: CostType;\n};\n\nexport const hints: Hint[] = [\n // 1 advantage or 1 triumph\n {\n description: recoverOneStrain,\n cost: {\n [SYMBOLS.ADVANTAGE]: 1,\n [SYMBOLS.TRIUMPH]: 1,\n },\n },\n {\n description: addBoostDieToActiveAlly,\n cost: {\n [SYMBOLS.ADVANTAGE]: 1,\n [SYMBOLS.TRIUMPH]: 1,\n },\n },\n {\n description: noticeImportantPoint,\n cost: {\n [SYMBOLS.ADVANTAGE]: 1,\n [SYMBOLS.TRIUMPH]: 1,\n },\n },\n {\n description: inflictCriticalInjury,\n cost: {\n [SYMBOLS.ADVANTAGE]: 1,\n [SYMBOLS.TRIUMPH]: 1,\n },\n },\n {\n description: activateWeaponQuality,\n cost: {\n [SYMBOLS.ADVANTAGE]: 1,\n [SYMBOLS.TRIUMPH]: 1,\n },\n },\n // 2 advantage or 1 triumph\n {\n description: performManeuver,\n cost: {\n [SYMBOLS.ADVANTAGE]: 2,\n [SYMBOLS.TRIUMPH]: 1,\n },\n },\n {\n description: addSetbackDie,\n cost: {\n [SYMBOLS.ADVANTAGE]: 2,\n [SYMBOLS.TRIUMPH]: 1,\n },\n },\n {\n description: addBoostDieToAnyAlly,\n cost: {\n [SYMBOLS.ADVANTAGE]: 2,\n [SYMBOLS.TRIUMPH]: 1,\n },\n },\n // 3 advantage or 1 triumph\n {\n description: negateEnemy,\n cost: {\n [SYMBOLS.ADVANTAGE]: 3,\n [SYMBOLS.TRIUMPH]: 1,\n },\n },\n {\n description: ignoreEnvironment,\n cost: {\n [SYMBOLS.ADVANTAGE]: 3,\n [SYMBOLS.TRIUMPH]: 1,\n },\n },\n {\n description: disableOpponent,\n cost: {\n [SYMBOLS.ADVANTAGE]: 3,\n [SYMBOLS.TRIUMPH]: 1,\n },\n },\n {\n description: gainDefense,\n cost: {\n [SYMBOLS.ADVANTAGE]: 3,\n [SYMBOLS.TRIUMPH]: 1,\n },\n },\n {\n description: dropWeapon,\n cost: {\n [SYMBOLS.ADVANTAGE]: 3,\n [SYMBOLS.TRIUMPH]: 1,\n },\n },\n // 1 triumph\n {\n description: upgradeDifficultyTargetedCharacter,\n cost: {\n [SYMBOLS.TRIUMPH]: 1,\n },\n },\n {\n description: doSomethingVital,\n cost: {\n [SYMBOLS.TRIUMPH]: 1,\n },\n },\n {\n description: upgradeAnyAllyCheck,\n cost: {\n [SYMBOLS.TRIUMPH]: 1,\n },\n },\n // 2 triumph\n {\n description: destroyEquipment,\n cost: {\n [SYMBOLS.TRIUMPH]: 2,\n },\n },\n // 1 threat or 1 despair\n {\n description: sufferStrain,\n cost: {\n [SYMBOLS.THREAT]: 1,\n [SYMBOLS.DESPAIR]: 1,\n },\n },\n {\n description: loseManeuverBenefit,\n cost: {\n [SYMBOLS.THREAT]: 1,\n [SYMBOLS.DESPAIR]: 1,\n },\n },\n // 2 threat or 1 despair\n {\n description: freeManeuver,\n cost: {\n [SYMBOLS.THREAT]: 2,\n [SYMBOLS.DESPAIR]: 1,\n },\n },\n {\n description: addBoostDieToTargetedCharacter,\n cost: {\n [SYMBOLS.THREAT]: 1,\n [SYMBOLS.DESPAIR]: 1,\n },\n },\n {\n description: sufferSetback,\n cost: {\n [SYMBOLS.THREAT]: 2,\n [SYMBOLS.DESPAIR]: 1,\n },\n },\n // 3 threat or 1 despair\n {\n description: fallProne,\n cost: {\n [SYMBOLS.THREAT]: 3,\n [SYMBOLS.DESPAIR]: 1,\n },\n },\n {\n description: gainSignificantAdvantage,\n cost: {\n [SYMBOLS.THREAT]: 3,\n [SYMBOLS.DESPAIR]: 1,\n },\n },\n // 1 despair\n {\n description: outOfAmmo,\n cost: {\n [SYMBOLS.DESPAIR]: 1,\n },\n },\n {\n description: upgradeDifficultyAlliedCharacter,\n cost: {\n [SYMBOLS.DESPAIR]: 1,\n },\n },\n {\n description: damagedItem,\n cost: {\n [SYMBOLS.DESPAIR]: 1,\n },\n },\n];\n\nexport function hintCostDisplayText(hint: Hint): string {\n if (!hint.cost || Object.keys(hint.cost).length === 0) {\n return \"No cost\";\n }\n const parts = Object.entries(hint.cost)\n .filter(([_, count]) => count && count > 0)\n .map(([symbol, count]) => {\n const symbolName =\n symbol.charAt(0).toUpperCase() + symbol.toLowerCase().slice(1);\n const plural = count > 1 ? \"s\" : \"\";\n return `${count} ${symbolName}${plural}`;\n });\n\n // Use \"OR\" in uppercase for clarity when multiple options exist\n if (parts.length > 1) {\n return parts.join(\" OR \");\n }\n return parts.length > 0 ? parts[0] : \"No cost\";\n}\n","import { hintCostDisplayText, hints } from \"./hints\";\nimport {\n DicePool,\n RollResult,\n DiceResult,\n DetailedDieResult,\n RollOptions,\n} from \"./types\";\n\n// Default dice limits for performance and security\nexport const DEFAULT_MAX_DICE_PER_TYPE = 100;\nexport const DEFAULT_MAX_TOTAL_DICE = 500;\n\nconst rollDie = (sides: number): number =>\n Math.floor(Math.random() * sides) + 1;\n\nconst boostDieResult = (roll: number): DiceResult => {\n switch (roll) {\n case 3:\n return {\n successes: 1,\n failures: 0,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n case 4:\n return {\n successes: 1,\n failures: 0,\n advantages: 1,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n case 5:\n return {\n successes: 0,\n failures: 0,\n advantages: 2,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n case 6:\n return {\n successes: 0,\n failures: 0,\n advantages: 1,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n default:\n return {\n successes: 0,\n failures: 0,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n }\n};\n\nconst setBackDieResult = (roll: number): DiceResult => {\n switch (roll) {\n case 3:\n case 4:\n return {\n successes: 0,\n failures: 1,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n case 5:\n case 6:\n return {\n successes: 0,\n failures: 0,\n advantages: 0,\n threats: 1,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n default:\n return {\n successes: 0,\n failures: 0,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n }\n};\n\nconst abilityDieResult = (roll: number): DiceResult => {\n switch (roll) {\n case 2:\n case 3:\n return {\n successes: 1,\n failures: 0,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n case 4:\n return {\n successes: 2,\n failures: 0,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n case 5:\n case 6:\n return {\n successes: 0,\n failures: 0,\n advantages: 1,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n case 7:\n return {\n successes: 1,\n failures: 0,\n advantages: 1,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n case 8:\n return {\n successes: 0,\n failures: 0,\n advantages: 2,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n default:\n return {\n successes: 0,\n failures: 0,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n }\n};\n\nconst difficultyDieResult = (roll: number): DiceResult => {\n switch (roll) {\n case 2:\n return {\n successes: 0,\n failures: 1,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n case 3:\n return {\n successes: 0,\n failures: 2,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n case 4:\n case 5:\n case 6:\n return {\n successes: 0,\n failures: 0,\n advantages: 0,\n threats: 1,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n case 7:\n return {\n successes: 0,\n failures: 0,\n advantages: 0,\n threats: 2,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n case 8:\n return {\n successes: 0,\n failures: 1,\n advantages: 0,\n threats: 1,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n default:\n return {\n successes: 0,\n failures: 0,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n }\n};\n\nconst proficiencyDieResult = (roll: number): DiceResult => {\n switch (roll) {\n case 2:\n case 3:\n return {\n successes: 1,\n failures: 0,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n case 4:\n case 5:\n return {\n successes: 2,\n failures: 0,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n case 6:\n return {\n successes: 0,\n failures: 0,\n advantages: 1,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n case 7:\n case 8:\n case 9:\n return {\n successes: 1,\n failures: 0,\n advantages: 1,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n case 10:\n case 11:\n return {\n successes: 0,\n failures: 0,\n advantages: 2,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n case 12:\n return {\n successes: 0,\n failures: 0,\n advantages: 0,\n threats: 0,\n triumphs: 1,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n default:\n return {\n successes: 0,\n failures: 0,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n }\n};\n\nconst challengeDieResult = (roll: number): DiceResult => {\n switch (roll) {\n case 2:\n case 3:\n return {\n successes: 0,\n failures: 1,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n case 4:\n case 5:\n return {\n successes: 0,\n failures: 2,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n case 6:\n case 7:\n return {\n successes: 0,\n failures: 0,\n advantages: 0,\n threats: 1,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n case 8:\n case 9:\n return {\n successes: 0,\n failures: 1,\n advantages: 0,\n threats: 1,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n case 10:\n case 11:\n return {\n successes: 0,\n failures: 0,\n advantages: 0,\n threats: 2,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n case 12:\n return {\n successes: 0,\n failures: 0,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 1,\n lightSide: 0,\n darkSide: 0,\n };\n default:\n return {\n successes: 0,\n failures: 0,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n }\n};\n\nconst forceDieResult = (roll: number): DiceResult => {\n switch (roll) {\n case 1:\n case 2:\n case 3:\n case 4:\n case 5:\n return {\n successes: 0,\n failures: 0,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 1,\n darkSide: 0,\n };\n case 6:\n case 7:\n return {\n successes: 0,\n failures: 0,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 2,\n darkSide: 0,\n };\n case 8:\n case 9:\n case 10:\n case 11:\n return {\n successes: 0,\n failures: 0,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 1,\n };\n case 12:\n return {\n successes: 0,\n failures: 0,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 2,\n };\n default:\n return {\n successes: 0,\n failures: 0,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n }\n};\n\nconst sumResults = (\n results: DiceResult[],\n options?: RollOptions,\n): DiceResult => {\n const sums = results.reduce(\n (acc, curr) => ({\n successes: acc.successes + curr.successes,\n failures: acc.failures + curr.failures,\n advantages: acc.advantages + curr.advantages,\n threats: acc.threats + curr.threats,\n triumphs: acc.triumphs + curr.triumphs,\n despair: acc.despair + curr.despair,\n lightSide: acc.lightSide + (curr.lightSide || 0),\n darkSide: acc.darkSide + (curr.darkSide || 0),\n }),\n {\n successes: 0,\n failures: 0,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n },\n );\n\n let netSuccesses = 0;\n let netFailures = 0;\n\n if (sums.successes === sums.failures) {\n netSuccesses = 0;\n netFailures = 0;\n } else if (sums.successes > sums.failures) {\n netSuccesses = sums.successes - sums.failures;\n } else {\n netFailures = sums.failures - sums.successes;\n }\n\n const result: DiceResult = {\n successes: netSuccesses,\n failures: netFailures,\n advantages: sums.advantages,\n threats: sums.threats,\n triumphs: sums.triumphs,\n despair: sums.despair,\n lightSide: sums.lightSide,\n darkSide: sums.darkSide,\n };\n\n return result;\n};\n\n/**\n * Rolls a dice pool and returns the results.\n *\n * @param pool - The dice pool to roll\n * @param options - Optional roll configuration including dice limits\n * @returns The roll results with detailed die information and summary\n * @throws {Error} If dice counts exceed configured limits\n *\n * Default limits:\n * - Max dice per type: 100 (configurable via options.maxDicePerType)\n * - Max total dice: 500 (configurable via options.maxTotalDice)\n */\nexport const roll = (pool: DicePool, options?: RollOptions): RollResult => {\n const boostCount = pool.boostDice ?? 0;\n const abilityCount = pool.abilityDice ?? 0;\n const proficiencyCount = pool.proficiencyDice ?? 0;\n const setBackCount = pool.setBackDice ?? 0;\n const difficultyCount = pool.difficultyDice ?? 0;\n const challengeCount = pool.challengeDice ?? 0;\n const forceCount = pool.forceDice ?? 0;\n\n // Get limits from options or use defaults\n const maxDicePerType = options?.maxDicePerType ?? DEFAULT_MAX_DICE_PER_TYPE;\n const maxTotalDice = options?.maxTotalDice ?? DEFAULT_MAX_TOTAL_DICE;\n\n // Ensure all dice counts are non-negative and apply per-type limits\n const sanitizedPool = {\n boostDice: Math.max(0, Math.min(boostCount, maxDicePerType)),\n abilityDice: Math.max(0, Math.min(abilityCount, maxDicePerType)),\n proficiencyDice: Math.max(0, Math.min(proficiencyCount, maxDicePerType)),\n setBackDice: Math.max(0, Math.min(setBackCount, maxDicePerType)),\n difficultyDice: Math.max(0, Math.min(difficultyCount, maxDicePerType)),\n challengeDice: Math.max(0, Math.min(challengeCount, maxDicePerType)),\n forceDice: Math.max(0, Math.min(forceCount, maxDicePerType)),\n };\n\n // Check if any dice counts exceeded the per-type limit\n const exceedsPerTypeLimit =\n boostCount > maxDicePerType ||\n abilityCount > maxDicePerType ||\n proficiencyCount > maxDicePerType ||\n setBackCount > maxDicePerType ||\n difficultyCount > maxDicePerType ||\n challengeCount > maxDicePerType ||\n forceCount > maxDicePerType;\n\n // Calculate total dice count\n const totalDice =\n sanitizedPool.boostDice +\n sanitizedPool.abilityDice +\n sanitizedPool.proficiencyDice +\n sanitizedPool.setBackDice +\n sanitizedPool.difficultyDice +\n sanitizedPool.challengeDice +\n sanitizedPool.forceDice;\n\n // Check total dice limit\n if (totalDice > maxTotalDice) {\n throw new Error(\n `Total dice count (${totalDice}) exceeds maximum allowed (${maxTotalDice}). ` +\n `Please reduce the number of dice in your pool.`,\n );\n }\n\n // Warn if per-type limits were exceeded (but continue with capped values)\n if (exceedsPerTypeLimit && options?.throwOnLimitExceeded) {\n const exceeded = [];\n if (boostCount > maxDicePerType) exceeded.push(`boost: ${boostCount}`);\n if (abilityCount > maxDicePerType)\n exceeded.push(`ability: ${abilityCount}`);\n if (proficiencyCount > maxDicePerType)\n exceeded.push(`proficiency: ${proficiencyCount}`);\n if (setBackCount > maxDicePerType)\n exceeded.push(`setback: ${setBackCount}`);\n if (difficultyCount > maxDicePerType)\n exceeded.push(`difficulty: ${difficultyCount}`);\n if (challengeCount > maxDicePerType)\n exceeded.push(`challenge: ${challengeCount}`);\n if (forceCount > maxDicePerType) exceeded.push(`force: ${forceCount}`);\n\n throw new Error(\n `Dice counts exceed per-type limit (${maxDicePerType}): ${exceeded.join(\", \")}. ` +\n `Dice counts have been capped to the maximum.`,\n );\n }\n\n const detailedResults: DetailedDieResult[] = [];\n\n // Roll boost dice\n for (let i = 0; i < sanitizedPool.boostDice; i++) {\n const roll = rollDie(6);\n detailedResults.push({\n type: \"boost\",\n roll,\n result: boostDieResult(roll),\n });\n }\n\n // Roll ability dice\n for (let i = 0; i < sanitizedPool.abilityDice; i++) {\n const roll = rollDie(8);\n detailedResults.push({\n type: \"ability\",\n roll,\n result: abilityDieResult(roll),\n });\n }\n\n // Roll proficiency dice\n for (let i = 0; i < sanitizedPool.proficiencyDice; i++) {\n const roll = rollDie(12);\n detailedResults.push({\n type: \"proficiency\",\n roll,\n result: proficiencyDieResult(roll),\n });\n }\n\n // Roll setback dice\n for (let i = 0; i < sanitizedPool.setBackDice; i++) {\n const roll = rollDie(6);\n detailedResults.push({\n type: \"setback\",\n roll,\n result: setBackDieResult(roll),\n });\n }\n\n // Roll difficulty dice\n for (let i = 0; i < sanitizedPool.difficultyDice; i++) {\n const roll = rollDie(8);\n detailedResults.push({\n type: \"difficulty\",\n roll,\n result: difficultyDieResult(roll),\n });\n }\n\n // Roll challenge dice\n for (let i = 0; i < sanitizedPool.challengeDice; i++) {\n const roll = rollDie(12);\n detailedResults.push({\n type: \"challenge\",\n roll,\n result: challengeDieResult(roll),\n });\n }\n\n // Roll force dice\n for (let i = 0; i < sanitizedPool.forceDice; i++) {\n const roll = rollDie(12);\n detailedResults.push({\n type: \"force\",\n roll,\n result: forceDieResult(roll),\n });\n }\n\n const summary = sumResults(detailedResults.map((r) => r.result));\n\n if (options?.hints) {\n const applicableHints = hints.filter((hint) => {\n const { cost } = hint;\n // For OR conditions: at least one option must be fully satisfied\n // Each entry in cost represents an alternative way to pay for the hint\n return Object.entries(cost).some(([symbol, required]) => {\n const summaryKey = (symbol.toLowerCase() + \"s\") as keyof typeof summary;\n const value = summary[summaryKey];\n if (typeof value !== \"number\") return false;\n // Check if we have enough of this symbol type to afford the hint\n return required !== undefined && required > 0 && value >= required;\n });\n });\n summary.hints = applicableHints.map(\n (hint) => `${hintCostDisplayText(hint)} - ${hint.description}`,\n );\n }\n\n return {\n results: detailedResults,\n summary: summary,\n };\n};\n","import { DicePool } from \"./types\";\n\n/**\n * Creates a basic skill check dice pool\n * @param ability Number of ability (green) dice\n * @param proficiency Number of proficiency (yellow) dice\n * @returns DicePool configured for a basic skill check\n */\nexport const createSkillCheck = (\n ability: number,\n proficiency: number,\n): DicePool => ({\n abilityDice: Math.max(0, ability),\n proficiencyDice: Math.max(0, proficiency),\n});\n\n/**\n * Creates a combat check dice pool with optional boost die\n * @param ability Number of ability (green) dice\n * @param proficiency Number of proficiency (yellow) dice\n * @param boost Number of boost (blue) dice\n * @returns DicePool configured for a combat check\n */\nexport const createCombatCheck = (\n ability: number,\n proficiency: number,\n boost: number = 0,\n): DicePool => ({\n abilityDice: Math.max(0, ability),\n proficiencyDice: Math.max(0, proficiency),\n boostDice: Math.max(0, boost),\n});\n\n/**\n * Creates an opposed check dice pool\n * @param ability Number of ability (green) dice\n * @param proficiency Number of proficiency (yellow) dice\n * @param difficulty Number of difficulty (purple) dice\n * @param challenge Number of challenge (red) dice\n * @returns DicePool configured for an opposed check\n */\nexport const createOpposedCheck = (\n ability: number,\n proficiency: number,\n difficulty: number,\n challenge: number = 0,\n): DicePool => ({\n abilityDice: Math.max(0, ability),\n proficiencyDice: Math.max(0, proficiency),\n difficultyDice: Math.max(0, difficulty),\n challengeDice: Math.max(0, challenge),\n});\n\n/**\n * Creates a difficulty check dice pool\n * @param difficulty Number of difficulty (purple) dice\n * @param challenge Number of challenge (red) dice\n * @returns DicePool configured for a pure difficulty check\n */\nexport const createDifficultyPool = (\n difficulty: number,\n challenge: number = 0,\n): DicePool => ({\n difficultyDice: Math.max(0, difficulty),\n challengeDice: Math.max(0, challenge),\n});\n"],"names":["SYMBOLS","hints","description","cost","SYMBOLS_ADVANTAGE","SYMBOLS_TRIUMPH","SYMBOLS_THREAT","SYMBOLS_DESPAIR","rollDie","sides","Math","floor","random","boostDieResult","roll","successes","failures","advantages","threats","triumphs","despair","lightSide","darkSide","setBackDieResult","abilityDieResult","difficultyDieResult","proficiencyDieResult","challengeDieResult","forceDieResult","ability","proficiency","boost","abilityDice","max","proficiencyDice","boostDice","difficulty","challenge","difficultyDice","challengeDice","pool","options","boostCount","_a","abilityCount","_b","proficiencyCount","_c","setBackCount","_d","setBackDice","difficultyCount","_e","challengeCount","_f","forceCount","_g","forceDice","maxDicePerType","_h","maxTotalDice","_j","sanitizedPool","min","exceedsPerTypeLimit","totalDice","Error","throwOnLimitExceeded","exceeded","push","join","detailedResults","i","type","result","summary","results","sums","reduce","acc","curr","netSuccesses","netFailures","sumResults","map","r","applicableHints","filter","hint","Object","entries","some","symbol","required","summaryKey","toLowerCase","value","undefined","keys","length","parts","_","count","charAt","toUpperCase","slice","hintCostDisplayText"],"mappings":"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"}
|
package/dist/cli.d.ts
ADDED