@archivist-gg/dnd5e 0.3.11 → 0.3.17

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 (192) hide show
  1. package/LICENSES/SRD.md +38 -3
  2. package/dist/armor/armor.codec.js +3 -3
  3. package/dist/armor/armor.parser.js +2 -2
  4. package/dist/armor/armor.schema.d.ts +1 -0
  5. package/dist/armor/armor.schema.js +1 -1
  6. package/dist/armor/armor.types.d.ts +2 -0
  7. package/dist/background/background.codec.js +5 -5
  8. package/dist/background/background.parser.js +4 -4
  9. package/dist/background/background.schema.js +3 -3
  10. package/dist/{chunk-XTRDCSJB.js → chunk-2JSQE3DD.js} +15 -1
  11. package/dist/chunk-2LULMQTF.js +14 -0
  12. package/dist/{chunk-MAH6DCRI.js → chunk-2UDSN6VW.js} +1 -1
  13. package/dist/chunk-3LWMFYKS.js +57 -0
  14. package/dist/{chunk-JCEV7KYN.js → chunk-3MGQFFNE.js} +1 -1
  15. package/dist/chunk-3VZZDKRA.js +1014 -0
  16. package/dist/{chunk-2DFENQIJ.js → chunk-5GKJAUMX.js} +2 -0
  17. package/dist/{chunk-2M34FLAY.js → chunk-5MXFW4O3.js} +9 -3
  18. package/dist/{chunk-4DOMDEBZ.js → chunk-6EI737IO.js} +1 -1
  19. package/dist/{chunk-G247QXWW.js → chunk-7ATNGKBS.js} +1 -1
  20. package/dist/{chunk-XY6X2APM.js → chunk-7Q2VPKCD.js} +17 -0
  21. package/dist/{chunk-T2SNEJOE.js → chunk-7QN7XSAK.js} +1 -1
  22. package/dist/{chunk-DNAJRMNN.js → chunk-A54HHCWW.js} +6 -7
  23. package/dist/{chunk-7YU4NPKR.js → chunk-AZRGFUSR.js} +1 -1
  24. package/dist/{chunk-PP2UHLBA.js → chunk-B3DP42OM.js} +5 -0
  25. package/dist/chunk-CM5CWO4K.js +735 -0
  26. package/dist/{chunk-MQ747UCR.js → chunk-DOXSFYLH.js} +70 -2
  27. package/dist/chunk-EJP263OP.js +186 -0
  28. package/dist/{chunk-SMLXZUBH.js → chunk-EYX4JMAU.js} +4 -1
  29. package/dist/{chunk-V6LJFP4R.js → chunk-FANQVQ3D.js} +2 -2
  30. package/dist/{chunk-AW3EHF3L.js → chunk-FC4IGH5Y.js} +1 -1
  31. package/dist/{chunk-23LZLBJK.js → chunk-G6MHJDVT.js} +6 -2
  32. package/dist/{chunk-JANNRGJC.js → chunk-G6PBI2BU.js} +1 -1
  33. package/dist/chunk-H5PTKYXL.js +101 -0
  34. package/dist/{chunk-LWFTHJIE.js → chunk-HHBD4SQ6.js} +1 -1
  35. package/dist/{chunk-JC5UNIVM.js → chunk-HS6FIOLP.js} +2 -0
  36. package/dist/chunk-HTYMW5CH.js +228 -0
  37. package/dist/chunk-IHE6KVC3.js +13 -0
  38. package/dist/{chunk-QHMWA3SZ.js → chunk-JCMUVZIK.js} +1 -1
  39. package/dist/{chunk-V373TRJE.js → chunk-JSM6JFZR.js} +198 -125
  40. package/dist/{chunk-LDDCNPHD.js → chunk-K5NJBTE2.js} +1 -1
  41. package/dist/chunk-KR6JF3BF.js +14 -0
  42. package/dist/{chunk-4ISR76DH.js → chunk-KSTV7J2U.js} +9 -3
  43. package/dist/chunk-LBEXLN6I.js +91 -0
  44. package/dist/{chunk-BLRW2UU6.js → chunk-LF5AGJA4.js} +2 -2
  45. package/dist/{chunk-UBBKSYBY.js → chunk-LHZXYFBU.js} +30 -1
  46. package/dist/{chunk-BIA32MQ5.js → chunk-MBX25B6D.js} +1 -1
  47. package/dist/{chunk-R2ZV233X.js → chunk-MYY2C5MB.js} +3 -3
  48. package/dist/{chunk-J77CKYV3.js → chunk-OFCSP6MT.js} +1 -1
  49. package/dist/{chunk-2INMRR3Q.js → chunk-ONTGZR5T.js} +326 -149
  50. package/dist/{chunk-MWCCGPG3.js → chunk-OOSRUJBI.js} +3 -2
  51. package/dist/{chunk-U3BABVJF.js → chunk-PKX6TGRE.js} +2 -2
  52. package/dist/{chunk-PJMG5XV3.js → chunk-PQZ4LM4Z.js} +1 -1
  53. package/dist/chunk-PXVNAY7T.js +84 -0
  54. package/dist/chunk-QH36K2PU.js +158 -0
  55. package/dist/{chunk-R747YKS7.js → chunk-QZSWN2KT.js} +1 -1
  56. package/dist/{chunk-CHUALUIX.js → chunk-RYLXAYIQ.js} +1 -1
  57. package/dist/{chunk-GFZ7PITJ.js → chunk-S3YUXDSC.js} +6 -1
  58. package/dist/{chunk-PZCE7DJM.js → chunk-T6QIF5XR.js} +31 -1
  59. package/dist/{chunk-CBEKVAX4.js → chunk-TULQ4FFX.js} +41 -13
  60. package/dist/{chunk-S56D6B6C.js → chunk-UUBJCNQU.js} +12 -3
  61. package/dist/{chunk-5N2GW72F.js → chunk-UZXG6QSY.js} +2 -1
  62. package/dist/{chunk-4XTNPNQB.js → chunk-VPYBK2MG.js} +1 -1
  63. package/dist/{chunk-3HX5VLWP.js → chunk-VRV3NNTA.js} +2 -2
  64. package/dist/{chunk-HZA7OE7N.js → chunk-XCFC7LGF.js} +2 -1
  65. package/dist/{chunk-BL3VELKP.js → chunk-Y5VVP73C.js} +1 -1
  66. package/dist/{chunk-PI4LLJG4.js → chunk-YD2VAHA6.js} +2 -2
  67. package/dist/{chunk-UIRMA5KM.js → chunk-YDGMBMYI.js} +1 -1
  68. package/dist/{chunk-NWDF5HG3.js → chunk-YKL6SHRJ.js} +1 -1
  69. package/dist/{chunk-6X4KUDMU.js → chunk-ZCTUYGNV.js} +7 -2
  70. package/dist/chunk-ZUQW5VBZ.js +89 -0
  71. package/dist/class/class.codec.js +7 -7
  72. package/dist/class/class.parser.js +6 -6
  73. package/dist/class/class.schema.d.ts +18 -0
  74. package/dist/class/class.schema.js +5 -5
  75. package/dist/class/class.standard-array.d.ts +16 -0
  76. package/dist/class/class.standard-array.js +20 -0
  77. package/dist/class/class.types.d.ts +3 -0
  78. package/dist/dnd/amount-text.d.ts +38 -0
  79. package/dist/dnd/amount-text.js +13 -0
  80. package/dist/dnd/resource-words.d.ts +4 -0
  81. package/dist/dnd/resource-words.js +30 -0
  82. package/dist/entities/base-item-resolver.js +2 -2
  83. package/dist/entities/slug.d.ts +18 -8
  84. package/dist/entities/slug.js +3 -1
  85. package/dist/feat/feat.codec.js +5 -5
  86. package/dist/feat/feat.parser.js +4 -4
  87. package/dist/feat/feat.schema.d.ts +41 -3
  88. package/dist/feat/feat.schema.js +3 -3
  89. package/dist/index.js +7513 -4177
  90. package/dist/item/item.actions-map.d.ts +40 -5
  91. package/dist/item/item.actions-map.js +5 -84
  92. package/dist/item/item.attunement.js +3 -9
  93. package/dist/item/item.bonuses.js +5 -2
  94. package/dist/item/item.codec.js +3 -3
  95. package/dist/item/item.conditions.js +4 -1
  96. package/dist/item/item.conditions.types.d.ts +4 -0
  97. package/dist/item/item.cost.d.ts +3 -0
  98. package/dist/item/item.cost.js +29 -0
  99. package/dist/item/item.icon.d.ts +15 -0
  100. package/dist/item/item.icon.js +211 -0
  101. package/dist/item/item.parser.js +2 -2
  102. package/dist/item/item.schema.d.ts +16 -1
  103. package/dist/item/item.schema.js +3 -1
  104. package/dist/item/item.types.d.ts +9 -2
  105. package/dist/monster/monster.parser.js +5 -5
  106. package/dist/monster/monster.schema.js +4 -4
  107. package/dist/optional-feature/optional-feature.codec.js +5 -4
  108. package/dist/optional-feature/optional-feature.parser.js +4 -3
  109. package/dist/optional-feature/optional-feature.schema.d.ts +255 -3
  110. package/dist/optional-feature/optional-feature.schema.js +7 -2
  111. package/dist/pc/pc.additional-spells.js +3 -3
  112. package/dist/pc/pc.amount-bindings.d.ts +32 -0
  113. package/dist/pc/pc.amount-bindings.js +23 -0
  114. package/dist/pc/pc.asi-flatten.d.ts +62 -1
  115. package/dist/pc/pc.asi-flatten.js +16 -0
  116. package/dist/pc/pc.conditions.js +1 -1
  117. package/dist/pc/pc.containment.d.ts +45 -0
  118. package/dist/pc/pc.containment.js +24 -0
  119. package/dist/pc/pc.decision-engine.d.ts +24 -3
  120. package/dist/pc/pc.decision-engine.js +26 -16
  121. package/dist/pc/pc.entry-overrides.d.ts +79 -0
  122. package/dist/pc/pc.entry-overrides.js +40 -0
  123. package/dist/pc/pc.equipment.d.ts +2 -2
  124. package/dist/pc/pc.equipment.js +19 -7
  125. package/dist/pc/pc.feature-effects.d.ts +12 -0
  126. package/dist/pc/pc.feature-effects.js +2 -2
  127. package/dist/pc/pc.infusions.d.ts +228 -0
  128. package/dist/pc/pc.infusions.js +64 -0
  129. package/dist/pc/pc.member-choices.d.ts +90 -0
  130. package/dist/pc/pc.member-choices.js +32 -0
  131. package/dist/pc/pc.parser.js +18 -1
  132. package/dist/pc/pc.pools.d.ts +8 -1
  133. package/dist/pc/pc.pools.js +13 -3
  134. package/dist/pc/pc.proficiencies.js +23 -15
  135. package/dist/pc/pc.proficiency-query.js +6 -0
  136. package/dist/pc/pc.recalc.d.ts +39 -36
  137. package/dist/pc/pc.recalc.js +115 -70
  138. package/dist/pc/pc.resolver.d.ts +2 -1
  139. package/dist/pc/pc.resolver.js +22 -14
  140. package/dist/pc/pc.resource-seed.js +1 -1
  141. package/dist/pc/pc.resources.d.ts +6 -1
  142. package/dist/pc/pc.resources.js +3 -1
  143. package/dist/pc/pc.rest.d.ts +21 -1
  144. package/dist/pc/pc.rest.js +52 -19
  145. package/dist/pc/pc.schema.d.ts +43 -2
  146. package/dist/pc/pc.schema.js +1 -1
  147. package/dist/pc/pc.slotting.d.ts +36 -3
  148. package/dist/pc/pc.slotting.js +13 -5
  149. package/dist/pc/pc.tool-picks.d.ts +51 -0
  150. package/dist/pc/pc.tool-picks.js +18 -0
  151. package/dist/pc/pc.types.d.ts +115 -14
  152. package/dist/pc/pc.weapon-grant.d.ts +15 -0
  153. package/dist/pc/pool-layout.d.ts +8 -0
  154. package/dist/pc/pool-layout.js +5 -3
  155. package/dist/pc/resource-equivalents.d.ts +44 -0
  156. package/dist/pc/spell-source.js +4 -9
  157. package/dist/race/race.codec.js +6 -6
  158. package/dist/race/race.parser.js +5 -5
  159. package/dist/race/race.schema.js +4 -4
  160. package/dist/schemas/attack-schema.d.ts +1 -1
  161. package/dist/schemas/choice-schema.js +2 -2
  162. package/dist/schemas/feature-effect-schema.d.ts +41 -3
  163. package/dist/schemas/feature-effect-schema.js +1 -1
  164. package/dist/schemas/feature-schema.js +3 -3
  165. package/dist/schemas/selection-pool-schema.d.ts +10 -0
  166. package/dist/schemas/selection-pool-schema.js +1 -1
  167. package/dist/spell/spell.codec.js +2 -2
  168. package/dist/spell/spell.parser.d.ts +6 -1
  169. package/dist/spell/spell.parser.js +5 -3
  170. package/dist/spell/spell.types.d.ts +10 -0
  171. package/dist/srd/retired-items.d.ts +14 -0
  172. package/dist/srd/retired-items.js +11 -0
  173. package/dist/subclass/subclass.codec.js +7 -7
  174. package/dist/subclass/subclass.parser.js +6 -6
  175. package/dist/subclass/subclass.schema.d.ts +10 -0
  176. package/dist/subclass/subclass.schema.js +5 -5
  177. package/dist/types/choice.d.ts +13 -0
  178. package/dist/types/equipment-grant.d.ts +18 -1
  179. package/dist/types/equipment-grant.js +12 -0
  180. package/dist/types/feature-effect.d.ts +12 -1
  181. package/dist/types/optional-feature.types.d.ts +84 -1
  182. package/dist/types/selection-pool.d.ts +18 -3
  183. package/dist/weapon/weapon.classify.d.ts +10 -8
  184. package/dist/weapon/weapon.classify.js +2 -2
  185. package/dist/weapon/weapon.codec.js +3 -3
  186. package/dist/weapon/weapon.parser.js +2 -2
  187. package/dist/weapon/weapon.schema.d.ts +1 -0
  188. package/dist/weapon/weapon.schema.js +1 -1
  189. package/dist/weapon/weapon.types.d.ts +2 -0
  190. package/package.json +1 -1
  191. package/dist/chunk-O4SRD3J5.js +0 -165
  192. package/dist/chunk-WXWPK3LI.js +0 -55
@@ -7,15 +7,20 @@ function bareEntitySlug(slug) {
7
7
  const p = slug.split("_");
8
8
  return p.length >= 3 ? p.slice(2).join("_") : p[p.length - 1];
9
9
  }
10
+ var STORED_SLUG = /^[a-z0-9-]+(?:_[a-z0-9-]+)+$/;
11
+ function isStoredSlug(tail) {
12
+ return STORED_SLUG.test(tail);
13
+ }
10
14
  function wikilinkTailSlug(link) {
11
15
  var _a;
12
16
  const inner = link.replace(/^\[\[/, "").replace(/\]\]$/, "");
13
- const tail = (_a = inner.split("/").pop()) != null ? _a : inner;
14
- return slugify(tail);
17
+ const tail = ((_a = inner.split("/").pop()) != null ? _a : inner).trim();
18
+ return isStoredSlug(tail) ? bareEntitySlug(tail) : slugify(tail);
15
19
  }
16
20
 
17
21
  export {
18
22
  slugify,
19
23
  bareEntitySlug,
24
+ isStoredSlug,
20
25
  wikilinkTailSlug
21
26
  };
@@ -0,0 +1,89 @@
1
+ // src/item/item.actions-map.ts
2
+ var ITEM_ACTIONS = {
3
+ // Wands and rods
4
+ "wand-of-fireballs": { cost: "action", range: "150 ft.", max_charges: 7, recovery: { amount: "1d6+1", reset: "dawn" } },
5
+ "wand-of-magic-missiles": { cost: "action", range: "120 ft.", max_charges: 7, recovery: { amount: "1d6+1", reset: "dawn" } },
6
+ "wand-of-lightning-bolts": { cost: "action", range: "100 ft.", max_charges: 7, recovery: { amount: "1d6+1", reset: "dawn" } },
7
+ "wand-of-paralysis": { cost: "action", range: "60 ft.", max_charges: 7, recovery: { amount: "1d6+1", reset: "dawn" } },
8
+ "wand-of-fear": { cost: "action", range: "Self", max_charges: 7, recovery: { amount: "1d6+1", reset: "dawn" } },
9
+ "wand-of-binding": { cost: "action", range: "Self", max_charges: 7, recovery: { amount: "1d6+1", reset: "dawn" } },
10
+ "wand-of-secrets": { cost: "action", range: "30 ft.", max_charges: 3, recovery: { amount: "1d3", reset: "dawn" } },
11
+ "wand-of-web": { cost: "action", range: "60 ft.", max_charges: 7, recovery: { amount: "1d6+1", reset: "dawn" } },
12
+ "wand-of-wonder": { cost: "action", range: "120 ft.", max_charges: 7, recovery: { amount: "1d6+1", reset: "dawn" } },
13
+ // Activatable wondrous items
14
+ "boots-of-speed": { cost: "bonus-action", range: "Self", max_charges: 1, recovery: { amount: "1", reset: "long" } },
15
+ "boots-of-levitation": { cost: "action", range: "Self" },
16
+ "boots-of-striding-and-springing": { cost: "free", range: "Self" },
17
+ "broom-of-flying": { cost: "action", range: "Touch" },
18
+ "cloak-of-displacement": { cost: "free", range: "Self" },
19
+ "cloak-of-the-bat": { cost: "action", range: "Self", max_charges: 1, recovery: { amount: "1", reset: "long" } },
20
+ "decanter-of-endless-water": { cost: "action", range: "Touch" },
21
+ "drum-of-panic": { cost: "action", range: "120 ft.", max_charges: 1, recovery: { amount: "1", reset: "long" } },
22
+ "eyes-of-charming": { cost: "action", range: "30 ft.", max_charges: 3, recovery: { amount: "3", reset: "dawn" } },
23
+ // Rings
24
+ "ring-of-three-wishes": { cost: "action", range: "Self", max_charges: 3, recovery: { amount: "0", reset: "special" } },
25
+ "ring-of-shooting-stars": { cost: "action", range: "60 ft.", max_charges: 6, recovery: { amount: "1d6", reset: "dawn" } },
26
+ "ring-of-the-ram": { cost: "action", range: "60 ft.", max_charges: 3, recovery: { amount: "1d3", reset: "dawn" } },
27
+ "ring-of-spell-storing": { cost: "action", range: "Self", max_charges: 5 },
28
+ "ring-of-animal-influence": { cost: "action", range: "Self", max_charges: 3, recovery: { amount: "1d3", reset: "dawn" } },
29
+ "ring-of-elemental-command": { cost: "action", range: "Self", max_charges: 5, recovery: { amount: "1d4+1", reset: "dawn" } },
30
+ "ring-of-evasion": { cost: "reaction", range: "Self", max_charges: 3, recovery: { amount: "1d3", reset: "dawn" } },
31
+ // Necklaces
32
+ "necklace-of-fireballs": { cost: "action", range: "60 ft.", max_charges: 9 },
33
+ // Gems
34
+ "gem-of-brightness": { cost: "action", range: "60 ft.", max_charges: 50 },
35
+ "gem-of-seeing": { cost: "action", range: "Self", max_charges: 3, recovery: { amount: "1d3", reset: "dawn" } },
36
+ // Helms
37
+ "helm-of-teleportation": { cost: "action", range: "Self", max_charges: 3, recovery: { amount: "1d3", reset: "dawn" } },
38
+ // Medallions
39
+ "medallion-of-thoughts": { cost: "action", range: "30 ft.", max_charges: 3, recovery: { amount: "1d3", reset: "dawn" } },
40
+ // Pipes
41
+ "pipes-of-haunting": { cost: "action", range: "30 ft.", max_charges: 3, recovery: { amount: "1d3", reset: "dawn" } },
42
+ "pipes-of-the-sewers": { cost: "action", range: "Self", max_charges: 3, recovery: { amount: "1d3", reset: "dawn" } },
43
+ // Cubes / chimes
44
+ "cube-of-force": { cost: "action", range: "Self", max_charges: 36, recovery: { amount: "1d20", reset: "dawn" } },
45
+ "chime-of-opening": { cost: "action", range: "120 ft.", max_charges: 10 },
46
+ // Magic weapons with activation actions (surface in items table only via override; weapons table is primary)
47
+ "sun-blade": { cost: "free", range: "Self" },
48
+ // Potions / consumables · consumed on use (user ruling 2026-09-24): using one spends the entry's quantity, so they
49
+ // carry no charges or recovery. 2024 healing potions are a Bonus Action to drink/administer (the type=potion
50
+ // default covers uncurated ones).
51
+ "potion-of-healing": { cost: "bonus-action", range: "Self", consumed: true },
52
+ "potion-of-greater-healing": { cost: "bonus-action", range: "Self", consumed: true },
53
+ "potion-of-superior-healing": { cost: "bonus-action", range: "Self", consumed: true },
54
+ "potion-of-supreme-healing": { cost: "bonus-action", range: "Self", consumed: true },
55
+ "alchemists-fire": { cost: "action", range: "20 ft.", consumed: true },
56
+ "holy-water": { cost: "action", range: "20 ft.", consumed: true },
57
+ // Oils are APPLIED (minutes), not drunk: curated to "action" so the blanket
58
+ // type=potion → bonus-action default never mislabels these mis-typed items.
59
+ "oil-of-sharpness": { cost: "action", range: "Self", consumed: true },
60
+ "oil-of-etherealness": { cost: "action", range: "Self", consumed: true },
61
+ "oil-of-slipperiness": { cost: "action", range: "Self", consumed: true },
62
+ "dust-of-disappearance": { cost: "action", range: "Self", consumed: true }
63
+ };
64
+ function findItemAction(slug) {
65
+ if (slug in ITEM_ACTIONS) return ITEM_ACTIONS[slug];
66
+ const p = slug.split("_");
67
+ const bare = p.length >= 3 ? p.slice(2).join("_") : p[p.length - 1];
68
+ return bare === slug ? void 0 : ITEM_ACTIONS[bare];
69
+ }
70
+ function resolveItemAction(slug, entry, itemType, opts) {
71
+ var _a, _b, _c, _d, _e, _f;
72
+ const curated = (_a = findItemAction(slug)) != null ? _a : null;
73
+ const override = (opts == null ? void 0 : opts.weaponLike) ? void 0 : entry.overrides;
74
+ const overrideCost = override == null ? void 0 : override.action;
75
+ const overrideRange = override == null ? void 0 : override.range;
76
+ const viewEntity = (_b = opts == null ? void 0 : opts.view) == null ? void 0 : _b.entity;
77
+ const viewAction = viewEntity == null ? void 0 : viewEntity.action;
78
+ const viewRange = viewEntity == null ? void 0 : viewEntity.range;
79
+ const typeDefault = itemType === "potion" ? "bonus-action" : itemType === "scroll" ? (_c = opts == null ? void 0 : opts.spellCost) != null ? _c : "action" : void 0;
80
+ const cost = (_e = (_d = overrideCost != null ? overrideCost : viewAction) != null ? _d : curated == null ? void 0 : curated.cost) != null ? _e : typeDefault;
81
+ if (!cost) return null;
82
+ return { cost, range: (_f = overrideRange != null ? overrideRange : viewRange) != null ? _f : curated == null ? void 0 : curated.range };
83
+ }
84
+
85
+ export {
86
+ ITEM_ACTIONS,
87
+ findItemAction,
88
+ resolveItemAction
89
+ };
@@ -1,17 +1,17 @@
1
1
  import {
2
2
  classCodec
3
- } from "../chunk-BIA32MQ5.js";
4
- import "../chunk-NWDF5HG3.js";
3
+ } from "../chunk-MBX25B6D.js";
4
+ import "../chunk-YKL6SHRJ.js";
5
5
  import "../chunk-4U55VNC7.js";
6
- import "../chunk-S56D6B6C.js";
7
- import "../chunk-23LZLBJK.js";
6
+ import "../chunk-UUBJCNQU.js";
7
+ import "../chunk-G6MHJDVT.js";
8
8
  import "../chunk-CJYCVNW2.js";
9
- import "../chunk-PI4LLJG4.js";
9
+ import "../chunk-YD2VAHA6.js";
10
10
  import "../chunk-WYGD2UGN.js";
11
11
  import "../chunk-ZJXSXVFP.js";
12
12
  import "../chunk-IN4M4X7P.js";
13
- import "../chunk-2M34FLAY.js";
14
- import "../chunk-XTRDCSJB.js";
13
+ import "../chunk-5MXFW4O3.js";
14
+ import "../chunk-2JSQE3DD.js";
15
15
  import "../chunk-UA5KS2PL.js";
16
16
  export {
17
17
  classCodec
@@ -1,16 +1,16 @@
1
1
  import {
2
2
  parseClass
3
- } from "../chunk-NWDF5HG3.js";
3
+ } from "../chunk-YKL6SHRJ.js";
4
4
  import "../chunk-4U55VNC7.js";
5
- import "../chunk-S56D6B6C.js";
6
- import "../chunk-23LZLBJK.js";
5
+ import "../chunk-UUBJCNQU.js";
6
+ import "../chunk-G6MHJDVT.js";
7
7
  import "../chunk-CJYCVNW2.js";
8
- import "../chunk-PI4LLJG4.js";
8
+ import "../chunk-YD2VAHA6.js";
9
9
  import "../chunk-WYGD2UGN.js";
10
10
  import "../chunk-ZJXSXVFP.js";
11
11
  import "../chunk-IN4M4X7P.js";
12
- import "../chunk-2M34FLAY.js";
13
- import "../chunk-XTRDCSJB.js";
12
+ import "../chunk-5MXFW4O3.js";
13
+ import "../chunk-2JSQE3DD.js";
14
14
  import "../chunk-UA5KS2PL.js";
15
15
  export {
16
16
  parseClass
@@ -22,6 +22,14 @@ export declare const classEntitySchema: z.ZodObject<{
22
22
  wis: "wis";
23
23
  cha: "cha";
24
24
  }>>;
25
+ standard_array: z.ZodOptional<z.ZodObject<{
26
+ str: z.ZodNumber;
27
+ dex: z.ZodNumber;
28
+ con: z.ZodNumber;
29
+ int: z.ZodNumber;
30
+ wis: z.ZodNumber;
31
+ cha: z.ZodNumber;
32
+ }, z.core.$strict>>;
25
33
  saving_throws: z.ZodArray<z.ZodEnum<{
26
34
  str: "str";
27
35
  dex: "dex";
@@ -191,8 +199,18 @@ export declare const classEntitySchema: z.ZodObject<{
191
199
  }, z.core.$strip>;
192
200
  count: z.ZodObject<{
193
201
  column: z.ZodString;
202
+ label: z.ZodOptional<z.ZodString>;
194
203
  }, z.core.$strip>;
195
204
  replaceable: z.ZodOptional<z.ZodBoolean>;
205
+ active: z.ZodOptional<z.ZodObject<{
206
+ column: z.ZodString;
207
+ label: z.ZodString;
208
+ verb: z.ZodString;
209
+ counter_label: z.ZodOptional<z.ZodString>;
210
+ create_label: z.ZodOptional<z.ZodString>;
211
+ create_verb: z.ZodOptional<z.ZodString>;
212
+ }, z.core.$strip>>;
213
+ head_resource: z.ZodOptional<z.ZodString>;
196
214
  }, z.core.$strip>>>;
197
215
  pool_grants: z.ZodOptional<z.ZodArray<z.ZodObject<{
198
216
  pool: z.ZodString;
@@ -1,14 +1,14 @@
1
1
  import {
2
2
  classEntitySchema
3
- } from "../chunk-S56D6B6C.js";
4
- import "../chunk-23LZLBJK.js";
3
+ } from "../chunk-UUBJCNQU.js";
4
+ import "../chunk-G6MHJDVT.js";
5
5
  import "../chunk-CJYCVNW2.js";
6
- import "../chunk-PI4LLJG4.js";
6
+ import "../chunk-YD2VAHA6.js";
7
7
  import "../chunk-WYGD2UGN.js";
8
8
  import "../chunk-ZJXSXVFP.js";
9
9
  import "../chunk-IN4M4X7P.js";
10
- import "../chunk-2M34FLAY.js";
11
- import "../chunk-XTRDCSJB.js";
10
+ import "../chunk-5MXFW4O3.js";
11
+ import "../chunk-2JSQE3DD.js";
12
12
  import "../chunk-UA5KS2PL.js";
13
13
  export {
14
14
  classEntitySchema
@@ -0,0 +1,16 @@
1
+ /**
2
+ * D2b-A (A-1, user pick A) · the class's recommended Standard Array, which the Builder's Abilities step suggests.
3
+ */
4
+ import type { Ability } from "@archivist-gg/dnd5e/types/choice";
5
+ import type { ClassEntity } from "./class.types.js";
6
+ /** Structural subset of the registry this reads. */
7
+ export interface StandardArrayRegistry {
8
+ search(query: string, entityType: string, limit: number): Array<{
9
+ slug: string;
10
+ data: Record<string, unknown>;
11
+ }>;
12
+ }
13
+ /** The class's own `standard_array`; else, for a 2024 class that carries none (a book class imported before the table
14
+ * was data), the table of its 2024 twin in the registry (the same bare slug, e.g. the SRD 2024 Fighter for the PHB
15
+ * 2024 Fighter). Null for a 2014 class and for a class with no 2024 twin (homebrew): the Builder then suggests nothing. */
16
+ export declare function standardArrayFor(entity: Pick<ClassEntity, "slug" | "edition" | "standard_array">, registry: StandardArrayRegistry | null | undefined): Record<Ability, number> | null;
@@ -0,0 +1,20 @@
1
+ import {
2
+ bareEntitySlug
3
+ } from "../chunk-ZCTUYGNV.js";
4
+
5
+ // src/class/class.standard-array.ts
6
+ var isArray = (v) => !!v && typeof v === "object" && ["str", "dex", "con", "int", "wis", "cha"].every((k) => typeof v[k] === "number");
7
+ function standardArrayFor(entity, registry) {
8
+ if (isArray(entity.standard_array)) return entity.standard_array;
9
+ if (entity.edition !== "2024" || !registry) return null;
10
+ const bare = bareEntitySlug(entity.slug);
11
+ for (const e of registry.search("", "class", Number.POSITIVE_INFINITY)) {
12
+ if (e.slug === entity.slug || bareEntitySlug(e.slug) !== bare) continue;
13
+ const d = e.data;
14
+ if (d.edition === "2024" && isArray(d.standard_array)) return d.standard_array;
15
+ }
16
+ return null;
17
+ }
18
+ export {
19
+ standardArrayFor
20
+ };
@@ -69,6 +69,9 @@ export interface ClassEntity {
69
69
  description: string;
70
70
  hit_die: string;
71
71
  primary_abilities: Ability[];
72
+ /** D2b-A (A-1): the recommended Standard Array for the class, one score per ability (SRD 5.2 "Standard Array by
73
+ * Class"). Absent on 2014 classes and homebrew; the Builder then suggests nothing. */
74
+ standard_array?: Record<Ability, number>;
72
75
  saving_throws: Ability[];
73
76
  proficiencies: ClassProficiencies;
74
77
  skill_choices: SkillChoices;
@@ -0,0 +1,38 @@
1
+ /**
2
+ * D2b-A · an AMOUNT that names a modifier prints the number (design §1.2 A, user rulings 2026-09-27).
3
+ *
4
+ * An effect amount, a rider amount or a save DC formula is written in the book's words ("1d8 plus your Wisdom
5
+ * modifier", "your spell save DC") or with a `{token}` ("2d4 + {spell_mod}"). Nothing rendered it as a number: the
6
+ * resource DSL (`resource-formula.ts`) has no dice production and no spellcasting idents. This module reads both at
7
+ * READ time, so existing notes and homebrew need no re-import:
8
+ * 1. `normalizeAmountPhrases` turns the closed phrase table below into tokens;
9
+ * 2. `resolveAmountText` substitutes each `{ident}` with its number and folds: a pure numeric result is evaluated by
10
+ * the resource DSL (so `floor`, `max`, `ceil` keep working) and a trailing "(minimum of N)" is applied;
11
+ * `<dice> +/- <numbers>` folds to one roll ("1d8+3"); anything else keeps its words with the numbers in place
12
+ * ("one roll of your Martial Arts die + 3").
13
+ * The phrase table is the ONE place the book's English is read; an unmapped phrase stays as written.
14
+ */
15
+ import { type FormulaBindings } from "./resource-formula.js";
16
+ /** The DSL bindings plus the owner's spellcasting modifier and save DC (absent when the owner casts no spells). */
17
+ export interface AmountBindings extends FormulaBindings {
18
+ spell_mod?: number;
19
+ spell_dc?: number;
20
+ }
21
+ /** The book phrases of `text` as tokens, "plus" as "+"; text with no mapped phrase comes back unchanged. */
22
+ export declare function normalizeAmountPhrases(text: string): string;
23
+ /**
24
+ * The amount as the sheet prints it: the phrases and tokens of `text` resolved against `b`. A pure number is
25
+ * evaluated ("13"); a roll plus numbers folds ("1d8+3"); other words keep their place with the numbers in ("the roll + 2
26
+ * (minimum of 1)"). An UNBOUND token prints its short label when the note wrote the token, and a book phrase whose
27
+ * token is unbound keeps the note's own words. Text with no phrase and no token comes back unchanged.
28
+ */
29
+ export declare function resolveAmountText(text: string, b: AmountBindings): string;
30
+ /** The leading dice roll of a resolved amount ("1d8+3" of "1d8+3 (minimum of 1)"), which the sheet makes rollable; null
31
+ * when the amount does not open with a roll. */
32
+ export declare function diceRollOf(resolved: string): string | null;
33
+ /** The leading roll of `text` as the RAW characters it spans (`raw`, which the caller cuts the text by) and as a notation
34
+ * with no spaces (`notation`, which the roller reads): "2d4 + 2 more" is { raw: "2d4 + 2", notation: "2d4+2" }. */
35
+ export declare function diceRollPrefix(text: string): {
36
+ raw: string;
37
+ notation: string;
38
+ } | null;
@@ -0,0 +1,13 @@
1
+ import {
2
+ diceRollOf,
3
+ diceRollPrefix,
4
+ normalizeAmountPhrases,
5
+ resolveAmountText
6
+ } from "../chunk-QH36K2PU.js";
7
+ import "../chunk-EVMUJYUD.js";
8
+ export {
9
+ diceRollOf,
10
+ diceRollPrefix,
11
+ normalizeAmountPhrases,
12
+ resolveAmountText
13
+ };
@@ -0,0 +1,4 @@
1
+ /** The resource's name worded for `amount`: the last word singular for one, plural otherwise, when it is a count noun. */
2
+ export declare function resourceCountWord(name: string, amount: number): string;
3
+ /** "<amount> <name worded for it>" ("1 Superiority Die"). */
4
+ export declare function countedResource(amount: number, name: string): string;
@@ -0,0 +1,30 @@
1
+ // src/dnd/resource-words.ts
2
+ var COUNT_NOUNS = [
3
+ ["Die", "Dice"],
4
+ ["Point", "Points"],
5
+ ["Use", "Uses"],
6
+ ["Seal", "Seals"],
7
+ ["Rage", "Rages"],
8
+ ["Cast", "Casts"],
9
+ ["Casting", "Castings"],
10
+ ["Scroll", "Scrolls"],
11
+ ["Charge", "Charges"],
12
+ ["Token", "Tokens"],
13
+ ["Slot", "Slots"]
14
+ ];
15
+ var BY_WORD = new Map(
16
+ COUNT_NOUNS.flatMap((pair) => [[pair[0], pair], [pair[1], pair]])
17
+ );
18
+ function resourceCountWord(name, amount) {
19
+ const at = name.lastIndexOf(" ") + 1;
20
+ const pair = BY_WORD.get(name.slice(at));
21
+ if (!pair) return name;
22
+ return name.slice(0, at) + (amount === 1 ? pair[0] : pair[1]);
23
+ }
24
+ function countedResource(amount, name) {
25
+ return `${amount} ${resourceCountWord(name, amount)}`;
26
+ }
27
+ export {
28
+ countedResource,
29
+ resourceCountWord
30
+ };
@@ -2,8 +2,8 @@ import {
2
2
  resolveBaseItem,
3
3
  resolveBaseItemOfType,
4
4
  vaultPathToSlug
5
- } from "../chunk-WXWPK3LI.js";
6
- import "../chunk-6X4KUDMU.js";
5
+ } from "../chunk-CM5CWO4K.js";
6
+ import "../chunk-ZCTUYGNV.js";
7
7
  export {
8
8
  resolveBaseItem,
9
9
  resolveBaseItemOfType,
@@ -10,16 +10,26 @@ export declare function slugify(name: string): string;
10
10
  * `parts.slice(2).join("_")`. Tolerates a nullish slug (degrades to "") so a
11
11
  * malformed entity can't hard-crash the builder; the resolver backfills real slugs. */
12
12
  export declare function bareEntitySlug(slug: string | null | undefined): string;
13
- /** "[[SRD 2024/Classes/Fighter]]" to "fighter" (tail segment, slugified).
13
+ /** Whether a link tail is a stored registry slug (`me_feat_wish-magic`) rather than a human name
14
+ * ("Wish Magic", "Magic Initiate (Cleric)"). The ONE slug-form rule: `wikilinkTailSlug` reads a tail by it,
15
+ * and a registry-free display surface uses it to name a slug-form link instead of printing the raw slug. */
16
+ export declare function isStoredSlug(tail: string): boolean;
17
+ /** A link's BARE name slug, the key `bareEntitySlug` gives an owner: "[[SRD 2024/Classes/Fighter]]" and
18
+ * "[[srd-2024_class_fighter]]" both give "fighter".
14
19
  *
15
- * The tail goes through the SAME `slugify` that mints registry slugs, so an apostrophe is DELETED rather than
16
- * hyphenated ("Mage's Bane" to "mages-bane", where the old hand-rolled regex minted "mage-s-bane" and missed
17
- * every time). Only ever call this on a human NAME tail, never on a full `<prefix>_<name>` slug, which slugify
18
- * would destroy: `pc.decision-engine.ts`'s `resolveEntityRef` is the function that strips a `[[wikilink]]`
19
- * WITHOUT slugifying, and it is the one to use for a STORED slug.
20
+ * A link names an entity one of two ways, and the tail is read by its shape:
21
+ * - a human NAME tail (a path's file name, or a bare `[[fighter]]`) goes through the SAME `slugify` that mints
22
+ * registry slugs, so an apostrophe is DELETED rather than hyphenated ("Mage's Bane" to "mages-bane", where
23
+ * the old hand-rolled regex minted "mage-s-bane" and missed every time);
24
+ * - a STORED slug tail (`[[me_class_bard-captain-lugen-compatibility]]`, the form every PC note and the Me
25
+ * homebrew notes write) goes through `bareEntitySlug`. slugify DELETES the `_`, so it used to mint
26
+ * "meclassbard-captain-lugen-compatibility", no owner's bare slug: a Me subclass linking its class that way
27
+ * was never offered under it and the Builder's Class step called it an orphan (2026-09-25, Captain Lugen).
28
+ * The answer is the BARE slug, never the full one, so a lookup that needs the exact entity must not route a
29
+ * stored slug through here: `pc.decision-engine.ts`'s `resolveEntityRef` strips a `[[wikilink]]` WITHOUT this
30
+ * helper and looks the full slug up directly.
20
31
  *
21
32
  * MOVED here from `pc.decision-engine.ts` in R4-G5 T1, beside `bareEntitySlug`, so `pc.pools.ts` can use it
22
33
  * without importing the decision engine: the engine imports `pc.pools` for `strandedPicks`, and the old
23
- * direction would be a cycle. The engine keeps a re-export, so its three plugin importers and its own test
24
- * are untouched. */
34
+ * direction would be a cycle. The engine keeps a re-export for its plugin importer and its own test. */
25
35
  export declare function wikilinkTailSlug(link: string): string;
@@ -1,10 +1,12 @@
1
1
  import {
2
2
  bareEntitySlug,
3
+ isStoredSlug,
3
4
  slugify,
4
5
  wikilinkTailSlug
5
- } from "../chunk-6X4KUDMU.js";
6
+ } from "../chunk-ZCTUYGNV.js";
6
7
  export {
7
8
  bareEntitySlug,
9
+ isStoredSlug,
8
10
  slugify,
9
11
  wikilinkTailSlug
10
12
  };
@@ -1,11 +1,11 @@
1
1
  import {
2
2
  featCodec
3
- } from "../chunk-CHUALUIX.js";
4
- import "../chunk-T2SNEJOE.js";
5
- import "../chunk-U3BABVJF.js";
3
+ } from "../chunk-RYLXAYIQ.js";
4
+ import "../chunk-7QN7XSAK.js";
5
+ import "../chunk-PKX6TGRE.js";
6
6
  import "../chunk-ZJXSXVFP.js";
7
- import "../chunk-2M34FLAY.js";
8
- import "../chunk-XTRDCSJB.js";
7
+ import "../chunk-5MXFW4O3.js";
8
+ import "../chunk-2JSQE3DD.js";
9
9
  import "../chunk-UA5KS2PL.js";
10
10
  export {
11
11
  featCodec
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  parseFeat
3
- } from "../chunk-T2SNEJOE.js";
4
- import "../chunk-U3BABVJF.js";
3
+ } from "../chunk-7QN7XSAK.js";
4
+ import "../chunk-PKX6TGRE.js";
5
5
  import "../chunk-ZJXSXVFP.js";
6
- import "../chunk-2M34FLAY.js";
7
- import "../chunk-XTRDCSJB.js";
6
+ import "../chunk-5MXFW4O3.js";
7
+ import "../chunk-2JSQE3DD.js";
8
8
  import "../chunk-UA5KS2PL.js";
9
9
  export {
10
10
  parseFeat
@@ -88,6 +88,31 @@ export declare const featEntitySchema: z.ZodObject<{
88
88
  minimum: z.ZodOptional<z.ZodNumber>;
89
89
  condition: z.ZodOptional<z.ZodString>;
90
90
  subject: z.ZodOptional<z.ZodString>;
91
+ }, z.core.$strip>, z.ZodObject<{
92
+ kind: z.ZodLiteral<"save-bonus">;
93
+ ability: z.ZodEnum<{
94
+ str: "str";
95
+ dex: "dex";
96
+ con: "con";
97
+ int: "int";
98
+ wis: "wis";
99
+ cha: "cha";
100
+ }>;
101
+ minimum: z.ZodOptional<z.ZodNumber>;
102
+ saves: z.ZodOptional<z.ZodArray<z.ZodEnum<{
103
+ str: "str";
104
+ dex: "dex";
105
+ con: "con";
106
+ int: "int";
107
+ wis: "wis";
108
+ cha: "cha";
109
+ }>>>;
110
+ inactive_while: z.ZodOptional<z.ZodEnum<{
111
+ incapacitated: "incapacitated";
112
+ unconscious: "unconscious";
113
+ }>>;
114
+ condition: z.ZodOptional<z.ZodString>;
115
+ subject: z.ZodOptional<z.ZodString>;
91
116
  }, z.core.$strip>, z.ZodObject<{
92
117
  kind: z.ZodLiteral<"half-proficiency">;
93
118
  skills: z.ZodOptional<z.ZodArray<z.ZodString>>;
@@ -163,11 +188,24 @@ export declare const featEntitySchema: z.ZodObject<{
163
188
  kind: z.ZodLiteral<"damage-bonus">;
164
189
  damage_type: z.ZodString;
165
190
  amount: z.ZodString;
166
- applies_to: z.ZodOptional<z.ZodEnum<{
167
- weapon: "weapon";
191
+ applies_to: z.ZodOptional<z.ZodUnion<readonly [z.ZodEnum<{
168
192
  spell: "spell";
169
193
  all: "all";
170
- }>>;
194
+ }>, z.ZodEnum<{
195
+ weapon: "weapon";
196
+ melee: "melee";
197
+ ranged: "ranged";
198
+ unarmed: "unarmed";
199
+ finesse: "finesse";
200
+ thrown: "thrown";
201
+ }>, z.ZodArray<z.ZodEnum<{
202
+ weapon: "weapon";
203
+ melee: "melee";
204
+ ranged: "ranged";
205
+ unarmed: "unarmed";
206
+ finesse: "finesse";
207
+ thrown: "thrown";
208
+ }>>]>>;
171
209
  condition: z.ZodOptional<z.ZodString>;
172
210
  subject: z.ZodOptional<z.ZodString>;
173
211
  }, z.core.$strip>, z.ZodObject<{
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  featEntitySchema
3
- } from "../chunk-U3BABVJF.js";
3
+ } from "../chunk-PKX6TGRE.js";
4
4
  import "../chunk-ZJXSXVFP.js";
5
- import "../chunk-2M34FLAY.js";
6
- import "../chunk-XTRDCSJB.js";
5
+ import "../chunk-5MXFW4O3.js";
6
+ import "../chunk-2JSQE3DD.js";
7
7
  import "../chunk-UA5KS2PL.js";
8
8
  export {
9
9
  featEntitySchema