@archivist-gg/dnd5e 0.3.17 → 0.3.24

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.
Files changed (439) hide show
  1. package/LICENSE +48 -21
  2. package/README.md +26 -48
  3. package/dist/armor/armor.codec.d.ts +0 -7
  4. package/dist/armor/armor.codec.js +1 -9
  5. package/dist/armor/armor.parser.js +1 -8
  6. package/dist/armor/armor.schema.js +1 -7
  7. package/dist/armor/armor.types.d.ts +0 -3
  8. package/dist/background/background.codec.d.ts +0 -6
  9. package/dist/background/background.codec.js +1 -12
  10. package/dist/background/background.parser.js +1 -11
  11. package/dist/background/background.schema.js +1 -12
  12. package/dist/background/background.types.d.ts +0 -5
  13. package/dist/chunk-2EOGK6R6.js +1 -0
  14. package/dist/chunk-2HRRH3WL.js +1 -0
  15. package/dist/chunk-2LCGKNVM.js +1 -0
  16. package/dist/chunk-2NUDWOFG.js +1 -0
  17. package/dist/chunk-334WLI7V.js +1 -0
  18. package/dist/chunk-3LWOVRLA.js +1 -0
  19. package/dist/chunk-3QQOATV3.js +1 -0
  20. package/dist/chunk-4E2GIWJE.js +1 -0
  21. package/dist/chunk-4GN3GYMP.js +1 -0
  22. package/dist/chunk-4IAMSRHD.js +1 -0
  23. package/dist/chunk-4JEF3CET.js +1 -0
  24. package/dist/chunk-4KVVAENP.js +1 -0
  25. package/dist/chunk-56JK6VCL.js +1 -0
  26. package/dist/chunk-5FEXHY4U.js +1 -0
  27. package/dist/chunk-63YJPWTM.js +1 -0
  28. package/dist/chunk-6ASJ3MVB.js +1 -0
  29. package/dist/chunk-6IC53O3Q.js +1 -0
  30. package/dist/chunk-6LCNV26D.js +1 -0
  31. package/dist/chunk-6W253VHH.js +1 -0
  32. package/dist/chunk-7AKJBRBD.js +1 -0
  33. package/dist/chunk-7EL3GWWJ.js +1 -0
  34. package/dist/chunk-7FPQJDFD.js +1 -0
  35. package/dist/chunk-7J5BNH2D.js +1 -0
  36. package/dist/chunk-7LPKI27J.js +1 -0
  37. package/dist/chunk-7UPYRKMF.js +1 -0
  38. package/dist/chunk-A7H6LX47.js +1 -0
  39. package/dist/chunk-AINRPPLH.js +1 -0
  40. package/dist/chunk-BC52J4LA.js +1 -0
  41. package/dist/chunk-BCXGB4HP.js +1 -0
  42. package/dist/chunk-BGX36NPE.js +1 -0
  43. package/dist/chunk-BPKG6RZ7.js +1 -0
  44. package/dist/chunk-BREHZNTL.js +1 -0
  45. package/dist/chunk-BZ6BGGZS.js +1 -0
  46. package/dist/chunk-CAPYNIGK.js +1 -0
  47. package/dist/chunk-CCFIINBA.js +1 -0
  48. package/dist/chunk-CMIEZQL4.js +1 -0
  49. package/dist/chunk-DVUXUIPV.js +1 -0
  50. package/dist/chunk-DY6FVAGA.js +1 -0
  51. package/dist/chunk-DZITM5AG.js +1 -0
  52. package/dist/chunk-DZKSXSJF.js +1 -0
  53. package/dist/chunk-EAARMPCW.js +1 -0
  54. package/dist/chunk-EVT7MGAC.js +1 -0
  55. package/dist/chunk-FOLHTMSC.js +1 -0
  56. package/dist/chunk-GCYUCIDN.js +1 -0
  57. package/dist/chunk-GIOV6JW7.js +1 -0
  58. package/dist/chunk-HCK6IUB3.js +1 -0
  59. package/dist/chunk-HR5MKCP2.js +1 -0
  60. package/dist/chunk-I26FHSI6.js +1 -0
  61. package/dist/chunk-I4O2FIDT.js +1 -0
  62. package/dist/chunk-IGVRLGLM.js +1 -0
  63. package/dist/chunk-IHPLT2ZT.js +1 -0
  64. package/dist/chunk-IOCJIWCV.js +1 -0
  65. package/dist/chunk-JXDX2DKF.js +1 -0
  66. package/dist/chunk-KBFSJ5WE.js +1 -0
  67. package/dist/chunk-KM75CC6Q.js +1 -0
  68. package/dist/chunk-KZDDFG4O.js +1 -0
  69. package/dist/chunk-LJNT3PJP.js +1 -0
  70. package/dist/chunk-LR6UMA5V.js +1 -0
  71. package/dist/chunk-M6RPOLKS.js +1 -0
  72. package/dist/chunk-MC6PLWRZ.js +1 -0
  73. package/dist/chunk-MGGKZGLG.js +1 -0
  74. package/dist/chunk-N3RYJ7RE.js +1 -0
  75. package/dist/chunk-NEMX7QGG.js +1 -0
  76. package/dist/chunk-NI364WV7.js +1 -0
  77. package/dist/chunk-O2QZ73GA.js +1 -0
  78. package/dist/chunk-O776WL7O.js +1 -0
  79. package/dist/chunk-OTFNINUY.js +1 -0
  80. package/dist/chunk-PQAVMK3T.js +1 -0
  81. package/dist/chunk-PZ3ZZ5H5.js +1 -0
  82. package/dist/chunk-PZ4L2EEG.js +1 -0
  83. package/dist/chunk-PZUPZBTN.js +1 -0
  84. package/dist/chunk-QBA757AU.js +1 -0
  85. package/dist/chunk-QFIGPOFW.js +1 -0
  86. package/dist/chunk-QMEKQTUT.js +1 -0
  87. package/dist/chunk-QVWT67WA.js +1 -0
  88. package/dist/chunk-RDXQAZBA.js +1 -0
  89. package/dist/chunk-RE5Z5RNK.js +1 -0
  90. package/dist/chunk-RL4VY2AL.js +1 -0
  91. package/dist/chunk-RQGTBHJW.js +1 -0
  92. package/dist/chunk-RQZCGXUZ.js +1 -0
  93. package/dist/chunk-S5UCI27C.js +1 -0
  94. package/dist/chunk-SEOASDO4.js +1 -0
  95. package/dist/chunk-SU4MEZ5P.js +1 -0
  96. package/dist/chunk-T55DELVL.js +1 -0
  97. package/dist/chunk-TKIEPC6F.js +1 -0
  98. package/dist/chunk-TLXFGGWH.js +1 -0
  99. package/dist/chunk-UBUKCRZ3.js +1 -0
  100. package/dist/chunk-V6NQ547U.js +1 -0
  101. package/dist/chunk-VA3ZWV7C.js +1 -0
  102. package/dist/chunk-VIP3FH2O.js +1 -0
  103. package/dist/chunk-VTQ4RWEG.js +1 -0
  104. package/dist/chunk-WUHTSLG4.js +1 -0
  105. package/dist/chunk-X22SISGM.js +1 -0
  106. package/dist/chunk-XKJXT2PN.js +1 -0
  107. package/dist/chunk-XQMKH4R4.js +1 -0
  108. package/dist/chunk-YGH7S5ZF.js +1 -0
  109. package/dist/chunk-ZE46ADXS.js +1 -0
  110. package/dist/chunk-ZI3FEUX3.js +1 -0
  111. package/dist/class/class.codec.d.ts +0 -7
  112. package/dist/class/class.codec.js +1 -18
  113. package/dist/class/class.parser.js +1 -17
  114. package/dist/class/class.schema.d.ts +2 -1
  115. package/dist/class/class.schema.js +1 -15
  116. package/dist/class/class.slug.d.ts +0 -11
  117. package/dist/class/class.slug.js +1 -8
  118. package/dist/class/class.standard-array.d.ts +0 -7
  119. package/dist/class/class.standard-array.js +1 -20
  120. package/dist/class/class.types.d.ts +0 -20
  121. package/dist/condition/condition.codec.d.ts +0 -6
  122. package/dist/condition/condition.parser.d.ts +0 -10
  123. package/dist/condition/condition.parser.js +1 -7
  124. package/dist/condition/condition.schema.d.ts +0 -16
  125. package/dist/condition/condition.types.d.ts +0 -3
  126. package/dist/data-srd/index.generated.js +1 -146
  127. package/dist/dnd/amount-text.d.ts +4 -27
  128. package/dist/dnd/amount-text.js +1 -13
  129. package/dist/dnd/constants.d.ts +0 -18
  130. package/dist/dnd/constants.js +1 -42
  131. package/dist/dnd/formula-tags.d.ts +0 -2
  132. package/dist/dnd/formula-tags.js +1 -119
  133. package/dist/dnd/math.d.ts +0 -26
  134. package/dist/dnd/math.js +1 -45
  135. package/dist/dnd/prose-tags.d.ts +1 -15
  136. package/dist/dnd/prose-tags.js +1 -18
  137. package/dist/dnd/resource-die.d.ts +0 -4
  138. package/dist/dnd/resource-die.js +1 -17
  139. package/dist/dnd/resource-formula.d.ts +0 -43
  140. package/dist/dnd/resource-formula.js +1 -14
  141. package/dist/dnd/resource-words.d.ts +0 -2
  142. package/dist/dnd/resource-words.js +1 -30
  143. package/dist/dnd/srd-tag-converter.d.ts +0 -21
  144. package/dist/dnd/srd-tag-converter.js +1 -12
  145. package/dist/dnd/tag-grammar.js +1 -12
  146. package/dist/dnd/warn-once.js +1 -8
  147. package/dist/encounter/encounter.ai-schema.js +1 -8
  148. package/dist/entities/base-item-resolver.d.ts +0 -26
  149. package/dist/entities/base-item-resolver.js +1 -11
  150. package/dist/entities/registry-revision.d.ts +10 -0
  151. package/dist/entities/registry-revision.js +1 -0
  152. package/dist/entities/slug.d.ts +1 -31
  153. package/dist/entities/slug.js +1 -12
  154. package/dist/entities/wikilink-display.d.ts +0 -2
  155. package/dist/entities/wikilink-display.js +1 -10
  156. package/dist/feat/feat.category-codes.d.ts +1 -26
  157. package/dist/feat/feat.category-codes.js +1 -14
  158. package/dist/feat/feat.codec.d.ts +0 -6
  159. package/dist/feat/feat.codec.js +1 -12
  160. package/dist/feat/feat.parser.js +1 -11
  161. package/dist/feat/feat.schema.d.ts +31 -1
  162. package/dist/feat/feat.schema.js +1 -10
  163. package/dist/feat/feat.types.d.ts +0 -6
  164. package/dist/index.js +45 -138113
  165. package/dist/inline-tag-parser.js +1 -6
  166. package/dist/item/item.actions-map.d.ts +4 -63
  167. package/dist/item/item.actions-map.js +1 -10
  168. package/dist/item/item.ai-schema.js +1 -6
  169. package/dist/item/item.attunement.d.ts +0 -14
  170. package/dist/item/item.attunement.js +1 -6
  171. package/dist/item/item.bonuses.js +1 -10
  172. package/dist/item/item.codec.js +1 -9
  173. package/dist/item/item.conditions.d.ts +0 -7
  174. package/dist/item/item.conditions.js +1 -11
  175. package/dist/item/item.conditions.types.d.ts +0 -2
  176. package/dist/item/item.cost.js +1 -29
  177. package/dist/item/item.enrichment.js +1 -9
  178. package/dist/item/item.icon.d.ts +0 -8
  179. package/dist/item/item.icon.js +1 -211
  180. package/dist/item/item.parser.js +1 -8
  181. package/dist/item/item.schema.d.ts +2 -0
  182. package/dist/item/item.schema.js +1 -11
  183. package/dist/item/item.types.d.ts +2 -28
  184. package/dist/monster/monster.ai-schema.js +1 -6
  185. package/dist/monster/monster.codec.d.ts +0 -10
  186. package/dist/monster/monster.enrichment.js +1 -19
  187. package/dist/monster/monster.format.d.ts +0 -69
  188. package/dist/monster/monster.format.js +1 -78
  189. package/dist/monster/monster.parser.d.ts +0 -4
  190. package/dist/monster/monster.parser.js +1 -15
  191. package/dist/monster/monster.resolve.d.ts +0 -4
  192. package/dist/monster/monster.schema.d.ts +0 -9
  193. package/dist/monster/monster.schema.js +1 -34
  194. package/dist/monster/monster.types.d.ts +0 -3
  195. package/dist/monster/monster.types.js +1 -1
  196. package/dist/optional-feature/optional-feature.codec.d.ts +0 -11
  197. package/dist/optional-feature/optional-feature.codec.js +1 -13
  198. package/dist/optional-feature/optional-feature.parser.js +1 -12
  199. package/dist/optional-feature/optional-feature.schema.d.ts +30 -1
  200. package/dist/optional-feature/optional-feature.schema.js +1 -15
  201. package/dist/pack.d.ts +0 -9
  202. package/dist/pc/conditions.constants.js +1 -6
  203. package/dist/pc/decision-recognizer.js +1 -8
  204. package/dist/pc/pc.additional-spells.d.ts +4 -14
  205. package/dist/pc/pc.additional-spells.js +1 -23
  206. package/dist/pc/pc.amount-bindings.d.ts +4 -20
  207. package/dist/pc/pc.amount-bindings.js +1 -23
  208. package/dist/pc/pc.asi-flatten.d.ts +0 -59
  209. package/dist/pc/pc.asi-flatten.js +1 -16
  210. package/dist/pc/pc.conditions.d.ts +1 -0
  211. package/dist/pc/pc.conditions.js +1 -6
  212. package/dist/pc/pc.containment.d.ts +0 -5
  213. package/dist/pc/pc.containment.js +1 -24
  214. package/dist/pc/pc.decision-engine.d.ts +4 -141
  215. package/dist/pc/pc.decision-engine.js +1 -52
  216. package/dist/pc/pc.defense-normalize.d.ts +0 -10
  217. package/dist/pc/pc.defense-normalize.js +1 -6
  218. package/dist/pc/pc.entry-overrides.d.ts +0 -58
  219. package/dist/pc/pc.entry-overrides.js +1 -40
  220. package/dist/pc/pc.equipment.d.ts +2 -22
  221. package/dist/pc/pc.equipment.js +1 -33
  222. package/dist/pc/pc.feature-effects.d.ts +23 -275
  223. package/dist/pc/pc.feature-effects.js +1 -26
  224. package/dist/pc/pc.formula-context.js +1 -11
  225. package/dist/pc/pc.infusions.d.ts +0 -65
  226. package/dist/pc/pc.infusions.js +1 -64
  227. package/dist/pc/pc.item-effects.d.ts +18 -0
  228. package/dist/pc/pc.member-choices.d.ts +18 -49
  229. package/dist/pc/pc.member-choices.js +1 -32
  230. package/dist/pc/pc.parser.js +1 -58
  231. package/dist/pc/pc.pools.d.ts +7 -10
  232. package/dist/pc/pc.pools.js +1 -26
  233. package/dist/pc/pc.proficiencies.d.ts +7 -33
  234. package/dist/pc/pc.proficiencies.js +1 -107
  235. package/dist/pc/pc.proficiency-grants.d.ts +0 -26
  236. package/dist/pc/pc.proficiency-normalize.d.ts +4 -25
  237. package/dist/pc/pc.proficiency-normalize.js +1 -12
  238. package/dist/pc/pc.proficiency-query.d.ts +0 -13
  239. package/dist/pc/pc.proficiency-query.js +1 -27
  240. package/dist/pc/pc.recalc.d.ts +7 -131
  241. package/dist/pc/pc.recalc.js +1 -946
  242. package/dist/pc/pc.resolver.d.ts +0 -104
  243. package/dist/pc/pc.resolver.js +1 -59
  244. package/dist/pc/pc.resource-seed.d.ts +0 -8
  245. package/dist/pc/pc.resource-seed.js +1 -42
  246. package/dist/pc/pc.resources.d.ts +1 -59
  247. package/dist/pc/pc.resources.js +1 -23
  248. package/dist/pc/pc.rest.d.ts +1 -20
  249. package/dist/pc/pc.rest.js +1 -230
  250. package/dist/pc/pc.schema.d.ts +19 -2
  251. package/dist/pc/pc.schema.js +1 -9
  252. package/dist/pc/pc.slotting.d.ts +0 -29
  253. package/dist/pc/pc.slotting.js +1 -28
  254. package/dist/pc/pc.speeds.d.ts +19 -0
  255. package/dist/pc/pc.spell-scope.d.ts +6 -0
  256. package/dist/pc/pc.spellcasting.d.ts +0 -70
  257. package/dist/pc/pc.spellcasting.js +1 -28
  258. package/dist/pc/pc.table-column.d.ts +0 -22
  259. package/dist/pc/pc.table-column.js +1 -18
  260. package/dist/pc/pc.tool-picks.d.ts +0 -27
  261. package/dist/pc/pc.tool-picks.js +1 -18
  262. package/dist/pc/pc.types.d.ts +85 -344
  263. package/dist/pc/pc.weapon-grant.d.ts +0 -6
  264. package/dist/pc/pool-layout.d.ts +0 -39
  265. package/dist/pc/pool-layout.js +1 -18
  266. package/dist/pc/resource-equivalents.d.ts +2 -40
  267. package/dist/pc/roll-scope.js +1 -8
  268. package/dist/pc/roll-tag-labels.d.ts +0 -32
  269. package/dist/pc/roll-tag-labels.js +1 -17
  270. package/dist/pc/spell-source.d.ts +0 -11
  271. package/dist/pc/spell-source.js +1 -8
  272. package/dist/race/race.codec.d.ts +0 -6
  273. package/dist/race/race.codec.js +1 -15
  274. package/dist/race/race.parser.js +1 -14
  275. package/dist/race/race.schema.d.ts +0 -8
  276. package/dist/race/race.schema.js +1 -14
  277. package/dist/race/race.structural.d.ts +0 -6
  278. package/dist/race/race.structural.js +1 -6
  279. package/dist/race/race.types.d.ts +0 -8
  280. package/dist/schemas/attack-schema.d.ts +5 -0
  281. package/dist/schemas/caster-type-schema.d.ts +1 -6
  282. package/dist/schemas/caster-type-schema.js +1 -6
  283. package/dist/schemas/choice-schema.js +1 -7
  284. package/dist/schemas/duration-schema.d.ts +0 -2
  285. package/dist/schemas/duration-schema.js +1 -6
  286. package/dist/schemas/entity-extras-schema.d.ts +0 -30
  287. package/dist/schemas/entity-extras-schema.js +1 -10
  288. package/dist/schemas/equipment-grant-schema.d.ts +0 -2
  289. package/dist/schemas/equipment-grant-schema.js +1 -12
  290. package/dist/schemas/feature-alias.d.ts +0 -27
  291. package/dist/schemas/feature-effect-schema.d.ts +30 -1
  292. package/dist/schemas/feature-effect-schema.js +1 -6
  293. package/dist/schemas/feature-schema.d.ts +0 -6
  294. package/dist/schemas/feature-schema.js +1 -12
  295. package/dist/schemas/resource-schema.d.ts +1 -34
  296. package/dist/schemas/resource-schema.js +1 -12
  297. package/dist/schemas/selection-pool-schema.js +1 -10
  298. package/dist/spell/casting-time.d.ts +0 -15
  299. package/dist/spell/casting-time.js +1 -6
  300. package/dist/spell/spell.access.d.ts +0 -6
  301. package/dist/spell/spell.access.js +1 -45
  302. package/dist/spell/spell.ai-schema.js +1 -6
  303. package/dist/spell/spell.codec.js +1 -9
  304. package/dist/spell/spell.enrichment.js +1 -9
  305. package/dist/spell/spell.filter.d.ts +0 -5
  306. package/dist/spell/spell.filter.js +1 -75
  307. package/dist/spell/spell.parser.d.ts +0 -31
  308. package/dist/spell/spell.parser.js +1 -16
  309. package/dist/spell/spell.scaling.d.ts +0 -46
  310. package/dist/spell/spell.scaling.js +1 -79
  311. package/dist/spell/spell.schema.js +1 -7
  312. package/dist/spell/spell.types.d.ts +0 -7
  313. package/dist/srd/retired-items.d.ts +0 -4
  314. package/dist/srd/retired-items.js +1 -11
  315. package/dist/srd-store.d.ts +0 -33
  316. package/dist/subclass/subclass.codec.d.ts +0 -8
  317. package/dist/subclass/subclass.codec.js +1 -17
  318. package/dist/subclass/subclass.parser.js +1 -16
  319. package/dist/subclass/subclass.schema.d.ts +2 -1
  320. package/dist/subclass/subclass.schema.js +1 -14
  321. package/dist/subclass/subclass.types.d.ts +0 -3
  322. package/dist/types/attack.d.ts +2 -0
  323. package/dist/types/casting-option.d.ts +0 -4
  324. package/dist/types/choice.d.ts +1 -72
  325. package/dist/types/choice.js +1 -24
  326. package/dist/types/edition.d.ts +0 -3
  327. package/dist/types/equipment-grant.d.ts +1 -27
  328. package/dist/types/equipment-grant.js +1 -12
  329. package/dist/types/feature-effect.d.ts +14 -14
  330. package/dist/types/feature.d.ts +0 -22
  331. package/dist/types/optional-feature.types.d.ts +1 -31
  332. package/dist/types/resource.d.ts +1 -21
  333. package/dist/types/selection-pool.d.ts +0 -24
  334. package/dist/weapon/weapon-mastery.d.ts +0 -1
  335. package/dist/weapon/weapon.classify.d.ts +0 -11
  336. package/dist/weapon/weapon.classify.js +1 -7
  337. package/dist/weapon/weapon.codec.d.ts +0 -9
  338. package/dist/weapon/weapon.codec.js +1 -9
  339. package/dist/weapon/weapon.parser.js +1 -8
  340. package/dist/weapon/weapon.schema.js +1 -7
  341. package/dist/weapon/weapon.types.d.ts +0 -3
  342. package/package.json +3 -3
  343. package/src/data-srd/ATTRIBUTION.md +1 -1
  344. package/dist/chunk-2FRUSVZS.js +0 -489
  345. package/dist/chunk-2JSQE3DD.js +0 -206
  346. package/dist/chunk-2LULMQTF.js +0 -14
  347. package/dist/chunk-2UDSN6VW.js +0 -18
  348. package/dist/chunk-3LWMFYKS.js +0 -57
  349. package/dist/chunk-3MGQFFNE.js +0 -110
  350. package/dist/chunk-3TM34RSJ.js +0 -23
  351. package/dist/chunk-3VZZDKRA.js +0 -1014
  352. package/dist/chunk-4U55VNC7.js +0 -22
  353. package/dist/chunk-5GKJAUMX.js +0 -59
  354. package/dist/chunk-5MXFW4O3.js +0 -71
  355. package/dist/chunk-656QCX4U.js +0 -22
  356. package/dist/chunk-6EI737IO.js +0 -19
  357. package/dist/chunk-6GNXYAYP.js +0 -25
  358. package/dist/chunk-6PXTNCBP.js +0 -133
  359. package/dist/chunk-6X2NV665.js +0 -33
  360. package/dist/chunk-7ATNGKBS.js +0 -178
  361. package/dist/chunk-7Q2VPKCD.js +0 -181
  362. package/dist/chunk-7QN7XSAK.js +0 -19
  363. package/dist/chunk-A54HHCWW.js +0 -67
  364. package/dist/chunk-AZRGFUSR.js +0 -18
  365. package/dist/chunk-B3DP42OM.js +0 -55
  366. package/dist/chunk-CJYCVNW2.js +0 -7
  367. package/dist/chunk-CM5CWO4K.js +0 -735
  368. package/dist/chunk-DEEHHLAP.js +0 -271
  369. package/dist/chunk-DOXSFYLH.js +0 -158
  370. package/dist/chunk-DPUJDOKV.js +0 -365
  371. package/dist/chunk-EJP263OP.js +0 -186
  372. package/dist/chunk-EVMUJYUD.js +0 -195
  373. package/dist/chunk-EYX4JMAU.js +0 -101
  374. package/dist/chunk-FANQVQ3D.js +0 -89
  375. package/dist/chunk-FC4IGH5Y.js +0 -18
  376. package/dist/chunk-G6MHJDVT.js +0 -41
  377. package/dist/chunk-G6PBI2BU.js +0 -18
  378. package/dist/chunk-H5PTKYXL.js +0 -101
  379. package/dist/chunk-HHBD4SQ6.js +0 -24
  380. package/dist/chunk-HS6FIOLP.js +0 -52
  381. package/dist/chunk-HTYMW5CH.js +0 -228
  382. package/dist/chunk-IHE6KVC3.js +0 -13
  383. package/dist/chunk-IN4M4X7P.js +0 -34
  384. package/dist/chunk-IUAAXXNO.js +0 -58
  385. package/dist/chunk-JCMUVZIK.js +0 -133
  386. package/dist/chunk-JSM6JFZR.js +0 -709
  387. package/dist/chunk-K5NJBTE2.js +0 -18
  388. package/dist/chunk-KR6JF3BF.js +0 -14
  389. package/dist/chunk-KSTV7J2U.js +0 -112
  390. package/dist/chunk-KU3YLF6D.js +0 -106
  391. package/dist/chunk-LBEXLN6I.js +0 -91
  392. package/dist/chunk-LF5AGJA4.js +0 -81
  393. package/dist/chunk-LHZXYFBU.js +0 -94
  394. package/dist/chunk-LSLSG67V.js +0 -31
  395. package/dist/chunk-LVQLWRCU.js +0 -15
  396. package/dist/chunk-MBX25B6D.js +0 -18
  397. package/dist/chunk-MYY2C5MB.js +0 -233
  398. package/dist/chunk-OFCSP6MT.js +0 -23
  399. package/dist/chunk-ONTGZR5T.js +0 -1806
  400. package/dist/chunk-OOSRUJBI.js +0 -19
  401. package/dist/chunk-PDJSUH24.js +0 -110
  402. package/dist/chunk-PKX6TGRE.js +0 -93
  403. package/dist/chunk-PQZ4LM4Z.js +0 -19
  404. package/dist/chunk-PTXBIDG7.js +0 -63
  405. package/dist/chunk-PVCEA4HZ.js +0 -6
  406. package/dist/chunk-PXVNAY7T.js +0 -84
  407. package/dist/chunk-QH36K2PU.js +0 -158
  408. package/dist/chunk-QS5L5YTJ.js +0 -24
  409. package/dist/chunk-QYZV2MQA.js +0 -97
  410. package/dist/chunk-QZSWN2KT.js +0 -18
  411. package/dist/chunk-RLGQ5PZZ.js +0 -16
  412. package/dist/chunk-RYLXAYIQ.js +0 -18
  413. package/dist/chunk-S3YUXDSC.js +0 -278
  414. package/dist/chunk-S7REMWW4.js +0 -21
  415. package/dist/chunk-T6QIF5XR.js +0 -348
  416. package/dist/chunk-TOM66P2P.js +0 -38
  417. package/dist/chunk-TULQ4FFX.js +0 -353
  418. package/dist/chunk-UA5KS2PL.js +0 -26
  419. package/dist/chunk-UUBJCNQU.js +0 -187
  420. package/dist/chunk-UZXG6QSY.js +0 -58
  421. package/dist/chunk-VPYBK2MG.js +0 -18
  422. package/dist/chunk-VRV3NNTA.js +0 -161
  423. package/dist/chunk-VTTA2ALZ.js +0 -16
  424. package/dist/chunk-W6GC6OKK.js +0 -16
  425. package/dist/chunk-WELIKLZF.js +0 -256
  426. package/dist/chunk-WSVMLNTO.js +0 -31
  427. package/dist/chunk-WYGD2UGN.js +0 -14
  428. package/dist/chunk-XCFC7LGF.js +0 -122
  429. package/dist/chunk-XJ2F2WO6.js +0 -8
  430. package/dist/chunk-Y5VVP73C.js +0 -23
  431. package/dist/chunk-YBLDE5CG.js +0 -42
  432. package/dist/chunk-YD2VAHA6.js +0 -159
  433. package/dist/chunk-YDGMBMYI.js +0 -25
  434. package/dist/chunk-YHYTW5QA.js +0 -20
  435. package/dist/chunk-YKL6SHRJ.js +0 -23
  436. package/dist/chunk-ZCTUYGNV.js +0 -26
  437. package/dist/chunk-ZDAEGJH4.js +0 -102
  438. package/dist/chunk-ZJXSXVFP.js +0 -58
  439. package/dist/chunk-ZUQW5VBZ.js +0 -89
@@ -1,946 +1 @@
1
- import {
2
- amountBindingsFor
3
- } from "../chunk-PXVNAY7T.js";
4
- import "../chunk-KR6JF3BF.js";
5
- import {
6
- computeConditionEffects
7
- } from "../chunk-MYY2C5MB.js";
8
- import {
9
- collectChosenAbilityPoints,
10
- collectChosenProficiencies
11
- } from "../chunk-ONTGZR5T.js";
12
- import "../chunk-2LULMQTF.js";
13
- import "../chunk-H5PTKYXL.js";
14
- import {
15
- assembleEffectFeatures,
16
- computeFeatureEffects,
17
- foldsNow,
18
- selfEffectsOf
19
- } from "../chunk-TULQ4FFX.js";
20
- import "../chunk-TOM66P2P.js";
21
- import "../chunk-KU3YLF6D.js";
22
- import {
23
- featPickSites,
24
- poolMemberSitesOf
25
- } from "../chunk-HTYMW5CH.js";
26
- import {
27
- resourceLevelFor
28
- } from "../chunk-KSTV7J2U.js";
29
- import {
30
- computeSpellLimits,
31
- deriveSpellSlots,
32
- effectiveSpellcastingAbility,
33
- resolveSpellcasting
34
- } from "../chunk-DPUJDOKV.js";
35
- import {
36
- legacyAsiBranch
37
- } from "../chunk-LBEXLN6I.js";
38
- import {
39
- toDefenseSlug
40
- } from "../chunk-XJ2F2WO6.js";
41
- import {
42
- buildUnarmedRow,
43
- computeAppliedBonuses,
44
- computeSlotsAndAttacks,
45
- emptyAppliedBonuses
46
- } from "../chunk-JSM6JFZR.js";
47
- import "../chunk-3LWMFYKS.js";
48
- import "../chunk-YDGMBMYI.js";
49
- import "../chunk-EJP263OP.js";
50
- import "../chunk-RLGQ5PZZ.js";
51
- import "../chunk-3VZZDKRA.js";
52
- import "../chunk-W6GC6OKK.js";
53
- import "../chunk-B3DP42OM.js";
54
- import {
55
- diceColumnAt,
56
- unarmedDieColumnFor
57
- } from "../chunk-IUAAXXNO.js";
58
- import "../chunk-YHYTW5QA.js";
59
- import "../chunk-VRV3NNTA.js";
60
- import "../chunk-PVCEA4HZ.js";
61
- import "../chunk-IHE6KVC3.js";
62
- import "../chunk-HHBD4SQ6.js";
63
- import "../chunk-A54HHCWW.js";
64
- import "../chunk-LHZXYFBU.js";
65
- import "../chunk-YBLDE5CG.js";
66
- import "../chunk-ZUQW5VBZ.js";
67
- import "../chunk-LVQLWRCU.js";
68
- import "../chunk-CM5CWO4K.js";
69
- import {
70
- resolveAmountText
71
- } from "../chunk-QH36K2PU.js";
72
- import "../chunk-EVMUJYUD.js";
73
- import "../chunk-VTTA2ALZ.js";
74
- import "../chunk-ZCTUYGNV.js";
75
- import "../chunk-7Q2VPKCD.js";
76
- import "../chunk-ZDAEGJH4.js";
77
- import "../chunk-3TM34RSJ.js";
78
- import {
79
- abilityModifier,
80
- attackBonus,
81
- isCanonicalDamageType,
82
- isChosenDamageType,
83
- proficiencyFromLevel,
84
- saveDC,
85
- savingThrow,
86
- skillBonus
87
- } from "../chunk-PDJSUH24.js";
88
- import {
89
- ABILITY_KEYS,
90
- ALL_SKILLS,
91
- SKILL_ABILITY
92
- } from "../chunk-WELIKLZF.js";
93
- import "../chunk-4U55VNC7.js";
94
- import "../chunk-UA5KS2PL.js";
95
-
96
- // src/pc/pc.recalc.ts
97
- var WEAPON_CATEGORY_WORDS = /* @__PURE__ */ new Set([
98
- "simple",
99
- "martial",
100
- "simple-melee",
101
- "simple-ranged",
102
- "martial-melee",
103
- "martial-ranged",
104
- "natural"
105
- ]);
106
- function phbAverageForDie(hitDieStr) {
107
- const n = parseDieSize(hitDieStr);
108
- if (n == null) return 4;
109
- return Math.floor(n / 2) + 1;
110
- }
111
- function parseDieSize(die) {
112
- if (die == null) return null;
113
- if (typeof die === "number") return die;
114
- const m = die.match(/^d?(\d+)$/i);
115
- return m ? parseInt(m[1], 10) : null;
116
- }
117
- function skillSlugFromDisplay(display) {
118
- return display.toLowerCase().replace(/\s+/g, "-");
119
- }
120
- function skillSlugToAbilityLookup(slug) {
121
- return slug.replace(/-/g, " ");
122
- }
123
- function flattenRaceAsi(race) {
124
- var _a;
125
- const out = {};
126
- if (!(race == null ? void 0 : race.ability_score_increases)) return out;
127
- for (const asi of race.ability_score_increases) {
128
- if ("ability" in asi) {
129
- out[asi.ability] = ((_a = out[asi.ability]) != null ? _a : 0) + asi.amount;
130
- }
131
- }
132
- return out;
133
- }
134
- function subraceAsi(resolved) {
135
- var _a, _b, _c, _d, _e;
136
- const subSlug = (_b = (_a = resolved.definition.subrace) == null ? void 0 : _a.replace(/\[\[|\]\]/g, "")) != null ? _b : null;
137
- if (!subSlug) return [];
138
- const subraces = (_d = (_c = resolved.race) == null ? void 0 : _c.subraces) != null ? _d : [];
139
- const sub = subraces.find((s) => s.slug === subSlug);
140
- return (_e = sub == null ? void 0 : sub.ability_score_increases) != null ? _e : [];
141
- }
142
- function collectClassAsiBranch(resolved) {
143
- var _a;
144
- const out = {};
145
- for (const c of resolved.classes) {
146
- for (const choice of Object.values(c.choices)) {
147
- const alloc = legacyAsiBranch(choice);
148
- if (!alloc) continue;
149
- for (const ab of ABILITY_KEYS) {
150
- const v = alloc[ab];
151
- if (typeof v === "number") out[ab] = ((_a = out[ab]) != null ? _a : 0) + v;
152
- }
153
- }
154
- }
155
- return out;
156
- }
157
- function abilityBonusBreakdown(resolved, featureEffects) {
158
- var _a, _b, _c, _d, _e, _f, _g;
159
- const race = flattenRaceAsi(resolved.race);
160
- const origin = collectChosenAbilityPoints(resolved);
161
- const sub = subraceAsi(resolved);
162
- const classAsi = collectClassAsiBranch(resolved);
163
- const featPoints = collectClassFeatAbilityPoints(resolved);
164
- const out = {};
165
- for (const ab of ABILITY_KEYS) {
166
- let species = ((_a = race[ab]) != null ? _a : 0) + ((_b = origin.race[ab]) != null ? _b : 0);
167
- for (const asi of sub) {
168
- if (asi.ability === ab && typeof asi.amount === "number") species += asi.amount;
169
- }
170
- let feat = (_c = featPoints[ab]) != null ? _c : 0;
171
- for (const f of resolved.feats) {
172
- const bonus = (_d = f.ability_bonuses) == null ? void 0 : _d[ab];
173
- if (typeof bonus === "number") feat += bonus;
174
- }
175
- out[ab] = { species, background: (_e = origin.background[ab]) != null ? _e : 0, class: ((_f = classAsi[ab]) != null ? _f : 0) + ((_g = featureEffects == null ? void 0 : featureEffects.ability_bonus[ab]) != null ? _g : 0), feat };
176
- }
177
- return out;
178
- }
179
- function hitDiceAverageSum(classes) {
180
- var _a;
181
- let total = 0;
182
- let firstLevelCounted = false;
183
- for (const c of classes) {
184
- const die = parseDieSize((_a = c.entity) == null ? void 0 : _a.hit_die);
185
- if (!c.entity || die == null || c.level < 1) continue;
186
- for (let lvl = 1; lvl <= c.level; lvl++) {
187
- if (!firstLevelCounted) {
188
- total += die;
189
- firstLevelCounted = true;
190
- } else {
191
- total += Math.floor(die / 2) + 1;
192
- }
193
- }
194
- }
195
- return total;
196
- }
197
- function hpLevelCount(classes) {
198
- var _a;
199
- let count = 0;
200
- for (const c of classes) {
201
- const die = parseDieSize((_a = c.entity) == null ? void 0 : _a.hit_die);
202
- if (!c.entity || die == null || c.level < 1) continue;
203
- count += c.level;
204
- }
205
- return count;
206
- }
207
- function multiclassMaxHP(classes, conMod) {
208
- return Math.max(1, hitDiceAverageSum(classes) + conMod * hpLevelCount(classes));
209
- }
210
- function resolveDamageRider(rider, rowDamageType, bindings) {
211
- const { owner, ...rest } = rider;
212
- const out = { ...rest, amount: resolveAmountText(rider.amount, bindings(owner)) };
213
- if (rider.damage_type !== void 0 && !isChosenDamageType(rider.damage_type)) {
214
- const resolved = isCanonicalDamageType(rider.damage_type) ? rider.damage_type : rowDamageType;
215
- if (resolved) out.damage_type = resolved;
216
- else delete out.damage_type;
217
- }
218
- return out;
219
- }
220
- function riderReachesRow(rider, row) {
221
- var _a;
222
- if (!((_a = rider.scope) == null ? void 0 : _a.length)) return true;
223
- return rider.scope.some((word) => {
224
- switch (word) {
225
- case "weapon":
226
- return true;
227
- case "unarmed":
228
- return row.unarmed === true;
229
- case "melee":
230
- case "ranged":
231
- return row.weaponCategory === word;
232
- case "finesse":
233
- case "thrown":
234
- return row.properties.includes(word);
235
- }
236
- });
237
- }
238
- function unarmoredAC(resolved, mods, warnings) {
239
- return unarmoredACBreakdown(resolved, mods, warnings).total;
240
- }
241
- function unarmoredACBreakdown(resolved, mods, warnings, shieldBonus = 0) {
242
- var _a, _b, _c, _d, _e;
243
- const baseTerms = [
244
- { source: "Unarmored", amount: 10, kind: "unarmored" },
245
- { source: "DEX modifier", amount: mods.dex, kind: "dex" }
246
- ];
247
- const { activeBuffs } = assembleEffectFeatures(resolved);
248
- const candidates = [
249
- { total: 10 + mods.dex, terms: baseTerms, shieldAllowed: true }
250
- ];
251
- for (const rf of resolved.features) {
252
- if (!foldsNow(rf, activeBuffs)) continue;
253
- for (const eff of selfEffectsOf(rf.feature)) {
254
- if (eff.kind !== "unarmored-ac") continue;
255
- const base = (_a = eff.base) != null ? _a : 10;
256
- const terms = [{ source: "Unarmored", amount: base, kind: "unarmored" }];
257
- let total = base;
258
- for (const ab of eff.abilities) {
259
- terms.push(ab === "dex" ? { source: "DEX modifier", amount: mods.dex, kind: "dex" } : { source: `${ab.toUpperCase()} modifier (${(_b = rf.feature.name) != null ? _b : "Unarmored"})`, amount: mods[ab], kind: "ability" });
260
- total += mods[ab];
261
- }
262
- candidates.push({ total, terms, shieldAllowed: eff.allow_shield === true });
263
- }
264
- }
265
- if (candidates.length > 1) {
266
- const applied = (c) => c.total + (c.shieldAllowed ? shieldBonus : 0);
267
- let best = candidates[0];
268
- for (const c of candidates) if (applied(c) > applied(best)) best = c;
269
- return best;
270
- }
271
- for (const rf of resolved.features) {
272
- const feat = rf.feature;
273
- if ((_c = feat.unarmored_defense) == null ? void 0 : _c.ability) {
274
- const ab = feat.unarmored_defense.ability;
275
- const amt = (_d = mods[ab]) != null ? _d : 0;
276
- const terms = [
277
- ...baseTerms,
278
- { source: `${ab.toUpperCase()} modifier (Unarmored Defense)`, amount: amt, kind: "ability" }
279
- ];
280
- return { total: 10 + mods.dex + amt, terms, shieldAllowed: true };
281
- }
282
- }
283
- for (const rf of resolved.features) {
284
- const name = ((_e = rf.feature.name) != null ? _e : "").toLowerCase();
285
- if (!/unarmored\s*defense/.test(name)) continue;
286
- if (rf.source.kind === "class" && rf.source.slug.includes("monk")) {
287
- const terms = [
288
- ...baseTerms,
289
- { source: "WIS modifier (Unarmored Defense)", amount: mods.wis, kind: "ability" }
290
- ];
291
- return { total: 10 + mods.dex + mods.wis, terms, shieldAllowed: true };
292
- }
293
- if (rf.source.kind === "class" && rf.source.slug.includes("barbarian")) {
294
- const terms = [
295
- ...baseTerms,
296
- { source: "CON modifier (Unarmored Defense)", amount: mods.con, kind: "ability" }
297
- ];
298
- return { total: 10 + mods.dex + mods.con, terms, shieldAllowed: true };
299
- }
300
- }
301
- return { total: 10 + mods.dex, terms: baseTerms, shieldAllowed: true };
302
- }
303
- function resolveUnarmedStrike(resolved) {
304
- var _a, _b, _c;
305
- const dice = [];
306
- const abilities = /* @__PURE__ */ new Set();
307
- const classOf = (rf) => rf.source.kind === "class" ? resolved.classes.find((c) => {
308
- var _a2;
309
- return ((_a2 = c.entity) == null ? void 0 : _a2.slug) === rf.source.slug;
310
- }) : void 0;
311
- const readDie = (rf, d) => {
312
- var _a2, _b2;
313
- if (typeof d === "string") return d;
314
- if (!d) return void 0;
315
- const cls = classOf(rf);
316
- return cls ? (_b2 = diceColumnAt((_a2 = cls.entity) == null ? void 0 : _a2.table, cls.level, d.column)) != null ? _b2 : void 0 : void 0;
317
- };
318
- for (const rf of resolved.features) {
319
- const authored = selfEffectsOf(rf.feature).filter((e) => e.kind === "unarmed-strike");
320
- for (const e of authored) {
321
- const d2 = readDie(rf, e.dice);
322
- if (d2) dice.push(d2);
323
- for (const ab of (_a = e.abilities) != null ? _a : []) abilities.add(ab);
324
- }
325
- if (authored.length || rf.source.kind !== "class") continue;
326
- const slug = ((_c = (_b = rf.feature.id) != null ? _b : rf.feature.name) != null ? _c : "").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/(^-|-$)/g, "");
327
- const column = unarmedDieColumnFor(slug);
328
- if (!column) continue;
329
- const d = readDie(rf, { column });
330
- if (!d) continue;
331
- dice.push(d);
332
- abilities.add("dex");
333
- }
334
- const avg = (d) => {
335
- const m = /^(\d+)d(\d+)$/i.exec(d);
336
- return m ? Number(m[1]) * (Number(m[2]) + 1) / 2 : 1;
337
- };
338
- const best = dice.sort((a, b) => avg(b) - avg(a))[0];
339
- return { ...best ? { dice: best } : {}, ...abilities.size ? { abilities: [...abilities] } : {} };
340
- }
341
- function initiativeBonus(dexMod, feats, edition) {
342
- let bonus = dexMod;
343
- for (const f of feats) {
344
- if (f.slug === "alert" && edition === "2014") bonus += 5;
345
- const initBonus = f.initiative_bonus;
346
- if (typeof initBonus === "number") bonus += initBonus;
347
- }
348
- return bonus;
349
- }
350
- function speedFromRace(resolved) {
351
- var _a, _b, _c;
352
- const base = (_c = (_b = (_a = resolved.race) == null ? void 0 : _a.speed) == null ? void 0 : _b.walk) != null ? _c : 30;
353
- let extra = 0;
354
- for (const f of resolved.feats) {
355
- const bonus = f.speed_bonus;
356
- if (typeof bonus === "number") extra += bonus;
357
- }
358
- return base + extra;
359
- }
360
- function collectClassFeatAbilityPoints(resolved) {
361
- var _a, _b;
362
- const out = {};
363
- const stripRef = (ref) => ref.replace(/^\[\[/, "").replace(/\]\]$/, "");
364
- const featBySlug = /* @__PURE__ */ new Map();
365
- for (const f of resolved.feats) featBySlug.set(f.slug, f);
366
- const sites = featPickSites(resolved.classes, poolMemberSitesOf(resolved), (ci) => {
367
- var _a2, _b2, _c, _d;
368
- return (_d = (_c = (_b2 = (_a2 = resolved.classes) == null ? void 0 : _a2[ci]) == null ? void 0 : _b2.entity) == null ? void 0 : _c.slug) != null ? _d : null;
369
- });
370
- for (const site of sites) {
371
- {
372
- const feat = featBySlug.get(stripRef(site.slug));
373
- if (!feat) continue;
374
- for (const ch of (_a = feat.choices) != null ? _a : []) {
375
- if (ch.kind !== "ability-points") continue;
376
- const raw = site.read(ch.id);
377
- if (!raw || typeof raw !== "object" || Array.isArray(raw)) continue;
378
- let left = ch.points;
379
- for (const ab of ABILITY_KEYS) {
380
- if (ch.pool && !ch.pool.includes(ab)) continue;
381
- const v = raw[ab];
382
- if (typeof v !== "number" || v <= 0 || left <= 0) continue;
383
- const take = Math.min(v, ch.max_per, left);
384
- out[ab] = ((_b = out[ab]) != null ? _b : 0) + take;
385
- left -= take;
386
- }
387
- }
388
- }
389
- }
390
- return out;
391
- }
392
- function computeAbilityScores(resolved, overrides) {
393
- var _a, _b, _c, _d, _e, _f;
394
- const out = { ...resolved.definition.abilities };
395
- const raceBonuses = flattenRaceAsi(resolved.race);
396
- for (const ab of ABILITY_KEYS) {
397
- const b = raceBonuses[ab];
398
- if (typeof b === "number") out[ab] = ((_a = out[ab]) != null ? _a : 0) + b;
399
- }
400
- for (const asi of subraceAsi(resolved)) {
401
- if (asi.ability && typeof asi.amount === "number") out[asi.ability] = ((_b = out[asi.ability]) != null ? _b : 0) + asi.amount;
402
- }
403
- const originPoints = collectChosenAbilityPoints(resolved);
404
- for (const src of [originPoints.race, originPoints.background]) {
405
- for (const ab of ABILITY_KEYS) {
406
- const v = src[ab];
407
- if (typeof v === "number") out[ab] = ((_c = out[ab]) != null ? _c : 0) + v;
408
- }
409
- }
410
- const classAsi = collectClassAsiBranch(resolved);
411
- for (const ab of ABILITY_KEYS) {
412
- const v = classAsi[ab];
413
- if (typeof v === "number") out[ab] = ((_d = out[ab]) != null ? _d : 0) + v;
414
- }
415
- const featPoints = collectClassFeatAbilityPoints(resolved);
416
- for (const ab of ABILITY_KEYS) {
417
- const v = featPoints[ab];
418
- if (typeof v === "number") out[ab] = ((_e = out[ab]) != null ? _e : 0) + v;
419
- }
420
- for (const f of resolved.feats) {
421
- const bonuses = f.ability_bonuses;
422
- if (bonuses) {
423
- for (const ab of ABILITY_KEYS) {
424
- const v = bonuses[ab];
425
- if (typeof v === "number") out[ab] = ((_f = out[ab]) != null ? _f : 0) + v;
426
- }
427
- }
428
- }
429
- if (overrides.scores) {
430
- for (const ab of ABILITY_KEYS) {
431
- const v = overrides.scores[ab];
432
- if (typeof v === "number") out[ab] = v;
433
- }
434
- }
435
- for (const ab of ABILITY_KEYS) {
436
- if (typeof out[ab] !== "number") out[ab] = 10;
437
- }
438
- return out;
439
- }
440
- function normalizeArmorProf(input) {
441
- var _a, _b;
442
- if (!input) return { categories: [], specific: [] };
443
- if (Array.isArray(input)) return { categories: input, specific: [] };
444
- return { categories: (_a = input.categories) != null ? _a : [], specific: (_b = input.specific) != null ? _b : [] };
445
- }
446
- function normalizeWeaponToolProf(input) {
447
- var _a, _b, _c;
448
- if (!input) return { categories: [], specific: [] };
449
- if (Array.isArray(input)) return { categories: [], specific: input };
450
- return { categories: (_a = input.categories) != null ? _a : [], specific: ((_b = input.fixed) != null ? _b : []).concat((_c = input.specific) != null ? _c : []) };
451
- }
452
- function mergeInto(target, source) {
453
- for (const c of source.categories) if (!target.categories.includes(c)) target.categories.push(c);
454
- for (const s of source.specific) if (!target.specific.includes(s)) target.specific.push(s);
455
- }
456
- var ORIGIN_RANK = { manual: 0, equipment: 1, grant: 2 };
457
- function composeDefenseEntries(manual, equipment, grants) {
458
- var _a;
459
- const byValue = /* @__PURE__ */ new Map();
460
- const consider = (list, origin) => {
461
- for (const raw of list) {
462
- const value = toDefenseSlug(raw);
463
- if (!value) continue;
464
- const existing = byValue.get(value);
465
- if (!existing) {
466
- byValue.set(value, { value, label: raw.trim(), origin });
467
- continue;
468
- }
469
- if (ORIGIN_RANK[origin] > ORIGIN_RANK[existing.origin]) existing.origin = origin;
470
- }
471
- };
472
- consider(manual, "manual");
473
- consider(equipment, "equipment");
474
- for (const g of grants) {
475
- const value = toDefenseSlug(g.value);
476
- if (!value) continue;
477
- const existing = byValue.get(value);
478
- if (!existing) {
479
- byValue.set(value, {
480
- value,
481
- label: g.value.trim(),
482
- origin: "grant",
483
- sources: [...g.sources],
484
- ...g.condition ? { condition: g.condition } : {}
485
- });
486
- continue;
487
- }
488
- if (ORIGIN_RANK.grant > ORIGIN_RANK[existing.origin]) existing.origin = "grant";
489
- const sources = (_a = existing.sources) != null ? _a : existing.sources = [];
490
- for (const src of g.sources) if (!sources.includes(src)) sources.push(src);
491
- if (!existing.condition && g.condition) existing.condition = g.condition;
492
- }
493
- return [...byValue.values()];
494
- }
495
- function suppress(resolved, bucket, entries) {
496
- var _a, _b, _c, _d, _e;
497
- const suppressed = new Set(
498
- ((_e = (_d = (_c = (_b = (_a = resolved.definition) == null ? void 0 : _a.overrides) == null ? void 0 : _b.defenses) == null ? void 0 : _c[bucket]) == null ? void 0 : _d.remove) != null ? _e : []).map(toDefenseSlug)
499
- );
500
- return entries.filter((e) => !suppressed.has(e.value));
501
- }
502
- function computeProficiencies(resolved) {
503
- var _a, _b, _c, _d, _e, _f, _g;
504
- const armor = { categories: [], specific: [] };
505
- const weapons = { categories: [], specific: [] };
506
- const tools = { categories: [], specific: [] };
507
- const languages = /* @__PURE__ */ new Set();
508
- for (const c of resolved.classes) {
509
- const p = (_a = c.entity) == null ? void 0 : _a.proficiencies;
510
- if (!p) continue;
511
- mergeInto(armor, normalizeArmorProf(p.armor));
512
- mergeInto(weapons, normalizeWeaponToolProf(p.weapons));
513
- mergeInto(tools, normalizeWeaponToolProf(p.tools));
514
- (_b = p.languages) == null ? void 0 : _b.forEach((l) => languages.add(l));
515
- }
516
- const racePr = (_c = resolved.race) == null ? void 0 : _c.proficiencies;
517
- if (racePr) {
518
- mergeInto(armor, normalizeArmorProf(racePr.armor));
519
- mergeInto(weapons, normalizeWeaponToolProf(racePr.weapons));
520
- mergeInto(tools, normalizeWeaponToolProf(racePr.tools));
521
- (_d = racePr.languages) == null ? void 0 : _d.forEach((l) => languages.add(l));
522
- }
523
- const bgPr = (_e = resolved.background) == null ? void 0 : _e.proficiencies;
524
- if (bgPr) {
525
- mergeInto(armor, normalizeArmorProf(bgPr.armor));
526
- mergeInto(weapons, normalizeWeaponToolProf(bgPr.weapons));
527
- mergeInto(tools, normalizeWeaponToolProf(bgPr.tools));
528
- (_f = bgPr.languages) == null ? void 0 : _f.forEach((l) => languages.add(l));
529
- }
530
- for (const f of resolved.feats) {
531
- const grants = f.grants_proficiency;
532
- if (!grants) continue;
533
- mergeInto(armor, normalizeArmorProf(grants.armor));
534
- mergeInto(weapons, normalizeWeaponToolProf(grants.weapons));
535
- mergeInto(tools, normalizeWeaponToolProf(grants.tools));
536
- (_g = grants.languages) == null ? void 0 : _g.forEach((l) => languages.add(l));
537
- }
538
- return {
539
- armor,
540
- weapons,
541
- tools,
542
- languages: Array.from(languages).sort(),
543
- saves: []
544
- };
545
- }
546
- function recalc(resolved, registry) {
547
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L, _M, _N, _O, _P, _Q, _R, _S, _T, _U, _V, _W, _X, _Y, _Z;
548
- const warnings = [];
549
- const overrides = (_a = resolved.definition.overrides) != null ? _a : {};
550
- const chosenProfs = collectChosenProficiencies(resolved);
551
- const { features: effectFeatures, activeBuffs } = assembleEffectFeatures(resolved);
552
- const tableDiceFor = (src, column, level) => {
553
- var _a2;
554
- const cls = src.kind === "class" ? resolved.classes.find((c) => {
555
- var _a3;
556
- return ((_a3 = c.entity) == null ? void 0 : _a3.slug) === src.slug;
557
- }) : src.kind === "subclass" ? resolved.classes.find((c) => {
558
- var _a3;
559
- return ((_a3 = c.subclass) == null ? void 0 : _a3.slug) === src.slug;
560
- }) : void 0;
561
- return cls ? diceColumnAt((_a2 = cls.entity) == null ? void 0 : _a2.table, level, column) : null;
562
- };
563
- const featureEffects = computeFeatureEffects(effectFeatures, { activeBuffs, levelFor: (src) => resourceLevelFor(src, resolved), tableDiceFor });
564
- const profsForApply = computeProficiencies(resolved);
565
- for (const t of chosenProfs.tools) {
566
- if (!profsForApply.tools.specific.includes(t)) profsForApply.tools.specific.push(t);
567
- }
568
- for (const l of chosenProfs.languages) {
569
- if (!profsForApply.languages.includes(l)) profsForApply.languages.push(l);
570
- }
571
- for (const w of chosenProfs.weapons) {
572
- if (!profsForApply.weapons.specific.includes(w)) profsForApply.weapons.specific.push(w);
573
- }
574
- for (const t of featureEffects.proficiencies.tools) {
575
- if (!profsForApply.tools.specific.includes(t)) profsForApply.tools.specific.push(t);
576
- }
577
- for (const l of featureEffects.proficiencies.languages) {
578
- if (!profsForApply.languages.includes(l)) profsForApply.languages.push(l);
579
- }
580
- for (const a of featureEffects.proficiencies.armor) {
581
- if (!profsForApply.armor.categories.includes(a)) profsForApply.armor.categories.push(a);
582
- }
583
- for (const w of featureEffects.proficiencies.weapons) {
584
- if (!profsForApply.weapons.categories.includes(w)) profsForApply.weapons.categories.push(w);
585
- if (!WEAPON_CATEGORY_WORDS.has(w) && !profsForApply.weapons.specific.includes(w)) {
586
- profsForApply.weapons.specific.push(w);
587
- }
588
- }
589
- profsForApply.languages.sort();
590
- const applied = registry ? computeAppliedBonuses(resolved, profsForApply, registry, warnings) : emptyAppliedBonuses();
591
- const savesInformational = applied.informational.filter(
592
- (i) => i.field === "saving_throws"
593
- );
594
- const spellcastingInformational = applied.informational.filter(
595
- (i) => i.field === "spell_attack" || i.field === "spell_save_dc"
596
- );
597
- const speedInformational = applied.informational.filter(
598
- (i) => i.field.startsWith("speed.")
599
- );
600
- const baseScores = computeAbilityScores(resolved, overrides);
601
- const scores = { ...baseScores };
602
- for (const ab of ABILITY_KEYS) {
603
- const bonus = applied.ability_bonuses[ab];
604
- scores[ab] += (typeof bonus === "number" ? bonus : 0) + ((_b = featureEffects.ability_bonus[ab]) != null ? _b : 0);
605
- }
606
- for (const ab of ABILITY_KEYS) {
607
- const stat = applied.ability_statics[ab];
608
- if (typeof stat === "number" && stat > scores[ab]) scores[ab] = stat;
609
- }
610
- if (overrides.scores) {
611
- for (const ab of ABILITY_KEYS) {
612
- const o = overrides.scores[ab];
613
- if (typeof o === "number") scores[ab] = o;
614
- }
615
- }
616
- const mods = {
617
- str: abilityModifier(scores.str),
618
- dex: abilityModifier(scores.dex),
619
- con: abilityModifier(scores.con),
620
- int: abilityModifier(scores.int),
621
- wis: abilityModifier(scores.wis),
622
- cha: abilityModifier(scores.cha)
623
- };
624
- const totalLevel = resolved.classes.reduce((s, c) => s + c.level, 0);
625
- const proficiencyBonus = proficiencyFromLevel(totalLevel || 1);
626
- const conditionEffects = computeConditionEffects(
627
- resolved.state,
628
- resolved.definition.edition,
629
- scores
630
- );
631
- const firstClass = (_d = (_c = resolved.classes[0]) == null ? void 0 : _c.entity) != null ? _d : null;
632
- const saveProfs = new Set((_e = firstClass == null ? void 0 : firstClass.saving_throws) != null ? _e : []);
633
- for (const ab of featureEffects.proficiencies.saves) saveProfs.add(ab);
634
- for (const ab of chosenProfs.saves) saveProfs.add(ab);
635
- const saves = {};
636
- const saveBreakdowns = {};
637
- const activeSaveBonusTerms = featureEffects.save_bonus_terms.filter((t) => {
638
- var _a2;
639
- return t.inactiveWhile === "incapacitated" ? !conditionEffects.actions_disabled : t.inactiveWhile === "unconscious" ? !((_a2 = resolved.state.conditions) != null ? _a2 : []).includes("unconscious") : true;
640
- });
641
- for (const ab of ABILITY_KEYS) {
642
- const override = (_f = overrides.saves) == null ? void 0 : _f[ab];
643
- const prof = (_g = override == null ? void 0 : override.proficient) != null ? _g : saveProfs.has(ab);
644
- const featureTerms = [];
645
- for (const t of activeSaveBonusTerms) {
646
- if (t.saves.length > 0 && !t.saves.includes(ab)) continue;
647
- const amount = Math.max(t.minimum, mods[t.ability]);
648
- const prior = featureTerms.find((x) => x.source === t.label);
649
- if (prior === void 0) featureTerms.push({ source: t.label, amount });
650
- else if (amount > prior.amount) prior.amount = amount;
651
- }
652
- const derivedBonus = savingThrow(scores[ab], prof, proficiencyBonus) + applied.save_bonus + featureTerms.reduce((sum, t) => sum + t.amount, 0) + conditionEffects.d20_test_penalty;
653
- const bonus = (_h = override == null ? void 0 : override.bonus) != null ? _h : derivedBonus;
654
- saves[ab] = { bonus, proficient: prof };
655
- saveBreakdowns[ab] = [
656
- { source: ab.toUpperCase(), amount: mods[ab] },
657
- ...prof ? [{ source: "Proficiency", amount: proficiencyBonus }] : [],
658
- ...applied.save_terms.map((t) => ({ ...t })),
659
- ...featureTerms,
660
- ...conditionEffects.d20_test_penalty ? [{ source: `Exhaustion ${conditionEffects.exhaustion_level}`, amount: conditionEffects.d20_test_penalty }] : []
661
- ];
662
- }
663
- const profSet = /* @__PURE__ */ new Set([
664
- ...resolved.definition.skills.proficient,
665
- ...(_j = (_i = resolved.background) == null ? void 0 : _i.skill_proficiencies) != null ? _j : [],
666
- ...chosenProfs.skills,
667
- ...featureEffects.proficiencies.skills
668
- ]);
669
- const expSet = /* @__PURE__ */ new Set([...resolved.definition.skills.expertise, ...chosenProfs.expertise, ...featureEffects.proficiencies.skillExpertise]);
670
- const skills = {};
671
- const skillBreakdowns = {};
672
- for (const skill of ALL_SKILLS) {
673
- const skillKey = skillSlugFromDisplay(skill);
674
- const ab = SKILL_ABILITY[skillSlugToAbilityLookup(skillKey)];
675
- const override = (_k = overrides.skills) == null ? void 0 : _k[skillKey];
676
- const tri = (_l = override == null ? void 0 : override.proficiency) != null ? _l : expSet.has(skillKey) ? "expertise" : profSet.has(skillKey) ? "proficient" : "none";
677
- const skillTerms = featureEffects.skill_bonus_terms.filter((t) => t.skills.includes(skillKey)).map((t) => ({ source: t.label, amount: Math.max(t.minimum, mods[t.ability]) }));
678
- const halfProfTerms = tri !== "none" ? [] : featureEffects.half_proficiency_terms.filter((t) => t.skills.length === 0 || t.skills.includes(skillKey)).map((t) => ({ source: t.label, amount: t.round === "up" ? Math.ceil(proficiencyBonus / 2) : Math.floor(proficiencyBonus / 2) }));
679
- const halfProfBest = halfProfTerms.length ? halfProfTerms.reduce((best, t) => t.amount > best.amount ? t : best) : null;
680
- const bonus = (_n = override == null ? void 0 : override.bonus) != null ? _n : skillBonus(scores[ab], tri, proficiencyBonus) + skillTerms.reduce((sum, t) => sum + t.amount, 0) + ((_m = halfProfBest == null ? void 0 : halfProfBest.amount) != null ? _m : 0) + conditionEffects.d20_test_penalty;
681
- skillBreakdowns[skillKey] = [
682
- { source: ab.toUpperCase(), amount: mods[ab] },
683
- ...tri !== "none" ? [{ source: tri === "expertise" ? "Expertise" : "Proficiency", amount: proficiencyBonus * (tri === "expertise" ? 2 : 1) }] : [],
684
- ...skillTerms,
685
- ...halfProfBest ? [halfProfBest] : [],
686
- ...conditionEffects.d20_test_penalty ? [{ source: "Conditions", amount: conditionEffects.d20_test_penalty }] : []
687
- ];
688
- skills[skillKey] = {
689
- bonus,
690
- proficiency: tri,
691
- ability: ab,
692
- ...halfProfBest ? { halfProficiency: { source: halfProfBest.source, amount: halfProfBest.amount } } : {}
693
- };
694
- }
695
- const passives = {
696
- perception: (_p = (_o = overrides.passives) == null ? void 0 : _o.perception) != null ? _p : 10 + skills.perception.bonus,
697
- investigation: (_r = (_q = overrides.passives) == null ? void 0 : _q.investigation) != null ? _r : 10 + skills.investigation.bonus,
698
- insight: (_t = (_s = overrides.passives) == null ? void 0 : _s.insight) != null ? _t : 10 + skills.insight.bonus
699
- };
700
- const hpRolled = (_v = (_u = overrides.hp) == null ? void 0 : _u.rolled) != null ? _v : null;
701
- const hpModifier = (_x = (_w = overrides.hp) == null ? void 0 : _w.modifier) != null ? _x : null;
702
- const averageDiceSum = hitDiceAverageSum(resolved.classes);
703
- const conLevels = hpLevelCount(resolved.classes);
704
- const diceSum = hpRolled != null ? hpRolled : averageDiceSum;
705
- const diceConRaw = diceSum + mods.con * conLevels;
706
- const diceConClamped = Math.max(1, diceConRaw);
707
- const hpMaxDerived = diceConClamped + featureEffects.hp_per_level_bonus * totalLevel + (hpModifier != null ? hpModifier : 0);
708
- const hpMaxAfterConditions = Math.max(0, Math.floor(hpMaxDerived * conditionEffects.hp_max_multiplier));
709
- const hpMax = (_z = (_y = overrides.hp) == null ? void 0 : _y.max) != null ? _z : hpMaxAfterConditions;
710
- const hpBreakdown = {
711
- diceSum,
712
- diceSource: hpRolled != null ? "rolled" : "average",
713
- averageDiceSum,
714
- conMod: mods.con,
715
- conLevels,
716
- clampApplied: diceConClamped !== diceConRaw,
717
- perLevelTerms: featureEffects.hp_per_level_terms.map((t) => ({
718
- label: t.label,
719
- perLevel: t.value,
720
- levels: totalLevel,
721
- total: t.value * totalLevel
722
- })),
723
- modifier: hpModifier,
724
- exhaustionMultiplier: conditionEffects.hp_max_multiplier,
725
- exhaustionLevel: conditionEffects.exhaustion_level,
726
- derivedMax: hpMaxAfterConditions,
727
- override: (_B = (_A = overrides.hp) == null ? void 0 : _A.max) != null ? _B : null,
728
- final: hpMax
729
- };
730
- const featureAcTermsFor = (hasArmor) => featureEffects.ac_terms.filter((t) => !t.requires_armor || hasArmor).map((t) => ({ source: t.label, amount: t.value, kind: "feature", condition: t.condition }));
731
- const sumTerms = (terms) => terms.reduce((s, t) => s + t.amount, 0);
732
- const weaponAbilities = [...featureEffects.weaponAbilities];
733
- const wantsSpellcasting = resolved.features.some((rf) => selfEffectsOf(rf.feature).some((e) => e.kind === "weapon-ability" && e.ability === "spellcasting"));
734
- if (wantsSpellcasting) {
735
- let primaryCasterAbility = null;
736
- for (const c of resolved.classes) {
737
- if (!c.entity) continue;
738
- const profile = resolveSpellcasting(c);
739
- if (profile) {
740
- primaryCasterAbility = effectiveSpellcastingAbility(c.entity.slug, profile.ability, overrides);
741
- break;
742
- }
743
- }
744
- if (primaryCasterAbility) weaponAbilities.unshift({ ability: primaryCasterAbility });
745
- }
746
- let derivedEquipment = null;
747
- let acDerived;
748
- let acBreakdownDerived = [];
749
- let acInformationalDerived = [];
750
- if (registry) {
751
- derivedEquipment = computeSlotsAndAttacks(resolved, mods, profsForApply, registry, warnings, proficiencyBonus, weaponAbilities, (_C = resolved.weaponMasteries) != null ? _C : [], featureEffects.attunement_set);
752
- if (derivedEquipment.equippedSlots.armor) {
753
- const featTerms = featureAcTermsFor(true);
754
- acDerived = derivedEquipment.ac + sumTerms(featTerms);
755
- acBreakdownDerived = [...derivedEquipment.acBreakdown, ...featTerms];
756
- acInformationalDerived = derivedEquipment.acInformational;
757
- } else {
758
- const shieldBonus = derivedEquipment.acBreakdown.filter((b) => b.kind === "shield").reduce((sum, b) => sum + b.amount, 0);
759
- const { total: unarmored, terms: unarmoredTerms, shieldAllowed } = unarmoredACBreakdown(resolved, mods, warnings, shieldBonus);
760
- const additive = derivedEquipment.acBreakdown.filter(
761
- (b) => b.kind === "item" || b.kind === "override" || b.kind === "shield" && shieldAllowed
762
- );
763
- const featTerms = featureAcTermsFor(false);
764
- const additiveSum = additive.reduce((sum, b) => sum + b.amount, 0);
765
- acDerived = unarmored + additiveSum + sumTerms(featTerms);
766
- acBreakdownDerived = [...unarmoredTerms, ...additive, ...featTerms];
767
- acInformationalDerived = derivedEquipment.acInformational;
768
- }
769
- } else {
770
- const { total, terms } = unarmoredACBreakdown(resolved, mods, warnings);
771
- const featTerms = featureAcTermsFor(false);
772
- acDerived = total + sumTerms(featTerms);
773
- acBreakdownDerived = [...terms, ...featTerms];
774
- }
775
- const ac = (_D = overrides.ac) != null ? _D : acDerived;
776
- const additiveSpeed = speedFromRace(resolved) + applied.speed_bonuses.walk + featureEffects.speed_walk_bonus;
777
- const baseSpeed = Math.max(featureEffects.speed_walk_set, additiveSpeed);
778
- const adjustedSpeed = baseSpeed * conditionEffects.speed_multiplier - conditionEffects.speed_reduction_ft;
779
- const conditionSpeed = conditionEffects.speed_floor_zero ? 0 : Math.max(0, Math.floor(adjustedSpeed));
780
- const speed = (_E = overrides.speed) != null ? _E : conditionSpeed;
781
- const raceSpeed = (_H = (_G = (_F = resolved.race) == null ? void 0 : _F.speed) == null ? void 0 : _G.walk) != null ? _H : 30;
782
- const speedBreakdown = [
783
- { source: "Base speed", amount: raceSpeed },
784
- ...speedFromRace(resolved) !== raceSpeed ? [{ source: "Feats", amount: speedFromRace(resolved) - raceSpeed }] : [],
785
- ...applied.speed_bonuses.walk ? [{ source: "Equipment", amount: applied.speed_bonuses.walk }] : [],
786
- ...featureEffects.speed_walk_terms.map((term) => ({ source: term.label, amount: term.value })),
787
- ...baseSpeed > additiveSpeed ? [{ source: "Minimum speed", amount: baseSpeed - additiveSpeed }] : [],
788
- ...conditionSpeed !== baseSpeed ? [{ source: "Conditions", amount: conditionSpeed - baseSpeed }] : []
789
- ];
790
- if (!resolved.race) warnings.push("No race resolved; speed defaulted to 30.");
791
- const init = (_I = overrides.initiative) != null ? _I : initiativeBonus(mods.dex, resolved.feats, resolved.definition.edition) + featureEffects.initiative_bonus;
792
- const initiativeBreakdown = [
793
- { source: "DEX", amount: mods.dex },
794
- ...initiativeBonus(mods.dex, resolved.feats, resolved.definition.edition) !== mods.dex ? [{ source: "Feats", amount: initiativeBonus(mods.dex, resolved.feats, resolved.definition.edition) - mods.dex }] : [],
795
- ...featureEffects.initiative_terms.map((term) => ({ source: term.label, amount: term.value }))
796
- ];
797
- const senses = {
798
- darkvision: Math.max((_L = (_K = (_J = resolved.race) == null ? void 0 : _J.vision) == null ? void 0 : _K.darkvision) != null ? _L : 0, featureEffects.senses.darkvision, applied.senses.darkvision),
799
- blindsight: Math.max(featureEffects.senses.blindsight, applied.senses.blindsight),
800
- tremorsense: Math.max(featureEffects.senses.tremorsense, applied.senses.tremorsense),
801
- truesight: Math.max(featureEffects.senses.truesight, applied.senses.truesight)
802
- };
803
- const spellcastingClasses = [];
804
- const slotInputs = [];
805
- const limitInputs = [];
806
- for (const c of resolved.classes) {
807
- if (!c.entity) continue;
808
- const profile = resolveSpellcasting(c);
809
- if (!profile) continue;
810
- const ab = effectiveSpellcastingAbility(c.entity.slug, profile.ability, overrides);
811
- const dc = saveDC(scores[ab], proficiencyBonus) + applied.spell_save_dc;
812
- const atk = attackBonus(scores[ab], proficiencyBonus) + applied.spell_attack;
813
- spellcastingClasses.push({
814
- classSlug: c.entity.slug,
815
- className: c.entity.name,
816
- ability: ab,
817
- defaultAbility: profile.ability,
818
- saveDC: dc,
819
- attackBonus: atk,
820
- casterType: profile.casterType,
821
- preparation: profile.preparation,
822
- spellList: profile.spellList
823
- });
824
- slotInputs.push({ casterType: profile.casterType, level: c.level });
825
- limitInputs.push({ classSlug: c.entity.slug, level: c.level, profile, abilityScore: scores[ab] });
826
- }
827
- const spellcasting = spellcastingClasses.length > 0 ? {
828
- ability: spellcastingClasses[0].ability,
829
- saveDC: spellcastingClasses[0].saveDC,
830
- attackBonus: spellcastingClasses[0].attackBonus
831
- } : null;
832
- const abilitySpellcasting = {};
833
- for (const s of resolved.spells) {
834
- const ab = s.ability;
835
- if (!ab || abilitySpellcasting[ab]) continue;
836
- abilitySpellcasting[ab] = {
837
- saveDC: saveDC(scores[ab], proficiencyBonus) + applied.spell_save_dc,
838
- attackBonus: attackBonus(scores[ab], proficiencyBonus) + applied.spell_attack
839
- };
840
- }
841
- const derivedSlots = deriveSpellSlots(slotInputs);
842
- const spellLimits = computeSpellLimits(limitInputs);
843
- const defenses = {
844
- resistances: suppress(resolved, "resistances", composeDefenseEntries(
845
- (_N = (_M = resolved.definition.defenses) == null ? void 0 : _M.resistances) != null ? _N : [],
846
- applied.defenses.resistances,
847
- featureEffects.resistances
848
- )),
849
- immunities: suppress(resolved, "immunities", composeDefenseEntries(
850
- (_P = (_O = resolved.definition.defenses) == null ? void 0 : _O.immunities) != null ? _P : [],
851
- applied.defenses.immunities,
852
- featureEffects.immunities
853
- )),
854
- vulnerabilities: suppress(resolved, "vulnerabilities", composeDefenseEntries(
855
- (_R = (_Q = resolved.definition.defenses) == null ? void 0 : _Q.vulnerabilities) != null ? _R : [],
856
- applied.defenses.vulnerabilities,
857
- featureEffects.vulnerabilities
858
- )),
859
- condition_immunities: suppress(resolved, "condition_immunities", composeDefenseEntries(
860
- (_T = (_S = resolved.definition.defenses) == null ? void 0 : _S.condition_immunities) != null ? _T : [],
861
- applied.defenses.condition_immunities,
862
- featureEffects.condition_immunities
863
- ))
864
- };
865
- const attackRows = [...(_U = derivedEquipment == null ? void 0 : derivedEquipment.attacks) != null ? _U : [], buildUnarmedRow(mods, proficiencyBonus, resolveUnarmedStrike(resolved))];
866
- const riderBindings = (owner) => amountBindingsFor(owner, resolved, { proficiencyBonus, mods, spellcastingClasses });
867
- return {
868
- totalLevel,
869
- proficiencyBonus,
870
- scores,
871
- mods,
872
- saves,
873
- proficiencies: profsForApply,
874
- skills,
875
- statBreakdowns: { skills: skillBreakdowns, saves: saveBreakdowns, speed: speedBreakdown, initiative: initiativeBreakdown },
876
- passives,
877
- senses,
878
- hp: {
879
- max: hpMax,
880
- current: resolved.state.hp.current,
881
- temp: resolved.state.hp.temp
882
- },
883
- hpBreakdown,
884
- ac,
885
- speed,
886
- initiative: init,
887
- spellcasting,
888
- spellcastingClasses,
889
- abilitySpellcasting,
890
- derivedSpellSlots: derivedSlots.standard,
891
- pactMagic: derivedSlots.pact,
892
- spellLimits,
893
- warnings,
894
- defenses,
895
- acBreakdown: acBreakdownDerived,
896
- acInformational: acInformationalDerived,
897
- savesInformational,
898
- spellcastingInformational,
899
- speedInformational,
900
- // Always ≥ 1; non-stacking (Math.max) extra attacks fold in pc.feature-effects.
901
- attacksPerAction: 1 + featureEffects.extraAttack,
902
- // Consolidated post-apply over the built attack rows: the d20 condition
903
- // penalty (always), plus display-only annotations conditionally spread so
904
- // untouched rows keep `critRange`/`attackNotes` ABSENT (not 20 / not []).
905
- // crit-range: folded weapon crit threshold, only when an effect lowered it.
906
- // attackNotes: reroll-damage / attack-rule captions, only when non-empty.
907
- attacks: attackRows.map((a) => {
908
- var _a2;
909
- const riders = [...(_a2 = a.damageRiders) != null ? _a2 : [], ...featureEffects.damageBonuses.filter((r) => riderReachesRow(r, a))].map((r) => resolveDamageRider(r, a.damageType, riderBindings));
910
- return {
911
- ...a,
912
- toHit: a.toHit + conditionEffects.d20_test_penalty,
913
- ...featureEffects.critRange < 20 ? { critRange: featureEffects.critRange } : {},
914
- ...featureEffects.attackNotes.length ? { attackNotes: featureEffects.attackNotes } : {},
915
- ...riders.length ? { damageRiders: riders } : {}
916
- };
917
- }),
918
- equippedSlots: (_V = derivedEquipment == null ? void 0 : derivedEquipment.equippedSlots) != null ? _V : {},
919
- carriedWeight: (_W = derivedEquipment == null ? void 0 : derivedEquipment.carriedWeight) != null ? _W : 0,
920
- attunementUsed: (_X = derivedEquipment == null ? void 0 : derivedEquipment.attunementUsed) != null ? _X : 0,
921
- attunementLimit: (_Z = derivedEquipment == null ? void 0 : derivedEquipment.attunementLimit) != null ? _Z : (_Y = overrides.attunement_limit) != null ? _Y : Math.max(3, featureEffects.attunement_set),
922
- conditionEffects,
923
- rollModifiers: featureEffects.rollModifiers,
924
- saveOutcomes: featureEffects.saveOutcomes
925
- };
926
- }
927
- export {
928
- abilityBonusBreakdown,
929
- collectClassAsiBranch,
930
- collectClassFeatAbilityPoints,
931
- computeAbilityScores,
932
- computeProficiencies,
933
- flattenRaceAsi,
934
- hitDiceAverageSum,
935
- hpLevelCount,
936
- initiativeBonus,
937
- multiclassMaxHP,
938
- parseDieSize,
939
- phbAverageForDie,
940
- recalc,
941
- resolveUnarmedStrike,
942
- riderReachesRow,
943
- speedFromRace,
944
- unarmoredAC,
945
- unarmoredACBreakdown
946
- };
1
+ import{buildFeatureAttackRows,buildUnarmedRow,computeAppliedBonuses,computeSlotsAndAttacks,emptyAppliedBonuses,pactWeaponIndexes}from"../chunk-7UPYRKMF.js";import"../chunk-T55DELVL.js";import"../chunk-SEOASDO4.js";import{amountBindingsFor}from"../chunk-MC6PLWRZ.js";import"../chunk-PZ3ZZ5H5.js";import{computeConditionEffects,speedConditionNames}from"../chunk-VA3ZWV7C.js";import"../chunk-4E2GIWJE.js";import{collectChosenAbilityPoints,collectChosenProficiencies}from"../chunk-IGVRLGLM.js";import"../chunk-2EOGK6R6.js";import"../chunk-RQZCGXUZ.js";import"../chunk-PQAVMK3T.js";import{assembleEffectFeatures,computeFeatureEffects,foldsNow,mergeDefenseItems,selfEffectsOf}from"../chunk-HCK6IUB3.js";import"../chunk-FOLHTMSC.js";import"../chunk-4JEF3CET.js";import{proficiencyKey}from"../chunk-VTQ4RWEG.js";import{featPickSites,poolMemberSitesOf,spellsReached}from"../chunk-QBA757AU.js";import"../chunk-A7H6LX47.js";import"../chunk-UBUKCRZ3.js";import{resourceLevelFor}from"../chunk-PZUPZBTN.js";import{computeSpellLimits,deriveSpellSlots,effectiveSpellcastingAbility,resolveSpellcasting}from"../chunk-NI364WV7.js";import{legacyAsiBranch}from"../chunk-QVWT67WA.js";import{toDefenseSlug}from"../chunk-LR6UMA5V.js";import"../chunk-DY6FVAGA.js";import"../chunk-CMIEZQL4.js";import{diceColumnAt,unarmedDieColumnFor}from"../chunk-BGX36NPE.js";import"../chunk-O776WL7O.js";import"../chunk-3LWOVRLA.js";import"../chunk-DVUXUIPV.js";import"../chunk-YGH7S5ZF.js";import"../chunk-NEMX7QGG.js";import"../chunk-56JK6VCL.js";import"../chunk-4IAMSRHD.js";import"../chunk-3QQOATV3.js";import"../chunk-DZITM5AG.js";import"../chunk-PZ4L2EEG.js";import"../chunk-QMEKQTUT.js";import{resolveAmountText}from"../chunk-VIP3FH2O.js";import"../chunk-EAARMPCW.js";import"../chunk-CAPYNIGK.js";import{bareEntitySlug,slugify}from"../chunk-63YJPWTM.js";import"../chunk-4KVVAENP.js";import"../chunk-7EL3GWWJ.js";import"../chunk-BREHZNTL.js";import{abilityModifier,attackBonus,isCanonicalDamageType,isChosenDamageType,proficiencyFromLevel,saveDC,savingThrow,skillBonus}from"../chunk-7FPQJDFD.js";import{ABILITY_KEYS,ALL_SKILLS,SKILL_ABILITY}from"../chunk-EVT7MGAC.js";import"../chunk-S5UCI27C.js";import"../chunk-6IC53O3Q.js";import"../chunk-I26FHSI6.js";var lower=s=>(s!=null?s:"").trim().toLowerCase();function namedSpellSlug(ref){var _a;const inner=ref.replace(/^\[\[/,"").replace(/\]\]$/,"").split("|")[0];return slugify((_a=inner.split("/").pop())!=null?_a:inner)}function dealsDamage(spell){var _a,_b;return((_b=(_a=spell.damage)==null?void 0:_a.types)!=null?_b:[]).some(t=>t.trim()!=="")}function spellsInScope(scope,spells,pickedTypes){var _a,_b;if(!scope)return[];const picked=scope.damage_type_pick!==void 0?pickedTypes(scope.damage_type_pick).map(lower):null;const types=(_a=scope.damage_types)==null?void 0:_a.map(lower);const named=(_b=scope.spells)==null?void 0:_b.map(namedSpellSlug);const hit=spells.filter(({slug,entity:e})=>{var _a2,_b2,_c,_d,_e;if(!dealsDamage(e))return false;const own=((_b2=(_a2=e.damage)==null?void 0:_a2.types)!=null?_b2:[]).map(lower);if(scope.list!==void 0&&!((_c=e.classes)!=null?_c:[]).map(lower).includes(lower(scope.list)))return false;if(scope.level!==void 0&&((_d=e.level)!=null?_d:0)!==scope.level)return false;if(scope.school!==void 0&&lower(e.school)!==lower(scope.school))return false;if(types&&!own.some(t=>types.includes(t)))return false;if(picked&&!own.some(t=>picked.includes(t)))return false;if(named&&!named.includes(bareEntitySlug(slug))&&!named.includes(slugify((_e=e.name)!=null?_e:"")))return false;return true});return[...new Set(hit.map(s=>s.slug))]}function pickedDamageTypes(resolved,choiceId){var _a,_b,_c,_d,_e,_f;const out=new Set;for(const c of(_a=resolved.classes)!=null?_a:[]){for(const owner of[c.entity,c.subclass]){for(const[lvl,feats]of Object.entries((_b=owner==null?void 0:owner.features_by_level)!=null?_b:{})){for(const feat of feats!=null?feats:[]){for(const ch of(_c=feat.choices)!=null?_c:[]){if(ch.kind!=="select-inline"||ch.id!==choiceId)continue;const sel=((_e=(_d=c.choices)==null?void 0:_d[Number(lvl)])!=null?_e:{})[ch.id];if(typeof sel!=="string")continue;const opt=ch.options.find(o=>o.value===sel);for(const word of`${sel} ${(_f=opt==null?void 0:opt.label)!=null?_f:""}`.split(/[^A-Za-z]+/)){if(word&&isCanonicalDamageType(word))out.add(word.toLowerCase())}}}}}}return[...out]}var OTHER_MODES=["fly","swim","climb","burrow"];function speedAfterConditions(pre,ce){if(ce.speed_floor_zero)return 0;return Math.max(0,Math.floor(pre*ce.speed_multiplier-ce.speed_reduction_ft))}var term=(source,amount,condition)=>({source,amount,...condition?{condition}:{}});function walkTerms(i,species){var _a,_b,_c;const terms=[term(species,i.walk.race)];for(const f of i.resolved.feats){const bonus=f.speed_bonus;if(typeof bonus==="number"&&bonus!==0)terms.push(term((_a=f.name)!=null?_a:"Feat",bonus))}for(const t of i.applied.speed_terms)if(t.mode==="walk"&&t.kind==="bonus")terms.push(term(t.source,t.amount));for(const t of i.features.speed_terms)if(t.mode==="walk"&&!t.set)terms.push(term(t.label,t.value,t.condition));if(i.walk.base>i.walk.additive){const itemWins=i.applied.speed_walk_set===i.walk.base&&i.applied.speed_walk_set>i.features.speed_walk_set;const source=itemWins?(_b=i.applied.speed_walk_set_terms.find(t=>t.amount===i.walk.base))==null?void 0:_b.source:(_c=i.features.speed_terms.find(t=>t.mode==="walk"&&t.set&&t.value===i.walk.base))==null?void 0:_c.label;terms.push(term(source!=null?source:"Minimum speed",i.walk.base-i.walk.additive))}if(i.walk.final!==i.walk.base)terms.push(term(conditionLabel(i),i.walk.final-i.walk.base));return terms}var conditionLabel=i=>i.conditionNames.join(", ")||"Conditions";function otherLine(i,mode,species){var _a,_b,_c,_d;const grants=[];const own=(_b=(_a=i.resolved.race)==null?void 0:_a.speed)==null?void 0:_b[mode];if(typeof own==="number"&&own>0)grants.push(term(species,own));for(const t of i.features.speed_terms)if(t.mode===mode&&t.set&&t.value>0)grants.push(term(t.label,t.value,t.condition));for(const t of i.applied.speed_terms)if(t.mode===mode&&t.kind==="grant"&&t.amount>0)grants.push(term(t.source,t.amount));for(const t of i.applied.speed_terms)if(t.mode===mode&&t.kind==="walk")grants.push({...term(t.source,i.walk.base),equalsWalk:true});if(grants.length===0)return null;const best=grants.reduce((a,b)=>b.amount>a.amount?b:a);if(best.amount<=0)return null;const{equalsWalk,...bestTerm}=best;const bonuses=i.features.speed_terms.filter(t=>t.mode===mode&&!t.set&&t.value!==0).map(t=>term(t.label,t.value,t.condition));const terms=[bestTerm,...bonuses];const pre=terms.reduce((s,t)=>s+t.amount,0);const value=speedAfterConditions(pre,i.conditions);if(value!==pre)terms.push(term(conditionLabel(i),value-pre));return{mode,value,...equalsWalk&&bonuses.length===0?{equalsWalk:true}:{},...mode==="fly"&&((_d=(_c=i.resolved.race)==null?void 0:_c.speed)==null?void 0:_d.hover)===true&&typeof own==="number"&&own>0?{hover:true}:{},terms}}function buildSpeedLines(i){var _a,_b;const species=(_b=(_a=i.resolved.race)==null?void 0:_a.name)!=null?_b:"Base speed";const lines=[{mode:"walk",value:i.walk.final,terms:walkTerms(i,species)}];for(const mode of OTHER_MODES){const line=otherLine(i,mode,species);if(line)lines.push(line)}return lines}var WEAPON_CATEGORY_WORDS=new Set(["simple","martial","simple-melee","simple-ranged","martial-melee","martial-ranged","natural"]);function phbAverageForDie(hitDieStr){const n=parseDieSize(hitDieStr);if(n==null)return 4;return Math.floor(n/2)+1}function parseDieSize(die){if(die==null)return null;if(typeof die==="number")return die;const m=die.match(/^d?(\d+)$/i);return m?parseInt(m[1],10):null}function skillSlugFromDisplay(display){return display.toLowerCase().replace(/\s+/g,"-")}function skillSlugToAbilityLookup(slug){return slug.replace(/-/g," ")}function flattenRaceAsi(race){var _a;const out={};if(!(race==null?void 0:race.ability_score_increases))return out;for(const asi of race.ability_score_increases){if("ability"in asi){out[asi.ability]=((_a=out[asi.ability])!=null?_a:0)+asi.amount}}return out}function subraceAsi(resolved){var _a,_b,_c,_d,_e;const subSlug=(_b=(_a=resolved.definition.subrace)==null?void 0:_a.replace(/\[\[|\]\]/g,""))!=null?_b:null;if(!subSlug)return[];const subraces=(_d=(_c=resolved.race)==null?void 0:_c.subraces)!=null?_d:[];const sub=subraces.find(s=>s.slug===subSlug);return(_e=sub==null?void 0:sub.ability_score_increases)!=null?_e:[]}function collectClassAsiBranch(resolved){var _a;const out={};for(const c of resolved.classes){for(const choice of Object.values(c.choices)){const alloc=legacyAsiBranch(choice);if(!alloc)continue;for(const ab of ABILITY_KEYS){const v=alloc[ab];if(typeof v==="number")out[ab]=((_a=out[ab])!=null?_a:0)+v}}}return out}function abilityBonusBreakdown(resolved,featureEffects){var _a,_b,_c,_d,_e,_f,_g,_h;const race=flattenRaceAsi(resolved.race);const origin=collectChosenAbilityPoints(resolved);const sub=subraceAsi(resolved);const classAsi=collectClassAsiBranch(resolved);const featPoints=collectClassFeatAbilityPoints(resolved);const out={};for(const ab of ABILITY_KEYS){let species=((_a=race[ab])!=null?_a:0)+((_b=origin.race[ab])!=null?_b:0);for(const asi of sub){if(asi.ability===ab&&typeof asi.amount==="number")species+=asi.amount}let feat=(_c=featPoints[ab])!=null?_c:0;for(const f of resolved.feats){const bonus=(_d=f.ability_bonuses)==null?void 0:_d[ab];if(typeof bonus==="number")feat+=bonus;feat+=(_e=fixedFeatAbilityIncrease(f)[ab])!=null?_e:0}out[ab]={species,background:(_f=origin.background[ab])!=null?_f:0,class:((_g=classAsi[ab])!=null?_g:0)+((_h=featureEffects==null?void 0:featureEffects.ability_bonus[ab])!=null?_h:0),feat}}return out}function fixedFeatAbilityIncrease(f){var _a;const g=f.grants_asi;if(!g||typeof g.amount!=="number"||g.amount<=0||!Array.isArray(g.pool)||g.pool.length!==1)return{};if(((_a=f.choices)!=null?_a:[]).some(c=>c.kind==="ability-points"))return{};const ab=g.pool[0];return ABILITY_KEYS.includes(ab)?{[ab]:g.amount}:{}}function hitDiceAverageSum(classes){var _a;let total=0;let firstLevelCounted=false;for(const c of classes){const die=parseDieSize((_a=c.entity)==null?void 0:_a.hit_die);if(!c.entity||die==null||c.level<1)continue;for(let lvl=1;lvl<=c.level;lvl++){if(!firstLevelCounted){total+=die;firstLevelCounted=true}else{total+=Math.floor(die/2)+1}}}return total}function hpLevelCount(classes){var _a;let count=0;for(const c of classes){const die=parseDieSize((_a=c.entity)==null?void 0:_a.hit_die);if(!c.entity||die==null||c.level<1)continue;count+=c.level}return count}function multiclassMaxHP(classes,conMod){return Math.max(1,hitDiceAverageSum(classes)+conMod*hpLevelCount(classes))}function resolveDamageRider(rider,rowDamageType,bindings){const{owner,scope:_scope,...rest}=rider;const out={...rest,amount:resolveAmountText(rider.amount,bindings(owner))};if(rider.damage_type!==void 0&&!isChosenDamageType(rider.damage_type)){const resolved=isCanonicalDamageType(rider.damage_type)?rider.damage_type:rowDamageType;if(resolved)out.damage_type=resolved;else delete out.damage_type}return out}function riderReachesRow(rider,row,opts){return scopeReachesRow(rider.scope,row,opts)}function scopeReachesRow(scope,row,opts){if(!(scope==null?void 0:scope.length))return true;return scope.some(word=>{switch(word){case"weapon":return row.unarmed!==true;case"pact-weapon":return(opts==null?void 0:opts.pactPicked)===true?row.pactWeapon===true:row.unarmed!==true;case"unarmed":return row.unarmed===true;case"melee":case"ranged":return row.weaponCategory===word;case"finesse":case"thrown":return row.properties.includes(word)}})}function unarmoredAC(resolved,mods,warnings){return unarmoredACBreakdown(resolved,mods,warnings).total}function unarmoredACBreakdown(resolved,mods,warnings,shieldBonus=0){var _a,_b,_c,_d,_e,_f;const baseTerms=[{source:"Unarmored",amount:10,kind:"unarmored"},{source:"DEX modifier",amount:mods.dex,kind:"dex"}];const{activeBuffs}=assembleEffectFeatures(resolved);const candidates=[{total:10+mods.dex,terms:baseTerms,shieldAllowed:true}];for(const rf of[...resolved.features,...(_a=resolved.itemFeatures)!=null?_a:[]]){if(!foldsNow(rf,activeBuffs))continue;for(const eff of selfEffectsOf(rf.feature)){if(eff.kind!=="unarmored-ac")continue;const base=(_b=eff.base)!=null?_b:10;const terms=[{source:"Unarmored",amount:base,kind:"unarmored"}];let total=base;for(const ab of eff.abilities){terms.push(ab==="dex"?{source:"DEX modifier",amount:mods.dex,kind:"dex"}:{source:`${ab.toUpperCase()} modifier (${(_c=rf.feature.name)!=null?_c:"Unarmored"})`,amount:mods[ab],kind:"ability"});total+=mods[ab]}candidates.push({total,terms,shieldAllowed:eff.allow_shield===true})}}if(candidates.length>1){const applied=c=>c.total+(c.shieldAllowed?shieldBonus:0);let best=candidates[0];for(const c of candidates)if(applied(c)>applied(best))best=c;return best}for(const rf of resolved.features){const feat=rf.feature;if((_d=feat.unarmored_defense)==null?void 0:_d.ability){const ab=feat.unarmored_defense.ability;const amt=(_e=mods[ab])!=null?_e:0;const terms=[...baseTerms,{source:`${ab.toUpperCase()} modifier (Unarmored Defense)`,amount:amt,kind:"ability"}];return{total:10+mods.dex+amt,terms,shieldAllowed:true}}}for(const rf of resolved.features){const name=((_f=rf.feature.name)!=null?_f:"").toLowerCase();if(!/unarmored\s*defense/.test(name))continue;if(rf.source.kind==="class"&&rf.source.slug.includes("monk")){const terms=[...baseTerms,{source:"WIS modifier (Unarmored Defense)",amount:mods.wis,kind:"ability"}];return{total:10+mods.dex+mods.wis,terms,shieldAllowed:true}}if(rf.source.kind==="class"&&rf.source.slug.includes("barbarian")){const terms=[...baseTerms,{source:"CON modifier (Unarmored Defense)",amount:mods.con,kind:"ability"}];return{total:10+mods.dex+mods.con,terms,shieldAllowed:true}}}return{total:10+mods.dex,terms:baseTerms,shieldAllowed:true}}function resolveUnarmedStrike(resolved){var _a,_b,_c;const dice=[];const abilities=new Set;const classOf=rf=>rf.source.kind==="class"?resolved.classes.find(c=>{var _a2;return((_a2=c.entity)==null?void 0:_a2.slug)===rf.source.slug}):void 0;const readDie=(rf,d)=>{var _a2,_b2;if(typeof d==="string")return d;if(!d)return void 0;const cls=classOf(rf);return cls?(_b2=diceColumnAt((_a2=cls.entity)==null?void 0:_a2.table,cls.level,d.column))!=null?_b2:void 0:void 0};for(const rf of resolved.features){const authored=selfEffectsOf(rf.feature).filter(e=>e.kind==="unarmed-strike");for(const e of authored){const d2=readDie(rf,e.dice);if(d2)dice.push(d2);for(const ab of(_a=e.abilities)!=null?_a:[])abilities.add(ab)}if(authored.length||rf.source.kind!=="class")continue;const slug=((_c=(_b=rf.feature.id)!=null?_b:rf.feature.name)!=null?_c:"").toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/(^-|-$)/g,"");const column=unarmedDieColumnFor(slug);if(!column)continue;const d=readDie(rf,{column});if(!d)continue;dice.push(d);abilities.add("dex")}const avg=d=>{const m=/^(\d+)d(\d+)$/i.exec(d);return m?Number(m[1])*(Number(m[2])+1)/2:1};const best=dice.sort((a,b)=>avg(b)-avg(a))[0];return{...best?{dice:best}:{},...abilities.size?{abilities:[...abilities]}:{}}}function initiativeBonus(dexMod,feats,edition){var _a,_b,_c;let bonus=dexMod;for(const f of feats){const featEdition=(_a=f.edition)!=null?_a:edition;const hasData=((_b=f.effects)!=null?_b:[]).some(e=>e.kind==="initiative-bonus");if(bareEntitySlug((_c=f.slug)!=null?_c:"")==="alert"&&featEdition==="2014"&&!hasData)bonus+=5;const initBonus=f.initiative_bonus;if(typeof initBonus==="number")bonus+=initBonus}return bonus}function speedFromRace(resolved){var _a,_b,_c;const base=(_c=(_b=(_a=resolved.race)==null?void 0:_a.speed)==null?void 0:_b.walk)!=null?_c:30;let extra=0;for(const f of resolved.feats){const bonus=f.speed_bonus;if(typeof bonus==="number")extra+=bonus}return base+extra}function collectClassFeatAbilityPoints(resolved){var _a,_b;const out={};const stripRef=ref=>ref.replace(/^\[\[/,"").replace(/\]\]$/,"");const featBySlug=new Map;for(const f of resolved.feats)featBySlug.set(f.slug,f);const sites=featPickSites(resolved.classes,poolMemberSitesOf(resolved),ci=>{var _a2,_b2,_c,_d;return(_d=(_c=(_b2=(_a2=resolved.classes)==null?void 0:_a2[ci])==null?void 0:_b2.entity)==null?void 0:_c.slug)!=null?_d:null});for(const site of sites){{const feat=featBySlug.get(stripRef(site.slug));if(!feat)continue;for(const ch of(_a=feat.choices)!=null?_a:[]){if(ch.kind!=="ability-points")continue;const raw=site.read(ch.id);if(!raw||typeof raw!=="object"||Array.isArray(raw))continue;let left=ch.points;for(const ab of ABILITY_KEYS){if(ch.pool&&!ch.pool.includes(ab))continue;const v=raw[ab];if(typeof v!=="number"||v<=0||left<=0)continue;const take=Math.min(v,ch.max_per,left);out[ab]=((_b=out[ab])!=null?_b:0)+take;left-=take}}}}return out}function computeAbilityScores(resolved,overrides){var _a,_b,_c,_d,_e,_f,_g;const out={...resolved.definition.abilities};const raceBonuses=flattenRaceAsi(resolved.race);for(const ab of ABILITY_KEYS){const b=raceBonuses[ab];if(typeof b==="number")out[ab]=((_a=out[ab])!=null?_a:0)+b}for(const asi of subraceAsi(resolved)){if(asi.ability&&typeof asi.amount==="number")out[asi.ability]=((_b=out[asi.ability])!=null?_b:0)+asi.amount}const originPoints=collectChosenAbilityPoints(resolved);for(const src of[originPoints.race,originPoints.background]){for(const ab of ABILITY_KEYS){const v=src[ab];if(typeof v==="number")out[ab]=((_c=out[ab])!=null?_c:0)+v}}const classAsi=collectClassAsiBranch(resolved);for(const ab of ABILITY_KEYS){const v=classAsi[ab];if(typeof v==="number")out[ab]=((_d=out[ab])!=null?_d:0)+v}const featPoints=collectClassFeatAbilityPoints(resolved);for(const ab of ABILITY_KEYS){const v=featPoints[ab];if(typeof v==="number")out[ab]=((_e=out[ab])!=null?_e:0)+v}for(const f of resolved.feats){const bonuses=f.ability_bonuses;if(bonuses){for(const ab of ABILITY_KEYS){const v=bonuses[ab];if(typeof v==="number")out[ab]=((_f=out[ab])!=null?_f:0)+v}}for(const[ab,v]of Object.entries(fixedFeatAbilityIncrease(f)))out[ab]=((_g=out[ab])!=null?_g:0)+v}if(overrides.scores){for(const ab of ABILITY_KEYS){const v=overrides.scores[ab];if(typeof v==="number")out[ab]=v}}for(const ab of ABILITY_KEYS){if(typeof out[ab]!=="number")out[ab]=10}return out}function normalizeArmorProf(input){var _a,_b;if(!input)return{categories:[],specific:[]};if(Array.isArray(input))return{categories:input,specific:[]};return{categories:(_a=input.categories)!=null?_a:[],specific:(_b=input.specific)!=null?_b:[]}}function normalizeWeaponToolProf(input){var _a,_b,_c;if(!input)return{categories:[],specific:[]};if(Array.isArray(input))return{categories:[],specific:input};return{categories:(_a=input.categories)!=null?_a:[],specific:((_b=input.fixed)!=null?_b:[]).concat((_c=input.specific)!=null?_c:[])}}function mergeInto(target,source){for(const c of source.categories)if(!target.categories.includes(c))target.categories.push(c);for(const s of source.specific)if(!target.specific.includes(s))target.specific.push(s)}function applyArmorWeaponOverrides(profs,overrides){var _a,_b;for(const kind of["armor","weapons"]){const ov=overrides==null?void 0:overrides[kind];if(!ov)continue;const set=profs[kind];const key=v=>proficiencyKey(kind,v);const removes=new Set(((_a=ov.remove)!=null?_a:[]).map(key));for(const v of(_b=ov.add)!=null?_b:[]){const k=key(v);if(removes.has(k))continue;const category=kind==="armor"||k==="simple"||k==="martial";const target=category?set.categories:set.specific;if(!target.some(e=>key(e)===k))target.push(category?k:v)}set.categories=set.categories.filter(e=>!removes.has(key(e)));set.specific=set.specific.filter(e=>!removes.has(key(e)))}}var ORIGIN_RANK={manual:0,equipment:1,grant:2};function composeDefenseEntries(manual,equipment,grants){const byValue=new Map;for(const raw of manual){const value=toDefenseSlug(raw);if(!value||byValue.has(value))continue;byValue.set(value,{value,label:raw.trim(),origin:"manual"})}const consider=(list,origin)=>{var _a,_b,_c,_d;for(const g of list){const value=toDefenseSlug(g.value);if(!value)continue;const existing=byValue.get(value);if(!existing){byValue.set(value,{value,label:g.value.trim(),origin,sources:[...g.sources],...g.condition?{condition:g.condition}:{},...((_a=g.items)==null?void 0:_a.length)?{items:g.items.map(it=>({...it}))}:{}});continue}if(ORIGIN_RANK[origin]>ORIGIN_RANK[existing.origin])existing.origin=origin;const sources=(_b=existing.sources)!=null?_b:existing.sources=[];for(const src of g.sources)if(!sources.includes(src))sources.push(src);if(!existing.condition&&g.condition)existing.condition=g.condition;if((_c=g.items)==null?void 0:_c.length)mergeDefenseItems((_d=existing.items)!=null?_d:existing.items=[],g.items)}};consider(equipment,"equipment");consider(grants,"grant");return[...byValue.values()]}function suppress(resolved,bucket,entries){var _a,_b,_c,_d,_e;const suppressed=new Set(((_e=(_d=(_c=(_b=(_a=resolved.definition)==null?void 0:_a.overrides)==null?void 0:_b.defenses)==null?void 0:_c[bucket])==null?void 0:_d.remove)!=null?_e:[]).map(toDefenseSlug));return entries.filter(e=>!suppressed.has(e.value))}function computeProficiencies(resolved){var _a,_b,_c,_d,_e,_f,_g;const armor={categories:[],specific:[]};const weapons={categories:[],specific:[]};const tools={categories:[],specific:[]};const languages=new Set;for(const c of resolved.classes){const p=(_a=c.entity)==null?void 0:_a.proficiencies;if(!p)continue;mergeInto(armor,normalizeArmorProf(p.armor));mergeInto(weapons,normalizeWeaponToolProf(p.weapons));mergeInto(tools,normalizeWeaponToolProf(p.tools));(_b=p.languages)==null?void 0:_b.forEach(l=>languages.add(l))}const racePr=(_c=resolved.race)==null?void 0:_c.proficiencies;if(racePr){mergeInto(armor,normalizeArmorProf(racePr.armor));mergeInto(weapons,normalizeWeaponToolProf(racePr.weapons));mergeInto(tools,normalizeWeaponToolProf(racePr.tools));(_d=racePr.languages)==null?void 0:_d.forEach(l=>languages.add(l))}const bgPr=(_e=resolved.background)==null?void 0:_e.proficiencies;if(bgPr){mergeInto(armor,normalizeArmorProf(bgPr.armor));mergeInto(weapons,normalizeWeaponToolProf(bgPr.weapons));mergeInto(tools,normalizeWeaponToolProf(bgPr.tools));(_f=bgPr.languages)==null?void 0:_f.forEach(l=>languages.add(l))}for(const f of resolved.feats){const grants=f.grants_proficiency;if(!grants)continue;mergeInto(armor,normalizeArmorProf(grants.armor));mergeInto(weapons,normalizeWeaponToolProf(grants.weapons));mergeInto(tools,normalizeWeaponToolProf(grants.tools));(_g=grants.languages)==null?void 0:_g.forEach(l=>languages.add(l))}return{armor,weapons,tools,languages:Array.from(languages).sort(),saves:[]}}function recalc(resolved,registry){var _a,_b,_c,_d,_e,_f,_g,_h,_i,_j,_k,_l,_m,_n,_o,_p,_q,_r,_s,_t,_u,_v,_w,_x,_y,_z,_A,_B,_C,_D,_E,_F,_G,_H,_I,_J,_K,_L,_M,_N,_O,_P,_Q,_R,_S,_T,_U,_V,_W,_X,_Y,_Z,__,_$;const warnings=[];const overrides=(_a=resolved.definition.overrides)!=null?_a:{};const chosenProfs=collectChosenProficiencies(resolved);const{features:effectFeatures,activeBuffs}=assembleEffectFeatures(resolved);const tableDiceFor=(src,column,level)=>{var _a2;const cls=src.kind==="class"?resolved.classes.find(c=>{var _a3;return((_a3=c.entity)==null?void 0:_a3.slug)===src.slug}):src.kind==="subclass"?resolved.classes.find(c=>{var _a3;return((_a3=c.subclass)==null?void 0:_a3.slug)===src.slug}):void 0;return cls?diceColumnAt((_a2=cls.entity)==null?void 0:_a2.table,level,column):null};const featureEffects=computeFeatureEffects(effectFeatures,{activeBuffs,levelFor:src=>resourceLevelFor(src,resolved),tableDiceFor});const profsForApply=computeProficiencies(resolved);for(const t of chosenProfs.tools){if(!profsForApply.tools.specific.includes(t))profsForApply.tools.specific.push(t)}for(const l of chosenProfs.languages){if(!profsForApply.languages.includes(l))profsForApply.languages.push(l)}for(const w of chosenProfs.weapons){if(!profsForApply.weapons.specific.includes(w))profsForApply.weapons.specific.push(w)}for(const t of featureEffects.proficiencies.tools){if(!profsForApply.tools.specific.includes(t))profsForApply.tools.specific.push(t)}for(const l of featureEffects.proficiencies.languages){if(!profsForApply.languages.includes(l))profsForApply.languages.push(l)}for(const a of featureEffects.proficiencies.armor){if(!profsForApply.armor.categories.includes(a))profsForApply.armor.categories.push(a)}for(const w of featureEffects.proficiencies.weapons){if(!profsForApply.weapons.categories.includes(w))profsForApply.weapons.categories.push(w);if(!WEAPON_CATEGORY_WORDS.has(w)&&!profsForApply.weapons.specific.includes(w)){profsForApply.weapons.specific.push(w)}}profsForApply.languages.sort();applyArmorWeaponOverrides(profsForApply,(_b=resolved.definition)==null?void 0:_b.overrides);const applied=registry?computeAppliedBonuses(resolved,profsForApply,registry,warnings):emptyAppliedBonuses();const savesInformational=applied.informational.filter(i=>i.field==="saving_throws");const spellcastingInformational=applied.informational.filter(i=>i.field==="spell_attack"||i.field==="spell_save_dc");const speedInformational=applied.informational.filter(i=>i.field.startsWith("speed."));const baseScores=computeAbilityScores(resolved,overrides);const scores={...baseScores};for(const ab of ABILITY_KEYS){const bonus=applied.ability_bonuses[ab];scores[ab]+=(typeof bonus==="number"?bonus:0)+((_c=featureEffects.ability_bonus[ab])!=null?_c:0)}for(const ab of ABILITY_KEYS){const stat=applied.ability_statics[ab];if(typeof stat==="number"&&stat>scores[ab])scores[ab]=stat}if(overrides.scores){for(const ab of ABILITY_KEYS){const o=overrides.scores[ab];if(typeof o==="number")scores[ab]=o}}const mods={str:abilityModifier(scores.str),dex:abilityModifier(scores.dex),con:abilityModifier(scores.con),int:abilityModifier(scores.int),wis:abilityModifier(scores.wis),cha:abilityModifier(scores.cha)};const totalLevel=resolved.classes.reduce((s,c)=>s+c.level,0);const proficiencyBonus=proficiencyFromLevel(totalLevel||1);const conditionEffects=computeConditionEffects(resolved.state,resolved.definition.edition,scores);const firstClass=(_e=(_d=resolved.classes[0])==null?void 0:_d.entity)!=null?_e:null;const saveProfs=new Set((_f=firstClass==null?void 0:firstClass.saving_throws)!=null?_f:[]);for(const ab of featureEffects.proficiencies.saves)saveProfs.add(ab);for(const ab of chosenProfs.saves)saveProfs.add(ab);const saves={};const saveBreakdowns={};const activeSaveBonusTerms=featureEffects.save_bonus_terms.filter(t=>{var _a2;return t.inactiveWhile==="incapacitated"?!conditionEffects.actions_disabled:t.inactiveWhile==="unconscious"?!((_a2=resolved.state.conditions)!=null?_a2:[]).includes("unconscious"):true});for(const ab of ABILITY_KEYS){const override=(_g=overrides.saves)==null?void 0:_g[ab];const prof=(_h=override==null?void 0:override.proficient)!=null?_h:saveProfs.has(ab);const featureTerms=[];for(const t of activeSaveBonusTerms){if(t.saves.length>0&&!t.saves.includes(ab))continue;const amount=Math.max(t.minimum,mods[t.ability]);const prior=featureTerms.find(x=>x.source===t.label);if(prior===void 0)featureTerms.push({source:t.label,amount});else if(amount>prior.amount)prior.amount=amount}const derivedBonus=savingThrow(scores[ab],prof,proficiencyBonus)+applied.save_bonus+featureTerms.reduce((sum,t)=>sum+t.amount,0)+conditionEffects.d20_test_penalty;const bonus=(_i=override==null?void 0:override.bonus)!=null?_i:derivedBonus;saves[ab]={bonus,proficient:prof};saveBreakdowns[ab]=[{source:ab.toUpperCase(),amount:mods[ab]},...prof?[{source:"Proficiency",amount:proficiencyBonus}]:[],...applied.save_terms.map(t=>({...t})),...featureTerms,...conditionEffects.d20_test_penalty?[{source:`Exhaustion ${conditionEffects.exhaustion_level}`,amount:conditionEffects.d20_test_penalty}]:[]]}const profSet=new Set([...resolved.definition.skills.proficient,...(_k=(_j=resolved.background)==null?void 0:_j.skill_proficiencies)!=null?_k:[],...chosenProfs.skills,...featureEffects.proficiencies.skills]);const expSet=new Set([...resolved.definition.skills.expertise,...chosenProfs.expertise,...featureEffects.proficiencies.skillExpertise]);const skills={};const skillBreakdowns={};for(const skill of ALL_SKILLS){const skillKey=skillSlugFromDisplay(skill);const ab=SKILL_ABILITY[skillSlugToAbilityLookup(skillKey)];const override=(_l=overrides.skills)==null?void 0:_l[skillKey];const tri=(_m=override==null?void 0:override.proficiency)!=null?_m:expSet.has(skillKey)?"expertise":profSet.has(skillKey)?"proficient":"none";const skillTerms=featureEffects.skill_bonus_terms.filter(t=>t.skills.includes(skillKey)).map(t=>({source:t.label,amount:Math.max(t.minimum,mods[t.ability])}));const halfProfTerms=tri!=="none"?[]:featureEffects.half_proficiency_terms.filter(t=>t.skills.length===0||t.skills.includes(skillKey)).map(t=>({source:t.label,amount:t.round==="up"?Math.ceil(proficiencyBonus/2):Math.floor(proficiencyBonus/2)}));const halfProfBest=halfProfTerms.length?halfProfTerms.reduce((best,t)=>t.amount>best.amount?t:best):null;const bonus=(_o=override==null?void 0:override.bonus)!=null?_o:skillBonus(scores[ab],tri,proficiencyBonus)+skillTerms.reduce((sum,t)=>sum+t.amount,0)+((_n=halfProfBest==null?void 0:halfProfBest.amount)!=null?_n:0)+conditionEffects.d20_test_penalty;skillBreakdowns[skillKey]=[{source:ab.toUpperCase(),amount:mods[ab]},...tri!=="none"?[{source:tri==="expertise"?"Expertise":"Proficiency",amount:proficiencyBonus*(tri==="expertise"?2:1)}]:[],...skillTerms,...halfProfBest?[halfProfBest]:[],...conditionEffects.d20_test_penalty?[{source:"Conditions",amount:conditionEffects.d20_test_penalty}]:[]];skills[skillKey]={bonus,proficiency:tri,ability:ab,...halfProfBest?{halfProficiency:{source:halfProfBest.source,amount:halfProfBest.amount}}:{}}}const passives={perception:(_q=(_p=overrides.passives)==null?void 0:_p.perception)!=null?_q:10+skills.perception.bonus,investigation:(_s=(_r=overrides.passives)==null?void 0:_r.investigation)!=null?_s:10+skills.investigation.bonus,insight:(_u=(_t=overrides.passives)==null?void 0:_t.insight)!=null?_u:10+skills.insight.bonus};const hpRolled=(_w=(_v=overrides.hp)==null?void 0:_v.rolled)!=null?_w:null;const hpModifier=(_y=(_x=overrides.hp)==null?void 0:_x.modifier)!=null?_y:null;const averageDiceSum=hitDiceAverageSum(resolved.classes);const conLevels=hpLevelCount(resolved.classes);const diceSum=hpRolled!=null?hpRolled:averageDiceSum;const diceConRaw=diceSum+mods.con*conLevels;const diceConClamped=Math.max(1,diceConRaw);const hpMaxDerived=diceConClamped+featureEffects.hp_per_level_bonus*totalLevel+(hpModifier!=null?hpModifier:0);const hpMaxAfterConditions=Math.max(0,Math.floor(hpMaxDerived*conditionEffects.hp_max_multiplier));const hpMax=(_A=(_z=overrides.hp)==null?void 0:_z.max)!=null?_A:hpMaxAfterConditions;const hpBreakdown={diceSum,diceSource:hpRolled!=null?"rolled":"average",averageDiceSum,conMod:mods.con,conLevels,clampApplied:diceConClamped!==diceConRaw,perLevelTerms:featureEffects.hp_per_level_terms.map(t=>({label:t.label,perLevel:t.value,levels:totalLevel,total:t.value*totalLevel})),modifier:hpModifier,exhaustionMultiplier:conditionEffects.hp_max_multiplier,exhaustionLevel:conditionEffects.exhaustion_level,derivedMax:hpMaxAfterConditions,override:(_C=(_B=overrides.hp)==null?void 0:_B.max)!=null?_C:null,final:hpMax};const featureAcTermsFor=hasArmor=>featureEffects.ac_terms.filter(t=>!t.requires_armor||hasArmor).map(t=>({source:t.label,amount:t.value,kind:"feature",condition:t.condition}));const sumTerms=terms=>terms.reduce((s,t)=>s+t.amount,0);const weaponAbilities=[...featureEffects.weaponAbilities];const wantsSpellcasting=resolved.features.some(rf=>selfEffectsOf(rf.feature).some(e=>e.kind==="weapon-ability"&&e.ability==="spellcasting"));if(wantsSpellcasting){let primaryCasterAbility=null;for(const c of resolved.classes){if(!c.entity)continue;const profile=resolveSpellcasting(c);if(profile){primaryCasterAbility=effectiveSpellcastingAbility(c.entity.slug,profile.ability,overrides);break}}if(primaryCasterAbility)weaponAbilities.unshift({ability:primaryCasterAbility})}let derivedEquipment=null;let acDerived;let acBreakdownDerived=[];let acInformationalDerived=[];if(registry){derivedEquipment=computeSlotsAndAttacks(resolved,mods,profsForApply,registry,warnings,proficiencyBonus,weaponAbilities,(_D=resolved.weaponMasteries)!=null?_D:[],featureEffects.attunement_set);if(derivedEquipment.equippedSlots.armor){const featTerms=featureAcTermsFor(true);acDerived=derivedEquipment.ac+sumTerms(featTerms);acBreakdownDerived=[...derivedEquipment.acBreakdown,...featTerms];acInformationalDerived=derivedEquipment.acInformational}else{const shieldBonus=derivedEquipment.acBreakdown.filter(b=>b.kind==="shield").reduce((sum,b)=>sum+b.amount,0);const{total:unarmored,terms:unarmoredTerms,shieldAllowed}=unarmoredACBreakdown(resolved,mods,warnings,shieldBonus);const additive=derivedEquipment.acBreakdown.filter(b=>b.kind==="item"||b.kind==="override"||b.kind==="shield"&&shieldAllowed);const featTerms=featureAcTermsFor(false);const additiveSum=additive.reduce((sum,b)=>sum+b.amount,0);acDerived=unarmored+additiveSum+sumTerms(featTerms);acBreakdownDerived=[...unarmoredTerms,...additive,...featTerms];acInformationalDerived=derivedEquipment.acInformational}}else{const{total,terms}=unarmoredACBreakdown(resolved,mods,warnings);const featTerms=featureAcTermsFor(false);acDerived=total+sumTerms(featTerms);acBreakdownDerived=[...terms,...featTerms]}const ac=(_E=overrides.ac)!=null?_E:acDerived;const additiveSpeed=speedFromRace(resolved)+applied.speed_bonuses.walk+featureEffects.speed_walk_bonus;const baseSpeed=Math.max(featureEffects.speed_walk_set,applied.speed_walk_set,additiveSpeed);const adjustedSpeed=baseSpeed*conditionEffects.speed_multiplier-conditionEffects.speed_reduction_ft;const conditionSpeed=conditionEffects.speed_floor_zero?0:Math.max(0,Math.floor(adjustedSpeed));const speed=(_F=overrides.speed)!=null?_F:conditionSpeed;const raceSpeed=(_I=(_H=(_G=resolved.race)==null?void 0:_G.speed)==null?void 0:_H.walk)!=null?_I:30;const speeds=buildSpeedLines({resolved,applied,features:featureEffects,conditions:conditionEffects,conditionNames:speedConditionNames(resolved.state,resolved.definition.edition),walk:{race:raceSpeed,additive:additiveSpeed,base:baseSpeed,final:conditionSpeed}});const speedBreakdown=speeds[0].terms;if(!resolved.race)warnings.push("No race resolved; speed defaulted to 30.");const initiativeAmountTerms=featureEffects.initiative_amount_terms.flatMap(term2=>{const text=resolveAmountText(term2.amount,amountBindingsFor(term2.owner,resolved,{proficiencyBonus,mods,spellcastingClasses:[]}));const n=Number(text);if(!Number.isInteger(n)){warnings.push(`${term2.label}: initiative amount "${term2.amount}" is not a number; nothing added.`);return[]}return[{source:term2.label,amount:n}]});const init=(_J=overrides.initiative)!=null?_J:initiativeBonus(mods.dex,resolved.feats,resolved.definition.edition)+featureEffects.initiative_bonus+initiativeAmountTerms.reduce((s,t)=>s+t.amount,0);const initiativeBreakdown=[{source:"DEX",amount:mods.dex},...initiativeBonus(mods.dex,resolved.feats,resolved.definition.edition)!==mods.dex?[{source:"Feats",amount:initiativeBonus(mods.dex,resolved.feats,resolved.definition.edition)-mods.dex}]:[],...featureEffects.initiative_terms.map(term2=>({source:term2.label,amount:term2.value})),...initiativeAmountTerms];const senses={darkvision:Math.max((_M=(_L=(_K=resolved.race)==null?void 0:_K.vision)==null?void 0:_L.darkvision)!=null?_M:0,featureEffects.senses.darkvision,applied.senses.darkvision),blindsight:Math.max(featureEffects.senses.blindsight,applied.senses.blindsight),tremorsense:Math.max(featureEffects.senses.tremorsense,applied.senses.tremorsense),truesight:Math.max(featureEffects.senses.truesight,applied.senses.truesight)};const spellcastingClasses=[];const slotInputs=[];const limitInputs=[];for(const c of resolved.classes){if(!c.entity)continue;const profile=resolveSpellcasting(c);if(!profile)continue;const ab=effectiveSpellcastingAbility(c.entity.slug,profile.ability,overrides);const dc=saveDC(scores[ab],proficiencyBonus)+applied.spell_save_dc;const atk=attackBonus(scores[ab],proficiencyBonus)+applied.spell_attack;spellcastingClasses.push({classSlug:c.entity.slug,className:c.entity.name,ability:ab,defaultAbility:profile.ability,saveDC:dc,attackBonus:atk,casterType:profile.casterType,preparation:profile.preparation,spellList:profile.spellList});slotInputs.push({casterType:profile.casterType,level:c.level});limitInputs.push({classSlug:c.entity.slug,level:c.level,profile,abilityScore:scores[ab]})}const spellcasting=spellcastingClasses.length>0?{ability:spellcastingClasses[0].ability,saveDC:spellcastingClasses[0].saveDC,attackBonus:spellcastingClasses[0].attackBonus}:null;const abilitySpellcasting={};for(const s of resolved.spells){const ab=s.ability;if(!ab||abilitySpellcasting[ab])continue;abilitySpellcasting[ab]={saveDC:saveDC(scores[ab],proficiencyBonus)+applied.spell_save_dc,attackBonus:attackBonus(scores[ab],proficiencyBonus)+applied.spell_attack}}const derivedSlots=deriveSpellSlots(slotInputs);const spellLimits=computeSpellLimits(limitInputs);const defenses={resistances:suppress(resolved,"resistances",composeDefenseEntries((_O=(_N=resolved.definition.defenses)==null?void 0:_N.resistances)!=null?_O:[],applied.defenses.resistances,featureEffects.resistances)),immunities:suppress(resolved,"immunities",composeDefenseEntries((_Q=(_P=resolved.definition.defenses)==null?void 0:_P.immunities)!=null?_Q:[],applied.defenses.immunities,featureEffects.immunities)),vulnerabilities:suppress(resolved,"vulnerabilities",composeDefenseEntries((_S=(_R=resolved.definition.defenses)==null?void 0:_R.vulnerabilities)!=null?_S:[],applied.defenses.vulnerabilities,featureEffects.vulnerabilities)),condition_immunities:suppress(resolved,"condition_immunities",composeDefenseEntries((_U=(_T=resolved.definition.defenses)==null?void 0:_T.condition_immunities)!=null?_U:[],applied.defenses.condition_immunities,featureEffects.condition_immunities))};const attackRows=[...(_V=derivedEquipment==null?void 0:derivedEquipment.attacks)!=null?_V:[],...buildFeatureAttackRows(resolved,mods,profsForApply,proficiencyBonus,weaponAbilities),buildUnarmedRow(mods,proficiencyBonus,resolveUnarmedStrike(resolved))];const scopeOpts={pactPicked:pactWeaponIndexes(resolved,registry)!==null};const riderBindings=owner=>amountBindingsFor(owner,resolved,{proficiencyBonus,mods,spellcastingClasses});const ownSpells=(_W=resolved.spells)!=null?_W:[];const spellDamageRiders=featureEffects.spellDamageBonuses.flatMap(r=>{const reached=new Set([...spellsReached(r.targets,ownSpells),...spellsInScope(r.scope,ownSpells,id=>pickedDamageTypes(resolved,id))]);const spells=[...new Set(ownSpells.map(s=>s.slug))].filter(slug=>reached.has(slug));if(!spells.length)return[];const{owner,targets:_targets,scope,damage_type,...rest}=r;return[{...rest,amount:resolveAmountText(r.amount,riderBindings(owner)),...damage_type&&isCanonicalDamageType(damage_type)?{damage_type}:{},...(scope==null?void 0:scope.once)?{once:true}:{},spells}]});const scopedExtra=featureEffects.scopedExtraAttacks;const rowAttacks=attackRows.map(a=>scopedExtra.length?1+Math.max(featureEffects.extraAttack,...scopedExtra.filter(x=>scopeReachesRow(x.scope,a,scopeOpts)).map(x=>x.count)):void 0);return{totalLevel,proficiencyBonus,scores,mods,saves,proficiencies:profsForApply,skills,statBreakdowns:{skills:skillBreakdowns,saves:saveBreakdowns,speed:speedBreakdown,initiative:initiativeBreakdown},passives,senses,hp:{max:hpMax,current:resolved.state.hp.current,temp:resolved.state.hp.temp},hpBreakdown,ac,speed,speeds,initiative:init,spellcasting,spellcastingClasses,abilitySpellcasting,derivedSpellSlots:derivedSlots.standard,pactMagic:derivedSlots.pact,spellLimits,warnings,defenses,acBreakdown:acBreakdownDerived,acInformational:acInformationalDerived,savesInformational,spellcastingInformational,speedInformational,attacksPerAction:Math.max(1+featureEffects.extraAttack,...rowAttacks.filter(n=>n!==void 0)),attacks:attackRows.map((a,i)=>{var _a2,_b2,_c2;const critRange=Math.min((_a2=a.critRange)!=null?_a2:20,featureEffects.critRange);const conditionalCrits=[...(_b2=a.conditionalCrits)!=null?_b2:[],...featureEffects.conditionalCrits].filter(c=>c.minRoll<critRange);const riders=[...(_c2=a.damageRiders)!=null?_c2:[],...featureEffects.damageBonuses.filter(r=>riderReachesRow(r,a,scopeOpts))].map(r=>resolveDamageRider(r,a.damageType,riderBindings));const{critRange:_ownCrit,conditionalCrits:_ownConditional,...row}=a;return{...row,toHit:a.toHit+conditionEffects.d20_test_penalty,...critRange<20?{critRange}:{},...conditionalCrits.length?{conditionalCrits}:{},...featureEffects.attackNotes.length?{attackNotes:featureEffects.attackNotes}:{},...riders.length?{damageRiders:riders}:{},...rowAttacks[i]!==void 0?{attacksPerAction:rowAttacks[i]}:{}}}),...spellDamageRiders.length?{spellDamageRiders}:{},equippedSlots:(_X=derivedEquipment==null?void 0:derivedEquipment.equippedSlots)!=null?_X:{},carriedWeight:(_Y=derivedEquipment==null?void 0:derivedEquipment.carriedWeight)!=null?_Y:0,attunementUsed:(_Z=derivedEquipment==null?void 0:derivedEquipment.attunementUsed)!=null?_Z:0,attunementLimit:(_$=derivedEquipment==null?void 0:derivedEquipment.attunementLimit)!=null?_$:(__=overrides.attunement_limit)!=null?__:Math.max(3,featureEffects.attunement_set),conditionEffects,rollModifiers:featureEffects.rollModifiers,saveOutcomes:featureEffects.saveOutcomes}}export{abilityBonusBreakdown,collectClassAsiBranch,collectClassFeatAbilityPoints,computeAbilityScores,computeProficiencies,fixedFeatAbilityIncrease,flattenRaceAsi,hitDiceAverageSum,hpLevelCount,initiativeBonus,multiclassMaxHP,parseDieSize,phbAverageForDie,recalc,resolveUnarmedStrike,riderReachesRow,scopeReachesRow,speedFromRace,unarmoredAC,unarmoredACBreakdown};