@archivist-gg/dnd5e 0.3.27 → 0.3.28

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 (77) hide show
  1. package/LICENSES/SRD.md +6 -13
  2. package/README.md +1 -1
  3. package/dist/chunk-2GZM7FCD.js +1 -0
  4. package/dist/{chunk-KEXSF3CH.js → chunk-2OVDSMPY.js} +1 -1
  5. package/dist/chunk-4AJYEWFQ.js +1 -0
  6. package/dist/chunk-4FTTUZXM.js +1 -0
  7. package/dist/{chunk-CCAVZANF.js → chunk-53SHSS4M.js} +1 -1
  8. package/dist/{chunk-6J3L2RYZ.js → chunk-5QDSAZG6.js} +1 -1
  9. package/dist/chunk-6IPWTOLU.js +1 -0
  10. package/dist/{chunk-BAOZAXB3.js → chunk-7HOOPNF5.js} +1 -1
  11. package/dist/{chunk-7CFLU2XL.js → chunk-ADX7435T.js} +1 -1
  12. package/dist/{chunk-35HHIMOJ.js → chunk-C4T6BUSP.js} +1 -1
  13. package/dist/chunk-CLZRWPWT.js +1 -0
  14. package/dist/{chunk-BWIEA5ZP.js → chunk-CYYVM6H3.js} +1 -1
  15. package/dist/{chunk-XVXNBWK6.js → chunk-D2BXAFOL.js} +1 -1
  16. package/dist/{chunk-PKIMOVQG.js → chunk-E4E6YEN6.js} +1 -1
  17. package/dist/{chunk-WAUNLUFQ.js → chunk-J27N3KUE.js} +1 -1
  18. package/dist/{chunk-AHEL6LJ5.js → chunk-J6FIBUI4.js} +1 -1
  19. package/dist/{chunk-JGCE4JVX.js → chunk-KGZXAAFN.js} +1 -1
  20. package/dist/chunk-KZFTTAFN.js +1 -0
  21. package/dist/chunk-M2UA2FAK.js +1 -0
  22. package/dist/{chunk-UWDHEIPY.js → chunk-MMDUUEFA.js} +1 -1
  23. package/dist/{chunk-LVKSX6EQ.js → chunk-NB4QWMF5.js} +1 -1
  24. package/dist/{chunk-3A4OSTC4.js → chunk-NU6WP4P5.js} +1 -1
  25. package/dist/{chunk-CEHL7PPC.js → chunk-RR26E7LH.js} +1 -1
  26. package/dist/{chunk-535ZMMZI.js → chunk-VY5ZEOLG.js} +1 -1
  27. package/dist/{chunk-TGK4OP7P.js → chunk-XCF5R5XX.js} +1 -1
  28. package/dist/class/class.codec.js +1 -1
  29. package/dist/class/class.parser.js +1 -1
  30. package/dist/class/class.schema.js +1 -1
  31. package/dist/index.js +1 -1
  32. package/dist/monster/monster.parser.js +1 -1
  33. package/dist/monster/monster.schema.js +1 -1
  34. package/dist/pc/pc.additional-spells.js +1 -1
  35. package/dist/pc/pc.amount-bindings.js +1 -1
  36. package/dist/pc/pc.decision-engine.d.ts +2 -0
  37. package/dist/pc/pc.decision-engine.js +1 -1
  38. package/dist/pc/pc.entry-overrides.js +1 -1
  39. package/dist/pc/pc.equipment.d.ts +5 -1
  40. package/dist/pc/pc.equipment.js +1 -1
  41. package/dist/pc/pc.feature-effects.d.ts +5 -0
  42. package/dist/pc/pc.feature-effects.js +1 -1
  43. package/dist/pc/pc.infusions.js +1 -1
  44. package/dist/pc/pc.item-effects.js +1 -1
  45. package/dist/pc/pc.member-choices.js +1 -1
  46. package/dist/pc/pc.parser.js +1 -1
  47. package/dist/pc/pc.pools.js +1 -1
  48. package/dist/pc/pc.proficiencies.js +1 -1
  49. package/dist/pc/pc.proficiency-replacements.d.ts +22 -0
  50. package/dist/pc/pc.proficiency-replacements.js +1 -0
  51. package/dist/pc/pc.recalc.d.ts +3 -1
  52. package/dist/pc/pc.recalc.js +1 -1
  53. package/dist/pc/pc.resolver.js +1 -1
  54. package/dist/pc/pc.resource-seed.js +1 -1
  55. package/dist/pc/pc.resources.js +1 -1
  56. package/dist/pc/pc.rest.js +1 -1
  57. package/dist/pc/pc.schema.d.ts +1 -0
  58. package/dist/pc/pc.schema.js +1 -1
  59. package/dist/pc/pc.species-increases.d.ts +12 -0
  60. package/dist/pc/pc.species-increases.js +1 -0
  61. package/dist/pc/pc.types.d.ts +29 -0
  62. package/dist/race/race.codec.js +1 -1
  63. package/dist/race/race.parser.js +1 -1
  64. package/dist/race/race.schema.js +1 -1
  65. package/dist/race/race.subspecies.d.ts +12 -0
  66. package/dist/race/race.subspecies.js +1 -0
  67. package/dist/schemas/attack-schema.d.ts +1 -0
  68. package/dist/schemas/feature-schema.js +1 -1
  69. package/dist/subclass/subclass.codec.js +1 -1
  70. package/dist/subclass/subclass.parser.js +1 -1
  71. package/dist/subclass/subclass.schema.js +1 -1
  72. package/dist/types/attack.d.ts +1 -0
  73. package/package.json +1 -1
  74. package/dist/chunk-BPXQOJES.js +0 -1
  75. package/dist/chunk-FD2VQ3H6.js +0 -1
  76. package/dist/chunk-GPBPFKUK.js +0 -1
  77. package/dist/chunk-ZREOQMHM.js +0 -1
package/LICENSES/SRD.md CHANGED
@@ -1,23 +1,16 @@
1
1
  # SRD Attribution (CC-BY-4.0)
2
2
 
3
- This repository bundles content from the Dungeons & Dragons **System Reference Document**,
4
- both the 5.1 (2014) and 5.2 (2024) editions, released by Wizards of the Coast under the
5
- Creative Commons Attribution 4.0 International License (CC-BY-4.0).
3
+ This repository bundles content from the **System Reference Document**, both the 5.1 (2014)
4
+ and 5.2 (2024) editions, licensed under the Creative Commons Attribution 4.0 International
5
+ License (CC-BY-4.0).
6
6
 
7
7
  ## Required attribution
8
8
 
9
- This work includes material from the System Reference Document 5.1 ("SRD 5.1") by Wizards of
10
- the Coast LLC and available at https://dnd.wizards.com/resources/systems-reference-document.
11
- The SRD 5.1 is licensed under the Creative Commons Attribution 4.0 International License,
12
- available at https://creativecommons.org/licenses/by/4.0/legalcode.
9
+ This work includes material taken from the System Reference Document 5.1 ("SRD 5.1") by Wizards of the Coast LLC and available at https://dnd.wizards.com/resources/systems-reference-document. The SRD 5.1 is licensed under the Creative Commons Attribution 4.0 International License available at https://creativecommons.org/licenses/by/4.0/legalcode.
13
10
 
14
- This work includes material from the System Reference Document 5.2 ("SRD 5.2") by Wizards of
15
- the Coast LLC and available at https://www.dndbeyond.com/srd. The SRD 5.2 is licensed under
16
- the Creative Commons Attribution 4.0 International License, available at
17
- https://creativecommons.org/licenses/by/4.0/legalcode.
11
+ This work includes material from the System Reference Document 5.2 ("SRD 5.2") by Wizards of the Coast LLC, available at https://www.dndbeyond.com/srd. The SRD 5.2 is licensed under the Creative Commons Attribution 4.0 International License, available at https://creativecommons.org/licenses/by/4.0/legalcode.
18
12
 
19
- Copyright © Wizards of the Coast LLC. "Dungeons & Dragons" is a trademark of Wizards of the
20
- Coast. This project is unofficial and not affiliated with or endorsed by Wizards of the Coast.
13
+ This project is unofficial and not affiliated with or endorsed by Wizards of the Coast.
21
14
 
22
15
  ## Bundled SRD locations
23
16
 
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @archivist-gg/dnd5e
2
2
 
3
- The D&D 5e (2014 and 2024) rules pack of Archivist, the D&D toolkit for Obsidian: parsers,
3
+ The fifth edition (2014 and 2024) rules pack of Archivist, the fifth edition toolkit for Obsidian: parsers,
4
4
  schemas, codecs and types for every entity type, the dice, formula and tag machinery, the
5
5
  player-character engine, and the bundled SRD content. Built on `@archivist-gg/core`.
6
6
 
@@ -0,0 +1 @@
1
+ import{equipmentCategoryKey,isCategoryGrant}from"./chunk-2EOGK6R6.js";import{withSubspeciesParent}from"./chunk-4AJYEWFQ.js";import{TOOL_CATEGORIES,backgroundToolPicks,categoryWords,classToolPicks,expandToolPool,toolCategoriesOf}from"./chunk-RQZCGXUZ.js";import{replacementChoiceId,replacementDescription,replacementOwner,replacementPick}from"./chunk-CLZRWPWT.js";import{assembleEffectFeatures,classifyProficiencyEffect,collectProficiencyEffectGrants,foldsNow,selfEffectsOf}from"./chunk-4FTTUZXM.js";import{ALL_LANGUAGES,ALL_SKILL_SLUGS,ALL_TOOLS}from"./chunk-4JEF3CET.js";import{humanizeProficiency,proficiencyLabel,toProfSlug}from"./chunk-VTQ4RWEG.js";import{buildItemFeatures}from"./chunk-MMDUUEFA.js";import{classPactWeaponPick,featOfSite,featPickSites,isTargetChoice,memberChoices,pactWeaponPick,poolMemberSites,poolMemberSitesOf,raceFeatSites}from"./chunk-J27N3KUE.js";import{collectAdditionalSpells}from"./chunk-RR26E7LH.js";import{resolveFeatureResources,resolveResourceIndex}from"./chunk-2OVDSMPY.js";import{attributeUnclassedSpell,effectiveSpellcastingAbility,normalizeKnownSpell,resolveSpellcasting}from"./chunk-PFQPP77Q.js";import{convertibleLegacyAsi,flattenAsiOrFeat,resolveLegacyAsiFeat}from"./chunk-QVWT67WA.js";import{bindFeatureConsumers,buildInfusionContext,resolveAllPools,resolveOptionRows,storedSpellNumbers,strandedPicks,withoutStrandedSites}from"./chunk-E4E6YEN6.js";import{countColumnsFor,readTableColumn}from"./chunk-CSTAQQGX.js";import{recognizeDecision}from"./chunk-3LWOVRLA.js";import{isItemEntity,resolveEntityForEntry}from"./chunk-4IAMSRHD.js";import{FEATURE_TYPE_FOR_CATEGORY,featCategoryOf,featProgressionCategory}from"./chunk-3QQOATV3.js";import{warnOnce}from"./chunk-DZITM5AG.js";import{resolveBaseItem}from"./chunk-PZ4L2EEG.js";import{bucketOf}from"./chunk-QMEKQTUT.js";import{isValidMaxFormula}from"./chunk-EAARMPCW.js";import{bareEntitySlug,wikilinkTailSlug}from"./chunk-63YJPWTM.js";import{mirrorSpellShapes}from"./chunk-4KVVAENP.js";import{ABILITY_KEYS,ALL_SKILLS}from"./chunk-EVT7MGAC.js";import{withResolvedActionCost}from"./chunk-S5UCI27C.js";var UNKNOWN_SOURCE="Unknown";var UNKNOWN_GRANT_SOURCE=UNKNOWN_SOURCE;function grantSourceName(resolved,kind,slug){var _a,_b,_c,_d,_e,_f,_g,_h,_i,_j,_k,_l,_m,_n,_o,_p,_q,_r;switch(kind){case"class":return(_d=(_c=(_b=(_a=resolved.classes)==null?void 0:_a.find(c=>{var _a2;return((_a2=c.entity)==null?void 0:_a2.slug)===slug}))==null?void 0:_b.entity)==null?void 0:_c.name)!=null?_d:UNKNOWN_SOURCE;case"subclass":return(_h=(_g=(_f=(_e=resolved.classes)==null?void 0:_e.find(c=>{var _a2;return((_a2=c.subclass)==null?void 0:_a2.slug)===slug}))==null?void 0:_f.subclass)==null?void 0:_g.name)!=null?_h:UNKNOWN_SOURCE;case"race":return(_j=(_i=resolved.race)==null?void 0:_i.name)!=null?_j:UNKNOWN_SOURCE;case"background":return(_l=(_k=resolved.background)==null?void 0:_k.name)!=null?_l:UNKNOWN_SOURCE;case"feat":return(_o=(_n=(_m=resolved.feats)==null?void 0:_m.find(f=>f.slug===slug))==null?void 0:_n.name)!=null?_o:UNKNOWN_SOURCE;case"item":return(_r=(_q=(_p=resolved.itemFeatures)==null?void 0:_p.find(f=>f.source.slug===slug))==null?void 0:_q.feature.name)!=null?_r:UNKNOWN_SOURCE;default:return UNKNOWN_SOURCE}}function collectProficiencyGrants(resolved){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;const classArmor=[];const classWeaponFixed=[];const classWeaponCategories=[];const classToolFixed=[];for(const c of resolved.classes){const prof=(_a=c.entity)==null?void 0:_a.proficiencies;if(!prof)continue;const source=(_c=(_b=c.entity)==null?void 0:_b.name)!=null?_c:UNKNOWN_SOURCE;for(const a of(_d=prof.armor)!=null?_d:[])classArmor.push({value:a,source});for(const w of(_f=(_e=prof.weapons)==null?void 0:_e.fixed)!=null?_f:[])classWeaponFixed.push({value:w,source});for(const w of(_h=(_g=prof.weapons)==null?void 0:_g.categories)!=null?_h:[])classWeaponCategories.push({value:w,source});for(const t of(_j=(_i=prof.tools)==null?void 0:_i.fixed)!=null?_j:[])classToolFixed.push({value:t,source});for(const t of classToolPicks(c.entity).grants)classToolFixed.push({value:t,source})}const raceSource=(_l=(_k=resolved.race)==null?void 0:_k.name)!=null?_l:UNKNOWN_SOURCE;const raceLangFixed=((_o=(_n=(_m=resolved.race)==null?void 0:_m.languages)==null?void 0:_n.fixed)!=null?_o:[]).map(l=>({value:l,source:raceSource}));const bgToolFixed=[];const bgLangFixed=[];const bg=resolved.background;if(bg){const source=(_p=bg.name)!=null?_p:UNKNOWN_SOURCE;for(const entry of(_q=bg.tool_proficiencies)!=null?_q:[]){if(entry.kind==="fixed"){for(const t of entry.items)bgToolFixed.push({value:t,source})}}for(const t of backgroundToolPicks(bg).grants)bgToolFixed.push({value:t,source});for(const entry of(_r=bg.language_proficiencies)!=null?_r:[]){if(entry.kind==="fixed"){for(const l of entry.languages)bgLangFixed.push({value:l,source})}}}const featArmor=[];const featWeapons=[];const featTools=[];const featLanguages=[];for(const f of(_s=resolved.feats)!=null?_s:[]){const featView=f;const grants=featView.proficiencies;if(!grants)continue;const source=(_t=f.name)!=null?_t:UNKNOWN_SOURCE;for(const a of(_u=grants.armor)!=null?_u:[])featArmor.push({value:a,source});for(const w of(_v=grants.weapons)!=null?_v:[])featWeapons.push({value:w,source});for(const t of(_w=grants.tools)!=null?_w:[])featTools.push({value:t,source});for(const l of(_x=grants.languages)!=null?_x:[])featLanguages.push({value:l,source})}const{features:effectFeatures,activeBuffs}=assembleEffectFeatures(resolved);const fx=collectProficiencyEffectGrants(effectFeatures,activeBuffs);const nameFor=(kind,slug)=>grantSourceName(resolved,kind,slug);const toGrants=(list,useRaw)=>list.map(g=>({value:useRaw?g.raw:g.value,source:nameFor(g.sourceKind,g.sourceSlug),...g.expertise?{expertise:true}:{}}));const effectArmor=toGrants(fx.armor,true);const effectWeapons=toGrants(fx.weapons,true);const effectTools=toGrants(fx.tools,false);const effectLanguages=toGrants(fx.languages,false);return{classArmor,classWeaponFixed,classWeaponCategories,classToolFixed,raceLangFixed,bgToolFixed,bgLangFixed,featArmor,featWeapons,featTools,featLanguages,effectArmor,effectWeapons,effectTools,effectLanguages}}function inventoryOptions(resolved,registry,entityType){var _a,_b,_c,_d;const out=[];const seen=new Set;const find=ref=>{var _a2,_b2;const withSlug=registry;if(typeof withSlug.getBySlug==="function")return resolveBaseItem(ref,withSlug);const bare=ref.replace(/^\[\[/,"").replace(/\]\]$/,"").split("|")[0].trim();return(_b2=(_a2=registry.getByTypeAndSlug(entityType,bare))!=null?_a2:registry.getByTypeAndSlug("item",bare))!=null?_b2:null};for(const entry of(_b=(_a=resolved.definition)==null?void 0:_a.equipment)!=null?_b:[]){if(typeof entry.item!=="string")continue;const e=find(entry.item);if(!e||seen.has(e.slug))continue;const value=e.slug;const base=e.entityType===entityType?e:typeof e.data.base_item==="string"?find(e.data.base_item):null;if(!base||base.entityType!==entityType)continue;seen.add(value);const name=(_d=(_c=entry.overrides)==null?void 0:_c.name)!=null?_d:e.name;out.push({value,label:name,entity:e})}return out}var warnedDegradedEquipment=new Set;var warnedAmbiguousBare=new Set;var foldedTypeMemo=new Map;function foldedType(s){let v=foldedTypeMemo.get(s);if(v===void 0){v=categoryWords(s).join(" ");foldedTypeMemo.set(s,v)}return v}function matchesFilter(e,where,ownerBare){var _a,_b,_c,_d,_e,_f;const d=e.data;if(where.feature_type&&d.feature_type!==where.feature_type)return false;if(where.category&&featCategoryOf((_a=d.category)!=null?_a:"")!==featCategoryOf(where.category))return false;if(where.list&&!((_b=d.classes)!=null?_b:[]).includes(where.list))return false;if(where.level!==void 0&&((_c=d.level)!=null?_c:0)!==where.level)return false;if(where.edition&&d.edition!==where.edition)return false;if(where.ritual&&d.ritual!==true)return false;if(where.weapon_category){const cat=((_d=d.category)!=null?_d:"").toLowerCase();if(!cat.startsWith(`${where.weapon_category}-`)&&cat!==where.weapon_category)return false}if(where.armor_category){if(((_e=d.category)!=null?_e:"").toLowerCase()!==where.armor_category)return false}if(where.item_type){const t=foldedType(typeof d.type==="string"?d.type:"");if(!t||!where.item_type.some(x=>foldedType(x)===t))return false}if(where.mundane){const r=typeof d.rarity==="string"?d.rarity.trim().toLowerCase():"";if(r&&r!=="none"&&r!=="mundane")return false}if(where.parent_class==="self"){if(!d.parent_class||wikilinkTailSlug(d.parent_class)!==ownerBare)return false}if(where.available_to==="self"){const list=(_f=d.available_to)!=null?_f:[];if(!list.some(l=>wikilinkTailSlug(l)===ownerBare))return false}return true}var __matchesFilterForTest=matchesFilter;function parseEquipmentCategory(category){const tools=toolCategoriesOf(category);if(tools)return{kind:"tool",tools};const words=categoryWords(category).filter(w=>w!=="any");const has=w=>words.includes(w);const only=allowed=>words.every(w=>allowed.includes(w));if(words.length===1&&has("shield"))return{kind:"shield"};if(has("armor")&&only(["armor","light","medium","heavy"])&&words.length<=2){const armor=["light","medium","heavy"].find(k=>has(k));return{kind:"armor",armor}}if(has("weapon")&&only(["weapon","simple","martial","melee","ranged"])){const klass=["simple","martial"].filter(k=>has(k));const range=["melee","ranged"].filter(k=>has(k));if(klass.length===1&&range.length<=1&&words.length===2+range.length){return{kind:"weapon",weapon:klass[0],range:range[0]}}}return void 0}function categoryToEntitySelect(category,id){const spec=parseEquipmentCategory(category);const pick={kind:"select-entity",id,count:1};switch(spec==null?void 0:spec.kind){case"shield":return{...pick,label:"Choose a shield",entity_type:"armor",where:{armor_category:"shield"}};case"armor":return spec.armor?{...pick,label:`Choose ${spec.armor} armor`,entity_type:"armor",where:{armor_category:spec.armor}}:{...pick,label:"Choose armor",entity_type:"armor"};case"weapon":return{...pick,label:`Choose a ${spec.weapon}${spec.range?` ${spec.range}`:""} weapon`,entity_type:"weapon",where:{weapon_category:spec.weapon}};case"tool":return{...pick,label:`Choose ${spec.tools.map(t=>TOOL_CATEGORIES[t].label).join(" or ")}`,entity_type:"item",where:{item_type:spec.tools.map(t=>TOOL_CATEGORIES[t].itemType),mundane:true}};default:warnOnce(`equipment-category:${category}`,`Archivist: starting-equipment category "${category}" is not a known item category; its pick offers no options.`);return{...pick,label:`Choose a ${category.replace(/[-_]+/g," ")}`,entity_type:"item",from:[]}}}var __categoryToEntitySelectForTest=categoryToEntitySelect;function equipmentDecisions(entries,ownerSlug){const out=[];let degraded=false;(entries!=null?entries:[]).forEach((eq,i)=>{var _a;if((eq==null?void 0:eq.kind)!=="choice")return;const options=(_a=eq.options)!=null?_a:[];out.push({kind:"select-inline",id:`equipment-${i}`,label:"Starting Equipment",count:1,options:options.map((opt,j)=>{var _a2;const label=typeof opt==="string"?opt:(_a2=opt==null?void 0:opt.label)!=null?_a2:"";const wellFormed=!!opt&&typeof opt==="object"&&Array.isArray(opt.grants);if(!wellFormed)degraded=true;const grants=wellFormed?opt.grants:[];return{value:`option-${j}`,label,choices:grants.flatMap((g,k)=>isCategoryGrant(g)?[categoryToEntitySelect(g.category,equipmentCategoryKey(i,j,k))]:[])}})})});if(degraded&&!warnedDegradedEquipment.has(ownerSlug)){warnedDegradedEquipment.add(ownerSlug);console.warn(`[archivist] Starting equipment for "${ownerSlug}" is in an outdated/unstructured format; its nested picks and seeding are skipped. Re-sync the compendium (delete _compendium.md and reload) to fix.`)}return out}function authoredProficiencyPool(choice){if(!choice.from)return void 0;return choice.domain==="tool"?expandToolPool(choice.from):choice.from}function enumerateOptions(choice,ctx,ownerBare){var _a,_b;switch(choice.kind){case"select-inline":return choice.options.map(o=>({value:o.value,label:o.label,description:o.description}));case"select-entity":{if(choice.from){let byBare;const bareIndex=()=>{var _a2,_b2,_c,_d;if(byBare)return byBare;const built=new Map;const pool=ctx.registry.search("",choice.entity_type,Number.POSITIVE_INFINITY).slice().sort((a,b)=>a.name.localeCompare(b.name)||a.slug.localeCompare(b.slug));const seed=e=>{const bare=bareEntitySlug(e.slug);if(built.has(bare)){if(!warnedAmbiguousBare.has(bare)){warnedAmbiguousBare.add(bare);console.warn(`Archivist: bare slug "${bare}" matches multiple ${choice.entity_type} entities; using "${built.get(bare).slug}"`)}return}built.set(bare,e)};for(const e of pool)if((_b2=(_a2=ctx.isEntityVisible)==null?void 0:_a2.call(ctx,e))!=null?_b2:true)seed(e);for(const e of pool)if(!((_d=(_c=ctx.isEntityVisible)==null?void 0:_c.call(ctx,e))!=null?_d:true))seed(e);byBare=built;return built};return choice.from.map(slug=>{var _a2;const e=(_a2=ctx.registry.getByTypeAndSlug(choice.entity_type,slug))!=null?_a2:bareIndex().get(slug);return e?{value:e.slug,label:e.name,entity:e}:{value:slug,label:slug,missing:true}})}const all=ctx.registry.search("",choice.entity_type,Number.POSITIVE_INFINITY);const filtered=choice.where?all.filter(e=>matchesFilter(e,choice.where,ownerBare)):all;return filtered.map(e=>({value:e.slug,label:e.name,entity:e}))}case"select-proficiency":{const pool=(_a=authoredProficiencyPool(choice))!=null?_a:choice.domain==="skill"?[...ALL_SKILL_SLUGS]:choice.domain==="language"?[...ALL_LANGUAGES]:choice.domain==="tool"?[...ALL_TOOLS]:[];return pool.map(v=>({value:v,label:humanizeProficiency(v)}))}case"ability-points":{const pool=(_b=choice.pool)!=null?_b:["str","dex","con","int","wis","cha"];return pool.map(a=>({value:a,label:a.toUpperCase()}))}}}function selectionCount(choice,selected){if(selected===void 0)return 0;if(choice.kind==="ability-points"){if(typeof selected!=="object"||Array.isArray(selected))return 0;return Object.values(selected).reduce((s,v)=>s+(typeof v==="number"?v:0),0)}if(Array.isArray(selected))return selected.length;return typeof selected==="string"&&selected.length>0?1:0}function requiredCount(choice){var _a;if(choice.kind==="ability-points")return choice.points;if(choice.kind==="select-proficiency")return choice.count;return(_a=choice.count)!=null?_a:1}function capAtCount(choice,value){const folds=choice.kind==="select-proficiency"||choice.kind==="select-entity"&&choice.entity_type==="weapon"&&choice.id!=="weapon-mastery"&&!isTargetChoice(choice);if(!folds||!Array.isArray(value))return value;const n=requiredCount(choice);return value.length>n?value.slice(0,n):value}function statusOf(choice,selected,satisfied){const n=selectionCount(choice,selected);const need=requiredCount(choice);if(satisfied)return"resolved";if(n===0)return"unresolved";return n>=need?"resolved":"partial"}var matchPool=(v,pool)=>pool.find(p=>toProfSlug(p)===toProfSlug(v));var canonicalizeSelection=(value,pool)=>{var _a;if(typeof value==="string")return(_a=matchPool(value,pool))!=null?_a:value;if(Array.isArray(value))return value.map(v=>{var _a2;return(_a2=matchPool(v,pool))!=null?_a2:v});return value};function resolveEntityRef(ctx,entityType,value){if(typeof value!=="string"||value.length===0)return void 0;const raw=value.replace(/^\[\[/,"").replace(/\]\]$/,"");const direct=ctx.registry.getByTypeAndSlug(entityType,raw);if(direct)return direct;for(const e of ctx.registry.search("",entityType,Number.POSITIVE_INFINITY)){if(e.slug===raw||bareEntitySlug(e.slug)===raw)return e}return void 0}function buildItem(inputChoice,source,level,featureName,readValue,ctx,ownerBare,effective,opts){var _a,_b,_c,_d,_e;const choice=flattenAsiOrFeat(inputChoice);const keyPrefix=(_a=opts==null?void 0:opts.keyPrefix)!=null?_a:"";const expandFeatChildren=(_b=opts==null?void 0:opts.expandFeatChildren)!=null?_b:true;const key=keyPrefix+choice.id;const raw=capAtCount(choice,readValue(key));const preExclusionOptions=choice.kind==="select-entity"&&((_c=choice.where)==null?void 0:_c.inventory)===true?effective.inventory(choice.entity_type):enumerateOptions(choice,ctx,ownerBare);let options=preExclusionOptions;const mine=new Set((Array.isArray(raw)?raw:raw===void 0?[]:[raw]).map(v=>toProfSlug(String(v))));if(choice.kind==="select-proficiency"&&choice.domain==="skill"&&choice.from_proficient){options=options.filter(o=>effective.skill.has(toProfSlug(o.value))||mine.has(toProfSlug(o.value)))}const postInclusionOptions=options;const excludes=choice.kind==="select-proficiency"&&(choice.domain==="language"||choice.domain==="tool"||choice.domain==="skill"&&choice.expertise===true);if(excludes&&choice.kind==="select-proficiency"){const known=choice.domain==="skill"?effective.skillExpertise:effective[choice.domain];options=options.filter(o=>!known.has(toProfSlug(o.value))||mine.has(toProfSlug(o.value)))}const satisfied=excludes&&postInclusionOptions.length>0&&options.length===0;const selected=choice.kind==="select-proficiency"?canonicalizeSelection(raw,options.map(o=>o.value)):raw;const item={key,source,level,featureName,choice,description:opts==null?void 0:opts.description,options,selected,status:statusOf(choice,selected,satisfied),satisfied};if(choice.kind==="select-inline"&&typeof selected==="string"){const branch=choice.options.find(o=>o.value===selected);if((_d=branch==null?void 0:branch.choices)==null?void 0:_d.length){item.children=branch.choices.map(c=>buildItem(c,source,level,featureName,readValue,ctx,ownerBare,effective,{keyPrefix,expandFeatChildren}));if(item.status==="resolved"&&item.children.some(c=>c.status!=="resolved")){item.status="partial"}}}if(choice.kind==="select-entity"&&choice.entity_type==="feat"&&expandFeatChildren&&typeof selected==="string"){const entity=resolveEntityRef(ctx,"feat",selected);const rawChoices=(_e=entity==null?void 0:entity.data)==null?void 0:_e.choices;const featChoices=Array.isArray(rawChoices)?rawChoices:[];if(featChoices.length){const childPrefix=`${keyPrefix}feat:`;item.children=featChoices.map(c=>buildItem(c,source,level,featureName,readValue,ctx,ownerBare,effective,{keyPrefix:childPrefix,expandFeatChildren:false}));if(item.status==="resolved"&&item.children.some(c=>c.status!=="resolved")){item.status="partial"}}}return item}function buildSubclassItem(choice,source,level,featureName,c,ctx,ownerBare,description){const selected=c.subclass?c.subclass.slug:void 0;return{key:"subclass",source,level,featureName,description,choice,options:enumerateOptions(choice,ctx,ownerBare),selected,status:selected?"resolved":"unresolved",satisfied:false}}function visitProficiencyChoices(resolved,visit){var _a,_b,_c,_d,_e,_f;const walk=(choices,read,owner,kind)=>{for(const ch of choices!=null?choices:[]){visit(ch,read(ch.id),owner,kind);if(ch.kind==="select-inline"){const sel=read(ch.id);const branch=typeof sel==="string"?ch.options.find(o=>o.value===sel):void 0;if(branch==null?void 0:branch.choices)walk(branch.choices,read,owner,kind)}}};const oc=(_a=resolved.definition.origin_choices)!=null?_a:{};const originRead=ns=>id=>oc[`${ns}:${id}`];const stripRef=ref=>ref.replace(/^\[\[/,"").replace(/\]\]$/,"");const featBySlug=new Map(((_b=resolved.feats)!=null?_b:[]).map(f=>[f.slug,f]));const memberSites=poolMemberSitesOf(resolved);const featSites=featPickSites(resolved.classes,memberSites,ci=>{var _a2,_b2,_c2,_d2;return(_d2=(_c2=(_b2=(_a2=resolved.classes)==null?void 0:_a2[ci])==null?void 0:_b2.entity)==null?void 0:_c2.slug)!=null?_d2:null});resolved.classes.forEach((c,i)=>{var _a2,_b2,_c2,_d2,_e2,_f2,_g,_h;if(!c.entity)return;const entity=c.entity;const readAt=lvl=>id=>{var _a3;return(_a3=c.choices[lvl])==null?void 0:_a3[id]};const className=entity.name;if(i===0&&((_b2=(_a2=entity.skill_choices)==null?void 0:_a2.from)==null?void 0:_b2.length)){visit({kind:"select-proficiency",id:"skills",count:entity.skill_choices.count,domain:"skill",from:entity.skill_choices.from},readAt(1)("skills"),className,"class")}if(i===0)walk(entity.choices,readAt(1),className,"class");if(i===0)walk(classToolPicks(entity).decisions,readAt(1),className,"class");for(const rf of resolved.features){if(rf.source.kind!=="class"&&rf.source.kind!=="subclass")continue;const belongs=rf.source.kind==="class"?rf.source.slug===entity.slug:c.subclass!=null&&rf.source.slug===c.subclass.slug;if(!belongs)continue;const featureOwner=rf.source.kind==="subclass"?(_d2=(_c2=c.subclass)==null?void 0:_c2.name)!=null?_d2:className:className;for(const copy of(_e2=rf.foldedFrom)!=null?_e2:[])walk(copy.choices,readAt(copy.level),featureOwner,"class");walk(rf.feature.choices,readAt(rf.source.level),featureOwner,"class")}for(const site of featSites){if(site.classIndex!==i)continue;const feat=(_g=featBySlug.get(stripRef(site.slug)))!=null?_g:featOfSite(site,(_f2=resolved.feats)!=null?_f2:[]);if(!feat)continue;walk(feat.choices,site.read,feat.name,"feat")}for(const site of memberSites)if(site.classIndex===i)walk(site.choices,site.read,(_h=site.member.name)!=null?_h:className,"class")});if(resolved.race){const raceName=resolved.race.name;walk(resolved.race.choices,originRead("race"),raceName,"race");for(const t of(_c=resolved.race.traits)!=null?_c:[])walk(t.choices,originRead("race"),raceName,"race")}if(resolved.background){const bgName=resolved.background.name;walk(resolved.background.choices,originRead("background"),bgName,"background");walk(backgroundToolPicks(resolved.background).decisions,originRead("background"),bgName,"background");if(resolved.background.feature){const feature=resolved.background.feature;walk(feature.choices,originRead("background"),bgName,"background")}}for(const r of(_d=resolved.proficiencyReplacements)!=null?_d:[]){walk([r.choice],originRead(r.carrier.kind),replacementOwner(r),r.carrier.kind)}if(resolved.originFeatSlug){const of=featBySlug.get(resolved.originFeatSlug);if(of)walk(of.choices,id=>oc[`background:feat:${id}`],of.name,"feat")}for(const site of raceFeatSites(resolved.race,oc)){const rf=(_f=featBySlug.get(stripRef(site.slug)))!=null?_f:((_e=resolved.feats)!=null?_e:[]).find(f=>bareEntitySlug(f.slug)===bareEntitySlug(site.slug));if(rf)walk(rf.choices,site.read,rf.name,"feat")}}var filterToPool=(vals,pool)=>pool?vals.map(v=>matchPool(v,pool)).filter(v=>!!v):vals;function collectChosenProficiencies(resolved){const out={skills:[],expertise:[],languages:[],tools:[],weapons:[],saves:[]};forEachChosenProficiency(resolved,(bucket,value)=>{const list=out[bucket];if(!list.includes(value))list.push(value)});return out}function forEachChosenProficiency(resolved,on){const isAbility=v=>ABILITY_KEYS.includes(v);visitProficiencyChoices(resolved,(choice,stored,owner,ownerKind)=>{const selected=capAtCount(choice,stored);const vals=Array.isArray(selected)?selected:typeof selected==="string"?[selected]:[];if(choice.kind==="select-entity"&&choice.entity_type==="weapon"){if(choice.id==="weapon-mastery"||isTargetChoice(choice))return;for(const v of vals){const bare=bareEntitySlug(String(v));if(bare)on("weapons",bare,owner,ownerKind)}return}if(choice.kind!=="select-proficiency")return;const valid=filterToPool(vals,authoredProficiencyPool(choice));if(choice.domain==="save"){for(const v of valid)if(isAbility(v))on("saves",v,owner,ownerKind);return}const bucket=choice.domain==="skill"?choice.expertise?"expertise":"skills":choice.domain==="language"?"languages":choice.domain==="tool"?"tools":null;if(bucket)for(const v of valid)on(bucket,v,owner,ownerKind)})}function collectRuleProficiencySources(resolved){var _a,_b,_c,_d;const out={skills:{},expertise:{},saves:{}};const add=(rec,key,source)=>{var _a2;const list=(_a2=rec[key])!=null?_a2:rec[key]=[];if(!list.includes(source))list.push(source)};const firstClass=(_b=(_a=resolved.classes)==null?void 0:_a[0])==null?void 0:_b.entity;if(firstClass)for(const ab of(_c=firstClass.saving_throws)!=null?_c:[])add(out.saves,ab,firstClass.name);const bg=resolved.background;const replaced=new Set(pickedReplacements(resolved).map(({r})=>`${r.carrier.kind}:${r.domain}:${r.value}`));if(bg)for(const sk of(_d=bg.skill_proficiencies)!=null?_d:[]){if(!replaced.has(`background:skill:${toProfSlug(sk)}`))add(out.skills,sk,bg.name)}forEachChosenProficiency(resolved,(bucket,value,owner)=>{if(bucket==="skills"||bucket==="expertise"||bucket==="saves")add(out[bucket],value,owner)});const{features,activeBuffs}=assembleEffectFeatures(resolved);for(const rf of features){if(!foldsNow(rf,activeBuffs))continue;for(const eff of selfEffectsOf(rf.feature)){const c=classifyProficiencyEffect(eff);if(!c||c.bucket!=="skills"&&c.bucket!=="saves")continue;if(c.bucket==="skills"&&!c.expertise&&replaced.has(`${rf.source.kind}:skill:${toProfSlug(c.value)}`))continue;const named=grantSourceName(resolved,rf.source.kind,rf.source.slug);const source=named===UNKNOWN_GRANT_SOURCE?rf.feature.name:named;if(c.bucket==="saves")add(out.saves,c.value,source);else add(c.expertise?out.expertise:out.skills,c.value,source)}}return out}function pickedReplacements(resolved){var _a,_b;const oc=(_a=resolved.definition)==null?void 0:_a.origin_choices;const out=[];for(const r of(_b=resolved.proficiencyReplacements)!=null?_b:[]){const pick=replacementPick(r,oc);if(pick)out.push({r,pick})}return out}var STEP_RANK={race:0,class:1,background:2,other:3};var stepOf=k=>k==="race"?"race":k==="background"?"background":k==="class"||k==="subclass"?"class":"other";function collectProficiencyReplacements(resolved){var _a,_b,_c,_d,_e,_f,_g,_h,_i,_j,_k,_l;const base={...resolved,proficiencyReplacements:void 0};const bg=base.background;const race=base.race;if(!bg&&!race)return[];const grants={skill:new Map,tool:new Map};const note=(domain,raw,g)=>{var _a2;if(typeof raw!=="string"||!raw.trim())return;const v=toProfSlug(raw);const list=(_a2=grants[domain].get(v))!=null?_a2:[];if(!list.some(x=>x.step===g.step&&x.name===g.name&&x.fixed===g.fixed))list.push(g);grants[domain].set(v,list)};const strings=v=>Array.isArray(v)?v:[];const{features,activeBuffs}=assembleEffectFeatures(base);const fx=collectProficiencyEffectGrants(features,activeBuffs);const effectName=g=>grantSourceName(base,g.sourceKind,g.sourceSlug);for(const g of fx.skills)if(!g.expertise)note("skill",g.value,{name:effectName(g),step:stepOf(g.sourceKind),fixed:true});for(const g of fx.tools)note("tool",g.value,{name:effectName(g),step:stepOf(g.sourceKind),fixed:true});if(bg){for(const sk of strings(bg.skill_proficiencies))note("skill",sk,{name:bg.name,step:"background",fixed:true});for(const e of strings(bg.tool_proficiencies)){if(e&&typeof e==="object"&&e.kind==="fixed"){for(const t of strings(e.items))note("tool",t,{name:bg.name,step:"background",fixed:true})}}for(const t of backgroundToolPicks(bg).grants)note("tool",t,{name:bg.name,step:"background",fixed:true})}const carried=[...grants.skill.values(),...grants.tool.values()].some(list=>list.some(g=>g.fixed&&(g.step==="race"||g.step==="background")));if(!carried)return[];for(const c of(_a=base.classes)!=null?_a:[]){const e=c.entity;if(!e)continue;const tools=(_b=e.proficiencies)==null?void 0:_b.tools;for(const t of[...strings(tools==null?void 0:tools.fixed),...classToolPicks(e).grants])note("tool",t,{name:e.name,step:"class",fixed:true})}for(const f of(_c=base.feats)!=null?_c:[]){const tools=(_d=f.proficiencies)==null?void 0:_d.tools;for(const t of strings(tools))note("tool",t,{name:f.name,step:"other",fixed:true})}forEachChosenProficiency(base,(bucket,value,owner,kind)=>{if(bucket==="skills")note("skill",value,{name:owner,step:stepOf(kind),fixed:false});else if(bucket==="tools")note("tool",value,{name:owner,step:stepOf(kind),fixed:false})});const held={skill:new Set([...(_g=(_f=(_e=base.definition)==null?void 0:_e.skills)==null?void 0:_f.proficient)!=null?_g:[],...(_j=(_i=(_h=base.definition)==null?void 0:_h.skills)==null?void 0:_i.expertise)!=null?_j:[],...fx.skills.map(g=>g.value),...grants.skill.keys(),...collectChosenProficiencies(base).expertise].map(toProfSlug)),tool:new Set};let toolsHeld=false;const heldTools=()=>{if(!toolsHeld){toolsHeld=true;for(const e of computeEffectiveProficiencies(base).tools)held.tool.add(toProfSlug(e.value))}return held.tool};const candidates=[];const skillOrder=v=>{const i=ALL_SKILL_SLUGS.indexOf(v);return i<0?999:i};for(const domain of["skill","tool"]){const entries=[...grants[domain].entries()];if(domain==="skill")entries.sort(([a],[b])=>skillOrder(a)-skillOrder(b));for(const[value,list]of entries){const sources=[];for(const g of[...list].sort((a,b)=>STEP_RANK[a.step]-STEP_RANK[b.step])){if(!sources.some(x=>x.step===g.step&&x.name===g.name))sources.push(g)}const names=keep=>[...new Set(sources.filter(keep).map(g=>g.name))];const label=domain==="skill"?(_k=ALL_SKILLS.find(d=>toProfSlug(d)===value))!=null?_k:humanizeProficiency(value):humanizeProficiency(value);const id=replacementChoiceId(domain,value);const bgCarries=!!bg&&list.some(g=>g.step==="background"&&g.fixed)&&names(g=>g.step!=="background").length>0;if(bg&&bgCarries){candidates.push({domain,value,label,id,carrier:{kind:"background",slug:bg.slug,name:bg.name},others:names(g=>g.step!=="background")})}const raceOthers=names(g=>g.step!=="race"&&!(bgCarries&&g.step==="background"));if(race&&list.some(g=>g.step==="race"&&g.fixed)&&raceOthers.length>0){candidates.push({domain,value,label,id,carrier:{kind:"race",slug:race.slug,name:race.name},others:raceOthers})}}}const oc=(_l=base.definition)==null?void 0:_l.origin_choices;const picks=candidates.map(c=>replacementPick({carrier:c.carrier,choice:{id:c.id}},oc));return candidates.map((c,i)=>{const vocab=c.domain==="skill"?ALL_SKILL_SLUGS:ALL_TOOLS;const taken=new Set(picks.filter((p,j)=>j!==i&&p&&candidates[j].domain===c.domain));const own=picks[i];const have=c.domain==="skill"?held.skill:heldTools();const from=vocab.filter(v=>v===own||!have.has(v)&&!taken.has(v));const{id,...rest}=c;return{...rest,choice:{kind:"select-proficiency",id,label:`Already proficient in ${c.label}: pick a replacement`,count:1,domain:c.domain,from}}})}function proficiencyEntryFor(raw,vocab,origin,sources,expertise){const hit=matchPool(raw,vocab);const value=hit?toProfSlug(hit):raw;const label=hit?humanizeProficiency(value):origin==="custom"?raw:proficiencyLabel(raw);return{value,label,sources,origin,...expertise?{expertise:true}:{}}}function computeEffectiveProficiencies(resolved){const c=composeLanguageToolProficiencies(resolved);return{languages:c.languages.kept,tools:c.tools.kept}}function computeSuppressedProficiencies(resolved){const c=composeLanguageToolProficiencies(resolved);return{languages:c.languages.suppressed,tools:c.tools.suppressed}}function composeLanguageToolProficiencies(resolved){const grants=collectProficiencyGrants(resolved);const chosen=collectChosenProficiencies(resolved);const build=domain=>{var _a,_b,_c,_d,_e,_f,_g,_h;const vocab=domain==="languages"?ALL_LANGUAGES:ALL_TOOLS;const ov=(_b=(_a=resolved.definition)==null?void 0:_a.overrides)==null?void 0:_b[domain];const adds=(_c=ov==null?void 0:ov.add)!=null?_c:[];const removes=(_d=ov==null?void 0:ov.remove)!=null?_d:[];const byValue=new Map;const push=(raw,origin,source,expertise)=>{const probe=proficiencyEntryFor(raw,vocab,origin,source?[source]:[],expertise);const existing=byValue.get(probe.value);if(!existing){byValue.set(probe.value,probe);return}if(source&&!existing.sources.includes(source))existing.sources.push(source);if(expertise)existing.expertise=true;const rank={grant:0,pick:1,manual:2,custom:3};if(rank[origin]<rank[existing.origin])existing.origin=origin};const grantBuckets=domain==="languages"?[grants.raceLangFixed,grants.bgLangFixed,grants.featLanguages,grants.effectLanguages]:[grants.classToolFixed,grants.bgToolFixed,grants.featTools,grants.effectTools];const replacedTools=domain==="tools"?pickedReplacements(resolved).filter(({r})=>r.domain==="tool"):[];for(const b of grantBuckets)for(const g of b){if(replacedTools.some(({r})=>r.carrier.name===g.source&&r.value===toProfSlug(g.value)))continue;push(g.value,"grant",g.source,g.expertise)}for(const{r,pick}of replacedTools)push(pick,"pick",replacementOwner(r));for(const v of domain==="languages"?chosen.languages:chosen.tools)push(v,"pick");for(const v of adds)push(v,matchPool(v,vocab)?"manual":"custom");const triSuppressed=new Set;if(domain==="tools"){const tri=(_h=(_g=(_f=(_e=resolved.definition)==null?void 0:_e.overrides)==null?void 0:_f.tools)==null?void 0:_g.proficiency)!=null?_h:{};for(const[tool,state]of Object.entries(tri)){const key=toProfSlug(tool);if(state==="none"){triSuppressed.add(key);continue}let entry=[...byValue.values()].find(e=>toProfSlug(e.value)===key);if(!entry){push(tool,matchPool(tool,vocab)?"manual":"custom");entry=[...byValue.values()].find(e=>toProfSlug(e.value)===key)}if(!entry)continue;if(state==="expertise")entry.expertise=true;else delete entry.expertise}}const suppressed=new Set([...removes.map(r=>toProfSlug(r)),...triSuppressed]);const byLabel=(a,b)=>a.label<b.label?-1:a.label>b.label?1:0;const kept=[...byValue.values()].filter(e=>!suppressed.has(toProfSlug(e.value))).sort(byLabel);return{kept,suppressed:[...byValue.values()].filter(e=>suppressed.has(toProfSlug(e.value))).sort(byLabel)}};return{languages:build("languages"),tools:build("tools")}}function collectChosenAbilityPoints(resolved){var _a,_b,_c;const oc=(_a=resolved.definition.origin_choices)!=null?_a:{};const out={race:{},background:{}};const fold=(ns,choices)=>{var _a2;for(const ch of choices!=null?choices:[]){if(ch.kind!=="ability-points")continue;const raw=oc[`${ns}:${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[ns][ab]=((_a2=out[ns][ab])!=null?_a2:0)+take;left-=take}}};const race=resolved.race;if(race){fold("race",race.choices);for(const t of(_b=race.traits)!=null?_b:[])fold("race",t.choices)}const bg=resolved.background;if(bg){fold("background",bg.choices);fold("background",(_c=bg.feature)==null?void 0:_c.choices)}return out}function buildDecisionLedger(resolved,ctx){var _a,_b,_c,_d,_e,_f,_g,_h,_i,_j,_k,_l,_m,_n;const eff=computeEffectiveProficiencies(resolved);const chosen=collectChosenProficiencies(resolved);const{features,activeBuffs}=assembleEffectFeatures(resolved);const effectGrants=collectProficiencyEffectGrants(features,activeBuffs);const effective={language:new Set(eff.languages.map(e=>toProfSlug(e.value))),tool:new Set(eff.tools.map(e=>toProfSlug(e.value))),skill:new Set([...(_c=(_b=(_a=resolved.definition)==null?void 0:_a.skills)==null?void 0:_b.proficient)!=null?_c:[],...(_e=(_d=resolved.background)==null?void 0:_d.skill_proficiencies)!=null?_e:[],...chosen.skills,...effectGrants.skills.map(g=>g.value)].map(toProfSlug)),skillExpertise:new Set([...(_h=(_g=(_f=resolved.definition)==null?void 0:_f.skills)==null?void 0:_g.expertise)!=null?_h:[],...chosen.expertise,...effectGrants.skills.filter(g=>g.expertise).map(g=>g.value)].map(toProfSlug)),inventory:entityType=>inventoryOptions(resolved,ctx.registry,entityType)};const classes=[];resolved.classes.forEach((c,classIndex)=>{var _a2,_b2,_c2,_d2,_e2,_f2,_g2,_h2,_i2,_j2,_k2,_l2,_m2,_n2,_o;if(!c.entity)return;const entity=c.entity;const ownerBare=bareEntitySlug(entity.slug);const byLevel=new Map;const push=(lvl,item)=>{var _a3;const arr=(_a3=byLevel.get(lvl))!=null?_a3:[];arr.push(item);byLevel.set(lvl,arr)};const readAt=lvl=>id=>{var _a3;return(_a3=c.choices[lvl])==null?void 0:_a3[id]};let legacyAsiFeat;const legacyAsiReader=(choice,lvl)=>{const alloc=convertibleLegacyAsi(c.choices[lvl]);if(!alloc)return null;const flat=flattenAsiOrFeat(choice);if(flat.kind!=="select-entity"||flat.entity_type!=="feat"||flat.from||flat.where)return null;if(legacyAsiFeat===void 0)legacyAsiFeat=resolveLegacyAsiFeat(ctx.registry,entity);const asi=legacyAsiFeat;if(!asi)return null;const raw=readAt(lvl);const childKey=`feat:${asi.childId}`;return id=>id==="feat"?asi.slug:id===childKey?alloc:raw(id)};const featProgressions=[...(_a2=entity.feat_progression)!=null?_a2:[],...(_c2=(_b2=c.subclass)==null?void 0:_b2.feat_progression)!=null?_c2:[]];const suppressedFeatureTypes=new Set;for(const decl of[...(_d2=entity.selection_pools)!=null?_d2:[],...(_f2=(_e2=c.subclass)==null?void 0:_e2.selection_pools)!=null?_f2:[]]){const rp=resolved.pools.find(p=>p.classIndex===classIndex&&p.id===decl.id);if(rp&&rp.count>=1)suppressedFeatureTypes.add(decl.source.where.feature_type)}for(const entry of featProgressions){const category=featProgressionCategory(entry.category);const ft=category?FEATURE_TYPE_FOR_CATEGORY[category]:void 0;if(ft)suppressedFeatureTypes.add(ft)}if(classIndex===0&&((_h2=(_g2=entity.skill_choices)==null?void 0:_g2.from)==null?void 0:_h2.length)){const skillChoice={kind:"select-proficiency",id:"skills",label:"Skill Proficiencies",count:entity.skill_choices.count,domain:"skill",from:entity.skill_choices.from};push(1,buildItem(skillChoice,{kind:"class",slug:entity.slug,level:1},1,"Proficiencies",readAt(1),ctx,ownerBare,effective))}if(classIndex===0){for(const ch of[...(_i2=entity.choices)!=null?_i2:[],...classToolPicks(entity).decisions]){push(1,buildItem(ch,{kind:"class",slug:entity.slug,level:1},1,"Proficiencies",readAt(1),ctx,ownerBare,effective))}}if(classIndex===0){for(const ch of equipmentDecisions(entity.starting_equipment,entity.slug)){push(1,buildItem(ch,{kind:"class",slug:entity.slug,level:1},1,"Starting Equipment",readAt(1),ctx,ownerBare,effective))}}let sawAuthoredSubclass=false;const staged=[];const authoredRank=(kind,level,feature)=>{var _a3,_b3,_c3;const at=(_c3=(_b3=(_a3=kind==="class"?entity:c.subclass)==null?void 0:_a3.features_by_level)==null?void 0:_b3[level])!=null?_c3:[];const index=at.findIndex(f=>feature.id?f.id===feature.id:f.name===feature.name);return(kind==="class"?0:1)*1e6+(index<0?999999:index)};for(const rf of resolved.features){const src=rf.source;if(src.kind!=="class"&&src.kind!=="subclass")continue;const belongs=src.kind==="class"?src.slug===entity.slug:c.subclass!=null&&src.slug===c.subclass.slug;if(!belongs)continue;const lvl=src.level;const stage=(atLvl,item)=>{staged.push({level:atLvl,item,rank:authoredRank(src.kind,atLvl,rf.feature),seq:staged.length})};const emitChoices=(list,atLvl,name,description)=>{var _a3,_b3;for(const ch of list){if(ch.kind==="select-entity"&&ch.entity_type==="subclass"){sawAuthoredSubclass=true;stage(atLvl,buildSubclassItem(ch,src,atLvl,name,c,ctx,ownerBare,description));continue}let emitted=ch;if(ch.kind==="select-entity"){const columns=countColumnsFor(ch.id);const fromTable=columns?readTableColumn(entity.table,c.level,columns):null;if(fromTable!=null)emitted={...ch,count:Math.max((_a3=ch.count)!=null?_a3:1,fromTable)}}stage(atLvl,buildItem(emitted,src,atLvl,name,(_b3=legacyAsiReader(emitted,atLvl))!=null?_b3:readAt(atLvl),ctx,ownerBare,effective,{description}))}};const informationalItem=(atLvl,name,description)=>{var _a3,_b3;return{key:(_a3=rf.feature.id)!=null?_a3:name,source:src,level:atLvl,featureName:name,description,choice:{kind:"select-inline",id:(_b3=rf.feature.id)!=null?_b3:name,options:[{value:"_",label:"_"}]},options:[],selected:void 0,status:"informational",satisfied:false}};const emitCopy=copy=>{let list=copy.choices;if(!(list==null?void 0:list.length)){const recognized=recognizeDecision({id:rf.feature.id,name:copy.name,description:copy.description});if(recognized==="informational"){stage(copy.level,informationalItem(copy.level,copy.name,copy.prose));return}list=recognized!=null?recognized:void 0;if(list==null?void 0:list.length){list=list.filter(ch=>{var _a3;if(ch.kind!=="select-entity")return true;const ft=(_a3=ch.where)==null?void 0:_a3.feature_type;return!(ft!==void 0&&suppressedFeatureTypes.has(ft))})}}if(!(list==null?void 0:list.length)){if(copy.prose)stage(copy.level,informationalItem(copy.level,copy.name,copy.prose));return}emitChoices(list,copy.level,copy.name,copy.description)};for(const copy of(_j2=rf.foldedFrom)!=null?_j2:[])emitCopy({...copy,prose:copy.description});emitCopy({level:lvl,name:rf.feature.name,description:rf.feature.description,prose:rf.feature.description||(((_k2=rf.feature.entries)==null?void 0:_k2.length)?rf.feature.entries.join("\n\n"):void 0),choices:rf.feature.choices})}staged.sort((a,b)=>a.rank-b.rank||a.seq-b.seq);for(const s of staged)push(s.level,s.item);const subclassLevel=(_l2=entity.subclass_level)!=null?_l2:null;if(subclassLevel!=null&&subclassLevel<=c.level&&!sawAuthoredSubclass){const featureName=(_m2=entity.subclass_feature_name)!=null?_m2:"Subclass";const synthChoice={kind:"select-entity",id:"subclass",label:featureName,count:1,entity_type:"subclass",where:{parent_class:"self"}};push(subclassLevel,buildSubclassItem(synthChoice,{kind:"class",slug:entity.slug,level:subclassLevel},subclassLevel,featureName,c,ctx,ownerBare))}for(const pool of resolved.pools){if(pool.classIndex!==classIndex||pool.count<1)continue;const stranded=strandedPicks(pool);const strandedSlugs=new Set(stranded.map(e=>e.slug));const synth={kind:"select-entity",id:pool.id,label:pool.label,count:pool.count,entity_type:"optional-feature",from:[...pool.available.map(e=>e.slug),...stranded.map(e=>e.slug)]};const item=buildItem(synth,{kind:"class",slug:entity.slug,level:pool.anchorLevel},pool.anchorLevel,pool.label,()=>pool.selected.map(e=>e.key),ctx,ownerBare,effective);item.pool={id:pool.id,anchorLevel:pool.anchorLevel};const repeatables=pool.available.filter(e=>e.entity.repeatable===true);if(repeatables.length>0){item.repeatable=repeatables.map(e=>{var _a3,_b3;return{noteSlug:e.slug,itemChoice:(_a3=e.entity.item_choice)!=null?_a3:"learn",rows:resolveOptionRows(e.entity,ctx.registry,{edition:resolved.definition.edition,isEntityVisible:(_b3=ctx.isEntityVisible)==null?void 0:_b3.bind(ctx)})}})}for(const o of item.options)if(strandedSlugs.has(o.value))o.stranded=true;const memberChildren=[];for(const entry of pool.selected){for(const ch of memberChoices(entry.entity)){const child=buildItem(ch,{kind:"class",slug:entity.slug,level:pool.anchorLevel},pool.anchorLevel,entry.entity.name,readAt(pool.anchorLevel),ctx,ownerBare,effective,{keyPrefix:`${pool.id}:${entry.key}:`});child.parentLabel=entry.entity.name;memberChildren.push(child)}}if(memberChildren.length){item.children=memberChildren;if(item.status==="resolved"&&memberChildren.some(c2=>c2.status!=="resolved"))item.status="partial"}push(pool.anchorLevel,item)}for(const entry of featProgressions){const category=featProgressionCategory(entry.category);if(!category){warnOnce(`feat-progression-category:${entity.slug}:${entry.name}`,`Archivist: feat_progression "${entry.name}" on "${entity.slug}" carries no category this engine maps (${((_n2=entry.category)!=null?_n2:[]).join(", ")}); no decision is offered`);continue}const progression=entry.progression;if(Array.isArray(progression))continue;for(const key of Object.keys(progression)){const lvl=Number.parseInt(key,10);if(!Number.isInteger(lvl)||String(lvl)!==key)continue;if(lvl>c.level)continue;if(((_o=byLevel.get(lvl))!=null?_o:[]).some(i=>i.key==="feat")){warnOnce(`feat-progression-collision:${entity.slug}:${lvl}`,`Archivist: "${entry.name}" on "${entity.slug}" would add a second feat pick at level ${lvl}, where one already exists; skipping`);continue}const progressionChoice={kind:"select-entity",id:"feat",label:entry.name,count:1,entity_type:"feat",where:{category}};push(lvl,buildItem(progressionChoice,{kind:"class",slug:entity.slug,level:lvl},lvl,entry.name,readAt(lvl),ctx,ownerBare,effective))}}const levels=[...byLevel.entries()].sort(([a],[b])=>a-b).map(([level,items])=>({level,items}));classes.push({classIndex,levels})});const origin=[];const oc=(_i=resolved.definition.origin_choices)!=null?_i:{};const originRead=ns=>id=>oc[`${ns}:${id}`];const pushOrigin=(choices,ns,source,featureName,ownerBare,description)=>{for(const ch of choices!=null?choices:[]){origin.push(buildItem(ch,source,0,featureName,originRead(ns),ctx,ownerBare,effective,{description}))}};const pushReplacements=(kind,bare)=>{var _a2;for(const r of(_a2=resolved.proficiencyReplacements)!=null?_a2:[]){if(r.carrier.kind!==kind)continue;origin.push(buildItem(r.choice,{kind,slug:r.carrier.slug},0,r.carrier.name,originRead(kind),ctx,bare,effective,{description:replacementDescription(r)}))}};if(resolved.race){const bare=bareEntitySlug(resolved.race.slug);pushReplacements("race",bare);pushOrigin(resolved.race.choices,"race",{kind:"race",slug:resolved.race.slug},(_j=resolved.race.name)!=null?_j:"Race",bare);for(const t of(_k=resolved.race.traits)!=null?_k:[]){pushOrigin(t.choices,"race",{kind:"race",slug:resolved.race.slug},t.name,bare,t.description)}}if(resolved.background){const bare=bareEntitySlug(resolved.background.slug);pushReplacements("background",bare);pushOrigin([...(_l=resolved.background.choices)!=null?_l:[],...backgroundToolPicks(resolved.background).decisions],"background",{kind:"background",slug:resolved.background.slug},(_m=resolved.background.name)!=null?_m:"Background",bare);if(resolved.background.feature){pushOrigin(resolved.background.feature.choices,"background",{kind:"background",slug:resolved.background.slug},resolved.background.feature.name,bare,resolved.background.feature.description)}if(resolved.background.origin_feat){const originFeat=resolveOriginFeat(ctx.registry,resolved.background.origin_feat,resolved.background.slug);if(originFeat){const featSource={kind:"feat",slug:originFeat.feat.slug};const featBare=bareEntitySlug(originFeat.feat.slug);for(const ch of(_n=originFeat.feat.choices)!=null?_n:[]){origin.push(buildItem(ch,featSource,0,originFeat.display,originRead("background"),ctx,featBare,effective,{keyPrefix:"feat:"}))}}}for(const ch of equipmentDecisions(resolved.background.equipment,resolved.background.slug)){origin.push(buildItem(ch,{kind:"background",slug:resolved.background.slug},0,"Starting Equipment",originRead("background"),ctx,bare,effective))}}return{classes,origin}}var SLUG_RE=/^\[\[(.+?)\]\]$/;function stripSlug(ref){if(!ref)return null;const m=ref.match(SLUG_RE);return m?m[1]:ref}function resolveOriginFeat(entities,originFeatRef,ownerSlug){var _a,_b,_c;if(!originFeatRef)return null;const slug=wikilinkTailSlug(originFeatRef);const inner=originFeatRef.replace(/^\[\[/,"").replace(/\]\]$/,"").trim();const rawTail=(_b=(_a=inner.split("/").pop())==null?void 0:_a.trim())!=null?_b:"";const base=rawTail.replace(/\s*\([^()]*\)\s*$/,"").trim();const baseSlug=base&&base!==rawTail?wikilinkTailSlug(`[[${base}]]`):null;const baseInner=baseSlug?inner.slice(0,inner.length-rawTail.length)+base:null;const prefix=(ownerSlug==null?void 0:ownerSlug.includes("_"))?ownerSlug.slice(0,ownerSlug.indexOf("_")):null;const feats=bucketOf(entities,"feat");const byPath=p=>feats.find(f=>f.filePath===`${p}.md`||f.filePath.endsWith(`/${p}.md`));const sameCompendiumTail=s=>prefix?feats.find(f=>f.slug.startsWith(`${prefix}_feat_`)&&f.slug.endsWith(`_${s}`)):void 0;const anyTail=s=>feats.find(f=>f.slug.endsWith(`_${s}`));const tiers=[()=>{var _a2;return(_a2=feats.find(f=>f.slug===inner))!=null?_a2:feats.find(f=>f.slug===slug)},()=>byPath(inner),()=>baseInner?byPath(baseInner):void 0,()=>sameCompendiumTail(slug),()=>baseSlug?sameCompendiumTail(baseSlug):void 0,()=>anyTail(slug),()=>baseSlug?anyTail(baseSlug):void 0];let reg;let hitTier=0;for(let i=0;i<tiers.length&&!reg;i++){reg=tiers[i]();hitTier=i+1}if(!reg)return null;const variantName=baseSlug&&(hitTier===3||hitTier===5||hitTier===7)?rawTail:void 0;const data=reg.data;const feat=data.slug==null?{...data,slug:reg.slug}:data;return{feat,display:(_c=variantName!=null?variantName:feat.name)!=null?_c:slug}}var PCResolver=class{constructor(entities){this.entities=entities}get registry(){return this.entities}resolve(character){var _a,_b,_c,_d,_e,_f,_g,_h,_i,_j;const warnings=[];const lookup=(rawRef,type)=>{const slug=stripSlug(rawRef);if(!slug)return null;const reg=this.entities.getByTypeAndSlug(type,slug);if(!reg){warnings.push(`Slug [[${slug}]] not found in compendium as ${type}.`);return null}const data=reg.data;return data.slug==null?{...data,slug:reg.slug}:data};const race=withSubspeciesParent(lookup(character.race,"race"),this.entities);const background=lookup(character.background,"background");const classes=character.class.map(c=>({entity:lookup(c.name,"class"),level:c.level,subclass:lookup(c.subclass,"subclass"),choices:c.choices}));const memberSites=withoutStrandedSites(poolMemberSites(classes,this.entities),classes,this.entities,character.edition);const classSlugOf=i=>{var _a2,_b2,_c2,_d2,_e2;return(_e2=(_b2=(_a2=classes[i])==null?void 0:_a2.entity)==null?void 0:_b2.slug)!=null?_e2:stripSlug((_d2=(_c2=character.class[i])==null?void 0:_c2.name)!=null?_d2:null)};const featSites=featPickSites(character.class,memberSites,classSlugOf);const feats=[];const featVia=new Map;for(const site of featSites){const f=lookup(`[[${site.slug}]]`,"feat");if(!f)continue;if(!feats.some(x=>x.slug===f.slug))feats.push(f);if(site.via&&!featVia.has(f.slug))featVia.set(f.slug,site.via)}const originFeat=(background==null?void 0:background.origin_feat)?resolveOriginFeat(this.entities,background.origin_feat,background.slug):null;const originFeatSlug=originFeat==null?void 0:originFeat.feat.slug;if(originFeat&&!feats.some(f=>f.slug===originFeat.feat.slug)){feats.push(originFeat.feat)}if(originFeat&&background&&!featVia.has(originFeat.feat.slug)){featVia.set(originFeat.feat.slug,{kind:"background",slug:background.slug})}const raceFeats=[];for(const site of raceFeatSites(race,character.origin_choices)){const f=lookup(`[[${site.slug}]]`,"feat");if(!f)continue;raceFeats.push({feat:f,read:site.read});if(!feats.some(x=>x.slug===f.slug))feats.push(f);if(!featVia.has(f.slug))featVia.set(f.slug,site.via)}const totalLevel=classes.reduce((sum,c)=>sum+c.level,0);const features=collectResolvedFeatures(race,classes,background,feats,featVia);const extraFeatures=collectChosenGrantedFeatures(character,classes,this.entities,race,background,memberSites);features.push(...extraFeatures);const originChoices=(_a=character.origin_choices)!=null?_a:{};const featChoiceSites=[];for(const site of featSites){const f=lookup(`[[${site.slug}]]`,"feat");if(f)featChoiceSites.push({feat:f,via:site.via,read:site.read})}if(originFeat&&background){featChoiceSites.push({feat:originFeat.feat,via:{kind:"background",slug:background.slug},read:id=>originChoices[`background:feat:${id}`]})}for(const rf of raceFeats)featChoiceSites.push({feat:rf.feat,via:race?{kind:"race",slug:race.slug}:null,read:rf.read});features.push(...collectFeatChoiceGrants(featChoiceSites,this.entities));features.push(...collectAdditionalFeatures(character,this.entities,warnings));const casters=[];classes.forEach((c,i)=>{const profile=c.entity?resolveSpellcasting(c):null;const classSlug=profile?stripSlug(character.class[i].name):null;if(profile&&classSlug!=null)casters.push({classSlug,spellList:profile.spellList})});const spells=[];for(const raw of(_b=character.spells.known)!=null?_b:[]){const n=normalizeKnownSpell(raw);const reg=this.entities.getByTypeAndSlug("spell",n.slug);if(!reg){warnings.push(`Spell [[${n.slug}]] not found in compendium.`);continue}const entity=mirrorSpellShapes(reg.data);const isCantrip=((_c=entity.level)!=null?_c:0)===0;const classSlug=(_d=n.classSlug)!=null?_d:attributeUnclassedSpell(entity.classes,casters,this.entities);const prep=isCantrip||n.alwaysPrepared?true:(_e=n.preparedFlag)!=null?_e:false;spells.push({entity,slug:n.slug,classSlug,source:n.source,prepared:prep,alwaysPrepared:n.alwaysPrepared,persisted:true})}const oc=(_f=character.origin_choices)!=null?_f:{};if(originFeat){const read=childId=>oc[`background:feat:${childId}`];spells.push(...collectFeatGrantedSpells(originFeat.feat,read,this.entities,warnings))}for(const rf of raceFeats)spells.push(...collectFeatGrantedSpells(rf.feat,rf.read,this.entities,warnings));for(const site of featSites){const reg=this.entities.getByTypeAndSlug("feat",site.slug);if(!reg)continue;const feat=reg.data;spells.push(...collectFeatGrantedSpells(feat,site.read,this.entities,warnings))}for(const site of memberSites){const classSlug=stripSlug((_h=(_g=character.class[site.classIndex])==null?void 0:_g.name)!=null?_h:null);for(const ch of site.choices){if(ch.kind!=="select-entity"||ch.entity_type!=="spell"||isTargetChoice(ch))continue;const v=site.read(ch.id);for(const ref of Array.isArray(v)?v:typeof v==="string"?[v]:[]){const slug=typeof ref==="string"?stripSlug(ref):null;if(!slug)continue;const reg=this.entities.getByTypeAndSlug("spell",slug);if(!reg){warnings.push(`Spell [[${slug}]] not found in compendium.`);continue}const entity=mirrorSpellShapes(reg.data);spells.push({entity,slug,classSlug,source:"class",prepared:true,alwaysPrepared:true})}}}const ownSpellcastingAbility=(_i=classes.map(c=>{if(!c.entity)return null;const p=resolveSpellcasting(c);return p?effectiveSpellcastingAbility(c.entity.slug,p.ability,character.overrides):null}).find(a=>a!=null))!=null?_i:null;spells.push(...collectItemGrantedSpells(character,ownSpellcastingAbility,this.entities,warnings));const chosenMasteries=collectChosenWeaponMasteries(character);if(chosenMasteries.full.length>0){const target=features.find(rf=>{var _a2;return rf.feature.id==="weapon-mastery"||((_a2=rf.feature.choices)==null?void 0:_a2.some(ch=>ch.kind==="select-entity"&&ch.id==="weapon-mastery"&&ch.entity_type==="weapon"))});if(target){const names=chosenMasteries.full.map(fullSlug=>{var _a2,_b2;return(_b2=(_a2=this.entities.getByTypeAndSlug("weapon",fullSlug))==null?void 0:_a2.name)!=null?_b2:fullSlug});const entry={label:"Mastered weapons",description:names.join(", ")};target.chosenInline=target.chosenInline?[...target.chosenInline,entry]:[entry]}}const featureResources=resolveFeatureResources(features);const resolvedCharacter={definition:character,race,classes,background,feats,...originFeatSlug?{originFeatSlug}:{},totalLevel,features,spells:[],pools:[],resources:featureResources,weaponMasteries:chosenMasteries.bare,...(()=>{var _a2;const p=(_a2=pactWeaponPick(memberSites))!=null?_a2:classPactWeaponPick(character,classes);return p?{pactWeapon:p}:{}})(),state:character.state};resolvedCharacter.pools=resolveAllPools(resolvedCharacter,this.entities,featureResources);spells.push(...collectAdditionalSpells({race,feats,classes,totalLevel,ownAbility:ownSpellcastingAbility,alreadyCollected:spells,entities:this.entities,warnings,raceChoice:id=>oc[`race:${id}`],pools:resolvedCharacter.pools}));resolvedCharacter.spells=dedupeResolvedSpells(spells);resolvedCharacter.resources=resolveResourceIndex(resolvedCharacter);resolvedCharacter.features=bindFeatureConsumers(resolvedCharacter.features,resolvedCharacter.resources,classes);const infusions=buildInfusionContext(character,resolvedCharacter,this.entities);if(infusions)resolvedCharacter.infusions=infusions;const itemFeatures=buildItemFeatures((_j=character.equipment)!=null?_j:[],this.entities,infusions,warnings);if(itemFeatures.length)resolvedCharacter.itemFeatures=itemFeatures;try{resolvedCharacter.proficiencyReplacements=collectProficiencyReplacements(resolvedCharacter)}catch(e){resolvedCharacter.proficiencyReplacements=[];warnings.push(`Duplicate proficiency check skipped: ${e instanceof Error?e.message:String(e)}`)}return{character:resolvedCharacter,warnings}}};function collectChosenWeaponMasteries(character){var _a,_b;const full=new Set;for(const cls of(_a=character.class)!=null?_a:[]){for(const lvl of Object.values((_b=cls.choices)!=null?_b:{})){const pick=lvl["weapon-mastery"];if(Array.isArray(pick)){for(const s of pick)if(typeof s==="string")full.add(s)}}}return{full:[...full],bare:[...new Set([...full].map(bareEntitySlug))]}}function collectFeatPicks(character){const picks=new Map;for(const site of featPickSites(character.class,[],()=>null)){if(!picks.has(site.slug))picks.set(site.slug,{slug:site.slug,classIndex:site.classIndex,level:site.level})}return[...picks.values()]}function collectFeatGrantedSpells(feat,read,entities,warnings){var _a;const ability=readChosenSpellAbility(read);const slugs=[];collectSpellPickSlugs(feat.choices,read,slugs);const out=[];for(const rawSlug of slugs){const slug=(_a=stripSlug(rawSlug))!=null?_a:rawSlug;const reg=entities.getByTypeAndSlug("spell",slug);if(!reg){warnings.push(`Feat spell [[${slug}]] not found in compendium.`);continue}const entity=mirrorSpellShapes(reg.data);out.push({entity,slug,classSlug:null,source:"feat",prepared:true,alwaysPrepared:true,ability})}return out}function collectItemGrantedSpells(character,ownAbility,entities,warnings){var _a;const out=[];((_a=character.equipment)!=null?_a:[]).forEach((entry,entryIndex)=>{var _a2,_b,_c,_d,_e,_f;const spellRef=(_a2=entry.overrides)==null?void 0:_a2.spell;if(!spellRef)return;const{entity:itemEntity}=resolveEntityForEntry(entry.item,entities);const scrollLevel=isItemEntity(itemEntity)?itemEntity.scroll_level:void 0;if(scrollLevel==null)return;const slug=(_b=stripSlug(spellRef))!=null?_b:spellRef;const reg=entities.getByTypeAndSlug("spell",slug);if(!reg){warnings.push(`Scroll spell [[${slug}]] not found in compendium.`);return}const entity=mirrorSpellShapes(reg.data);const ability=(_f=(_d=(_c=entry.overrides)==null?void 0:_c.spell_ability)!=null?_d:ownAbility)!=null?_f:(_e=character.overrides)==null?void 0:_e.spellcasting_ability;const itemCasting=storedSpellNumbers(itemEntity);out.push({entity,slug,classSlug:null,source:"item",prepared:true,alwaysPrepared:true,ability,entryIndex,...itemCasting?{itemCasting}:{}})});return out}function dedupeResolvedSpells(spells){const byKey=new Map;for(const s of spells){const key=s.source==="item"?`${s.slug}#${s.entryIndex}`:s.atWill?`${s.slug}#atwill`:s.slug;const existing=byKey.get(key);if(!existing){byKey.set(key,s);continue}if(existing.source==="feat"&&s.source!=="feat"){byKey.set(key,{...s,alwaysPrepared:s.alwaysPrepared||existing.alwaysPrepared,prepared:s.prepared||existing.alwaysPrepared,...existing.persisted||s.persisted?{persisted:true}:{}})}else if(s.alwaysPrepared&&!existing.alwaysPrepared){byKey.set(key,{...existing,alwaysPrepared:true,prepared:true})}}return[...byKey.values()]}function readChosenSpellAbility(read){const pick=read("spellcasting-ability");return typeof pick==="string"&&ABILITY_KEYS.includes(pick)?pick:null}function collectSpellPickSlugs(choices,read,out){for(const ch of choices!=null?choices:[]){if(ch.kind==="select-entity"&&ch.entity_type==="spell"){const sel=read(ch.id);const picks=Array.isArray(sel)?sel:typeof sel==="string"?[sel]:[];for(const p of picks)if(typeof p==="string"&&p.length>0)out.push(p)}else if(ch.kind==="select-inline"){const sel=read(ch.id);const branch=typeof sel==="string"?ch.options.find(o=>o.value===sel):void 0;if(branch==null?void 0:branch.choices)collectSpellPickSlugs(branch.choices,read,out)}}}function collectChosenGrantedFeatures(character,classes,registry,race=null,background=null,memberSites=[]){var _a,_b,_c,_d;const out=[];for(const site of memberSites){const classSlug=(_b=(_a=classes[site.classIndex])==null?void 0:_a.entity)==null?void 0:_b.slug;if(!classSlug)continue;const at={};const grants=site.choices.filter(ch=>!isTargetChoice(ch));for(const ch of grants)at[ch.id]=site.read(ch.id);walkChoiceGrants(grants,at,(granted,suppress)=>{out.push({feature:granted,source:{kind:"class",slug:classSlug,level:site.level},...suppress?{renderSuppressed:true}:{}})},registry)}classes.forEach((c,i)=>{var _a2,_b2,_c2,_d2;if(!c.entity)return;const entity=c.entity;const entry=character.class[i];if(!entry)return;for(const[lvlStr,atLevel]of Object.entries(entry.choices)){const lvl=Number(lvlStr);if(!Number.isFinite(lvl)||lvl>entry.level)continue;const features=(_b2=((_a2=entity.features_by_level)!=null?_a2:{})[lvl])!=null?_b2:[];const subFeatures=c.subclass?(_d2=((_c2=c.subclass.features_by_level)!=null?_c2:{})[lvl])!=null?_d2:[]:[];for(const feature of[...features,...subFeatures]){walkChoiceGrants(feature.choices,atLevel,(granted,suppress)=>{out.push({feature:granted,source:{kind:"class",slug:entity.slug,level:lvl},...suppress?{renderSuppressed:true}:{}})},registry)}}});const oc=(_c=character.origin_choices)!=null?_c:{};const originAt=ns=>{const at={};for(const[key,val]of Object.entries(oc)){if(key.startsWith(`${ns}:`))at[key.slice(ns.length+1)]=val}return at};if(race){const atRace=originAt("race");const emitRace=(granted,suppress)=>{out.push({feature:granted,source:{kind:"race",slug:race.slug},...suppress?{renderSuppressed:true}:{}})};walkChoiceGrants(race.choices,atRace,emitRace,registry);for(const trait of(_d=race.traits)!=null?_d:[]){walkChoiceGrants(trait.choices,atRace,emitRace,registry)}}if(background){const atBg=originAt("background");const emitBg=(granted,suppress)=>{out.push({feature:granted,source:{kind:"background",slug:background.slug},...suppress?{renderSuppressed:true}:{}})};walkChoiceGrants(background.choices,atBg,emitBg,registry);if(background.feature){walkChoiceGrants(background.feature.choices,atBg,emitBg,registry)}}return out}function choiceIdsOf(choices,out=[]){for(const ch of choices!=null?choices:[]){out.push(ch.id);if(ch.kind==="select-inline")for(const o of ch.options)choiceIdsOf(o.choices,out)}return out}function collectFeatChoiceGrants(sites,registry){var _a;const out=[];for(const site of sites){const choices=(_a=site.feat.choices)!=null?_a:[];if(!choices.length)continue;const at={};for(const id of choiceIdsOf(choices))at[id]=site.read(id);const source={kind:"feat",slug:site.feat.slug,...site.via?{via:site.via}:{}};walkChoiceGrants(choices,at,granted=>{var _a2;out.push({feature:{...granted,name:(_a2=site.feat.name)!=null?_a2:granted.name},source,renderSuppressed:true})},registry,{inlineOnly:true})}return out}function collectAdditionalFeatures(character,entities,warnings){var _a,_b,_c,_d,_e,_f,_g,_h;const out=[];for(const entry of(_a=character.additional_features)!=null?_a:[]){const slug=(_b=stripSlug(entry))!=null?_b:entry;const reg=entities.getByTypeAndSlug("optional-feature",slug);if(!reg){warnings.push(`Granted feature [[${slug}]] not found in compendium as optional-feature.`);continue}const d=reg.data;const feature={id:(_c=d.slug)!=null?_c:slug,name:(_d=d.name)!=null?_d:slug,description:d.description,...((_e=d.effects)==null?void 0:_e.length)?{effects:d.effects}:{},...d.action_cost?{action:d.action_cost}:{},...d.passive!==void 0?{passive:d.passive}:{},...d.activatable!==void 0?{activatable:d.activatable}:{},...d.duration?{duration:d.duration}:{},...d.consumes?{consumes:d.consumes}:{}};const uses=d.uses;if(uses){const maxFormula=String(uses.max);if(isValidMaxFormula(maxFormula)){feature.resources=[{id:(_f=d.slug)!=null?_f:slug,name:(_g=d.name)!=null?_g:slug,max_formula:maxFormula,reset:uses.recharge,...((_h=uses.recovery)==null?void 0:_h.length)?{recovery:uses.recovery}:{},...d.rendering_hint?{rendering_hint:d.rendering_hint}:{},...d.surface?{surface:d.surface}:{}}]}else{warnings.push(`Granted feature "${slug}" has a prose uses.max (${JSON.stringify(uses.max)}); no tracker.`)}}out.push({feature,source:{kind:"campaign",slug}})}return out}function walkChoiceGrants(choices,atLevel,emit,registry,opts={}){var _a,_b,_c,_d,_e;for(const ch of choices!=null?choices:[]){const sel=atLevel[ch.id];if(!opts.inlineOnly&&ch.kind==="select-entity"&&ch.entity_type==="optional-feature"){const slugs=Array.isArray(sel)?sel:typeof sel==="string"?[sel]:[];for(const slug of slugs){const reg=registry.getByTypeAndSlug("optional-feature",(_a=stripSlug(String(slug)))!=null?_a:String(slug));if(!reg)continue;const d=reg.data;emit({id:(_b=d.slug)!=null?_b:String(slug),name:(_c=d.name)!=null?_c:String(slug),description:d.description,effects:d.effects,...d.action_cost?{action:d.action_cost}:{}})}}if(ch.kind==="select-inline"){const picks=Array.isArray(sel)?sel.filter(v=>typeof v==="string"):typeof sel==="string"?[sel]:[];for(const value of picks){const branch=ch.options.find(o=>o.value===value);if((_d=branch==null?void 0:branch.effects)==null?void 0:_d.length){const wc=(_e=branch.choices)==null?void 0:_e.find(c=>c.kind==="select-entity"&&c.entity_type==="weapon");const picked=wc?atLevel==null?void 0:atLevel[wc.id]:void 0;const effects=branch.effects.map(e=>e.kind==="weapon-ability"&&e.weapons==="chosen"&&typeof picked==="string"?{...e,weapons:[bareEntitySlug(picked)]}:e);emit({id:`${ch.id}-${branch.value}`,name:branch.label,description:branch.description,effects},true)}if(branch==null?void 0:branch.choices)walkChoiceGrants(branch.choices,atLevel,emit,registry,opts)}}}}function resolveChosenInline(feature,atLevel){var _a;if(!atLevel)return void 0;const picks=[];for(const ch of(_a=feature.choices)!=null?_a:[]){if(ch.kind!=="select-inline")continue;const sel=atLevel[ch.id];if(typeof sel!=="string")continue;const opt=ch.options.find(o=>o.value===sel);if(!opt)continue;picks.push({label:opt.label,description:opt.description})}return picks.length?picks:void 0}function isAsiSlotFeature(feature){var _a,_b,_c,_d;return feature.id==="ability-score-improvement"&&!((_a=feature.effects)!=null?_a:[]).some(e=>!(e.kind==="ability-score-increase"&&e.abilities==="chosen"))&&!((_b=feature.resources)==null?void 0:_b.length)&&!feature.action&&!((_c=feature.sub_features)==null?void 0:_c.length)&&!((_d=feature.attacks)==null?void 0:_d.length)}function foldRepeated(list){const byId=new Map;for(const rf of list){const id=rf.feature.id;if(!id||rf.buildOnly)continue;const arr=byId.get(id);if(arr)arr.push(rf);else byId.set(id,[rf])}const out=[];for(const rf of list){if(!rf.feature.id||rf.buildOnly){out.push(rf);continue}const arr=byId.get(rf.feature.id);if(!arr||arr.length===1){out.push(rf);continue}const sorted=[...arr].sort((a,b)=>a.source.level-b.source.level);const top=sorted[sorted.length-1];if(rf!==top)continue;const effects=sorted.flatMap(c=>{var _a;return(_a=c.feature.effects)!=null?_a:[]});const seen=new Set;const resources=sorted.flatMap(c=>{var _a;return((_a=c.feature.resources)!=null?_a:[]).filter(r=>!seen.has(r.id)&&seen.add(r.id))});const chosenInline=sorted.flatMap(c=>c.chosenInline?[c.chosenInline]:[]);const cardProse=f=>{var _a,_b;return(_b=f.description)!=null?_b:((_a=f.entries)==null?void 0:_a.length)?f.entries.join("\n\n"):void 0};const foldedFrom=sorted.slice(0,-1).map(c=>{var _a;return{level:c.source.level,name:c.feature.name,...cardProse(c.feature)?{description:cardProse(c.feature)}:{},...((_a=c.feature.choices)==null?void 0:_a.length)?{choices:c.feature.choices}:{}}});out.push({...top,feature:{...top.feature,...effects.length?{effects}:{},...resources.length?{resources}:{}},...chosenInline.length?{chosenInline:chosenInline.flat()}:{},...foldedFrom.length?{foldedFrom}:{}})}return out}function collectResolvedFeatures(race,classes,background,feats,featVia=new Map){var _a,_b,_c,_d,_e,_f,_g,_h,_i,_j,_k,_l,_m,_n,_o;const out=[];for(const c of classes){if(!c.entity)continue;const slug=c.entity.slug;const byLevel=(_a=c.entity.features_by_level)!=null?_a:{};const classFeatures=[];const subclassFeatures=[];for(const[lvlStr,feats0]of Object.entries(byLevel)){const lvl=parseInt(lvlStr,10);if(Number.isNaN(lvl)||lvl>c.level)continue;for(const feat of feats0){const chosenInline=resolveChosenInline(feat,(_b=c.choices)==null?void 0:_b[lvl]);const feature=withResolvedActionCost(feat);classFeatures.push({feature,source:{kind:"class",slug,level:lvl},...chosenInline?{chosenInline}:{},...isAsiSlotFeature(feature)?{buildOnly:true}:{}})}}if(c.subclass){const sSlug=c.subclass.slug;const sByLevel=(_c=c.subclass.features_by_level)!=null?_c:{};for(const[lvlStr,feats0]of Object.entries(sByLevel)){const lvl=parseInt(lvlStr,10);if(Number.isNaN(lvl)||lvl>c.level)continue;for(const feat of feats0){const chosenInline=resolveChosenInline(feat,(_d=c.choices)==null?void 0:_d[lvl]);const feature=withResolvedActionCost(feat);subclassFeatures.push({feature,source:{kind:"subclass",slug:sSlug,level:lvl},...chosenInline?{chosenInline}:{},...isAsiSlotFeature(feature)?{buildOnly:true}:{}})}}}const foldedClass=foldRepeated(classFeatures);const foldedSubclass=foldRepeated(subclassFeatures);out.push(...foldedClass);if((_e=c.entity.resources)==null?void 0:_e.length){out.push({feature:{name:c.entity.name,resources:c.entity.resources},source:{kind:"class",slug,level:1}})}out.push(...foldedSubclass);if((_g=(_f=c.subclass)==null?void 0:_f.resources)==null?void 0:_g.length){out.push({feature:{name:c.subclass.name,resources:c.subclass.resources},source:{kind:"subclass",slug:c.subclass.slug,level:1}})}}if(race){const traits=(_h=race.traits)!=null?_h:[];for(const feat of traits){out.push({feature:withResolvedActionCost(feat),source:{kind:"race",slug:race.slug}})}}if(background){const bgFeature=background.feature;if(bgFeature){out.push({feature:withResolvedActionCost(bgFeature),source:{kind:"background",slug:background.slug}})}}for(const feat of feats){const via=featVia.get(feat.slug);const featSource={kind:"feat",slug:feat.slug,...via?{via}:{}};const bundled=(_i=feat.features)!=null?_i:[];const entityEffects=(_j=feat.effects)!=null?_j:[];if(bundled.length>0){bundled.forEach((f,i)=>{var _a2,_b2;const feature=i===0?{...f,action:(_a2=f.action)!=null?_a2:feat.action_cost,...entityEffects.length>0?{effects:[...(_b2=f.effects)!=null?_b2:[],...entityEffects]}:{}}:f;out.push({feature,source:featSource})})}else{const name=(_k=feat.name)!=null?_k:feat.slug;const foldedDesc=[feat.description,...(_l=feat.benefits)!=null?_l:[]].filter(Boolean).join("\n\n")||void 0;const buildOnly=((_m=feat.choices)!=null?_m:[]).some(c=>c.kind==="ability-points"&&c.points>=2)&&!((_n=feat.effects)==null?void 0:_n.length)&&!((_o=feat.resources)==null?void 0:_o.length)&&bundled.length===0;out.push({feature:{name,...foldedDesc?{description:foldedDesc}:{},...feat.resources?{resources:feat.resources}:{},...feat.action_cost?{action:feat.action_cost}:{},...entityEffects.length>0?{effects:entityEffects}:{}},source:featSource,...buildOnly?{buildOnly:true}:{}})}}return out}export{stripSlug,resolveOriginFeat,PCResolver,collectChosenWeaponMasteries,collectFeatPicks,collectFeatGrantedSpells,collectItemGrantedSpells,dedupeResolvedSpells,collectChosenGrantedFeatures,collectFeatChoiceGrants,collectAdditionalFeatures,collectResolvedFeatures,collectProficiencyGrants,__matchesFilterForTest,__categoryToEntitySelectForTest,collectChosenProficiencies,collectRuleProficiencySources,collectProficiencyReplacements,computeEffectiveProficiencies,computeSuppressedProficiencies,collectChosenAbilityPoints,buildDecisionLedger};
@@ -1 +1 @@
1
- import{resolveSpellcasting}from"./chunk-PFQPP77Q.js";import{heldPicks}from"./chunk-PKIMOVQG.js";import{warnOnce}from"./chunk-DZITM5AG.js";import{isValidMaxFormula}from"./chunk-EAARMPCW.js";function resourceLevelFor(source,resolved){var _a,_b,_c,_d;if(source.kind==="class"){return(_b=(_a=resolved.classes.find(c=>{var _a2;return((_a2=c.entity)==null?void 0:_a2.slug)===source.slug}))==null?void 0:_a.level)!=null?_b:resolved.totalLevel}if(source.kind==="subclass"){return(_d=(_c=resolved.classes.find(c=>{var _a2;return((_a2=c.subclass)==null?void 0:_a2.slug)===source.slug}))==null?void 0:_c.level)!=null?_d:resolved.totalLevel}return resolved.totalLevel}function resolveRecovery(entry){var _a;const kind=(_a=entry.restores)!=null?_a:"uses";const restTriggered=(entry.reset==="short-rest"||entry.reset==="long-rest")&&!entry.action;const flavour=kind==="spell-slots"?"manual":restTriggered?"rest":"manual";return{entry,kind,flavour}}function toResolvedResource(r,fallbackName,owner){var _a,_b,_c;return{id:r.id,name:(_a=r.name)!=null?_a:fallbackName,reset:r.reset,maxFormula:r.max_formula,...r.die?{die:r.die}:{},...r.scales_at?{scalesAt:r.scales_at}:{},...((_b=r.recovery)==null?void 0:_b.length)?{recovery:r.recovery.map(resolveRecovery)}:{},...r.rendering_hint?{renderingHint:r.rendering_hint}:{},...r.surface?{surface:r.surface}:{},...((_c=r.equivalent_ids)==null?void 0:_c.length)?{equivalentIds:r.equivalent_ids}:{},owner}}function resolveFeatureResources(features){var _a,_b;const out=new Map;for(const rf of features){for(const r of(_a=rf.feature.resources)!=null?_a:[]){if(out.has(r.id))continue;const owner={kind:"feature",featureId:(_b=rf.feature.id)!=null?_b:rf.feature.name,featureName:rf.feature.name,source:rf.source};out.set(r.id,toResolvedResource(r,rf.feature.name,owner))}}return out}function pickResourceId(entry){return entry.param!=null?entry.key:entry.slug}function resolveResourceIndex(resolved){var _a,_b,_c,_d;const out=new Map(resolveFeatureResources((_a=resolved.features)!=null?_a:[]));for(const pool of(_b=resolved.pools)!=null?_b:[]){const rc=resolved.classes[pool.classIndex];const classSlug=(_c=rc==null?void 0:rc.entity)==null?void 0:_c.slug;if(!classSlug)continue;for(const entry of[...heldPicks(pool),...(_d=pool.grants)!=null?_d:[]]){if(entry.itemBound===true)continue;const uses=entry.entity.uses;const id=pickResourceId(entry);if(!uses||out.has(id))continue;const maxFormula=String(uses.max);if(!isValidMaxFormula(maxFormula)){warnOnce(`pool-uses:${entry.slug}`,`optional feature "${entry.slug}" has a prose uses.max (${JSON.stringify(uses.max)}); no tracker`);continue}const pres=entry.entity;out.set(id,{id,name:entry.entity.name,reset:uses.recharge,maxFormula,...pres.rendering_hint?{renderingHint:pres.rendering_hint}:{},...pres.surface?{surface:pres.surface}:{},owner:{kind:"pool",poolId:pool.id,poolLabel:pool.label,source:{kind:"class",slug:classSlug,level:pool.anchorLevel}}})}}return out}function poolSaveDC(resolved,derived,pool){var _a,_b;const rc=resolved.classes[pool.classIndex];const ability=(_b=(_a=rc==null?void 0:rc.subclass)==null?void 0:_a.spellcasting)==null?void 0:_b.ability;if(!rc||!ability)return null;if(resolveSpellcasting(rc)!==null)return null;return 8+derived.proficiencyBonus+derived.mods[ability]}export{resourceLevelFor,resolveRecovery,resolveFeatureResources,pickResourceId,resolveResourceIndex,poolSaveDC};
1
+ import{resolveSpellcasting}from"./chunk-PFQPP77Q.js";import{heldPicks}from"./chunk-E4E6YEN6.js";import{warnOnce}from"./chunk-DZITM5AG.js";import{isValidMaxFormula}from"./chunk-EAARMPCW.js";function resourceLevelFor(source,resolved){var _a,_b,_c,_d;if(source.kind==="class"){return(_b=(_a=resolved.classes.find(c=>{var _a2;return((_a2=c.entity)==null?void 0:_a2.slug)===source.slug}))==null?void 0:_a.level)!=null?_b:resolved.totalLevel}if(source.kind==="subclass"){return(_d=(_c=resolved.classes.find(c=>{var _a2;return((_a2=c.subclass)==null?void 0:_a2.slug)===source.slug}))==null?void 0:_c.level)!=null?_d:resolved.totalLevel}return resolved.totalLevel}function resolveRecovery(entry){var _a;const kind=(_a=entry.restores)!=null?_a:"uses";const restTriggered=(entry.reset==="short-rest"||entry.reset==="long-rest")&&!entry.action;const flavour=kind==="spell-slots"?"manual":restTriggered?"rest":"manual";return{entry,kind,flavour}}function toResolvedResource(r,fallbackName,owner){var _a,_b,_c;return{id:r.id,name:(_a=r.name)!=null?_a:fallbackName,reset:r.reset,maxFormula:r.max_formula,...r.die?{die:r.die}:{},...r.scales_at?{scalesAt:r.scales_at}:{},...((_b=r.recovery)==null?void 0:_b.length)?{recovery:r.recovery.map(resolveRecovery)}:{},...r.rendering_hint?{renderingHint:r.rendering_hint}:{},...r.surface?{surface:r.surface}:{},...((_c=r.equivalent_ids)==null?void 0:_c.length)?{equivalentIds:r.equivalent_ids}:{},owner}}function resolveFeatureResources(features){var _a,_b;const out=new Map;for(const rf of features){for(const r of(_a=rf.feature.resources)!=null?_a:[]){if(out.has(r.id))continue;const owner={kind:"feature",featureId:(_b=rf.feature.id)!=null?_b:rf.feature.name,featureName:rf.feature.name,source:rf.source};out.set(r.id,toResolvedResource(r,rf.feature.name,owner))}}return out}function pickResourceId(entry){return entry.param!=null?entry.key:entry.slug}function resolveResourceIndex(resolved){var _a,_b,_c,_d;const out=new Map(resolveFeatureResources((_a=resolved.features)!=null?_a:[]));for(const pool of(_b=resolved.pools)!=null?_b:[]){const rc=resolved.classes[pool.classIndex];const classSlug=(_c=rc==null?void 0:rc.entity)==null?void 0:_c.slug;if(!classSlug)continue;for(const entry of[...heldPicks(pool),...(_d=pool.grants)!=null?_d:[]]){if(entry.itemBound===true)continue;const uses=entry.entity.uses;const id=pickResourceId(entry);if(!uses||out.has(id))continue;const maxFormula=String(uses.max);if(!isValidMaxFormula(maxFormula)){warnOnce(`pool-uses:${entry.slug}`,`optional feature "${entry.slug}" has a prose uses.max (${JSON.stringify(uses.max)}); no tracker`);continue}const pres=entry.entity;out.set(id,{id,name:entry.entity.name,reset:uses.recharge,maxFormula,...pres.rendering_hint?{renderingHint:pres.rendering_hint}:{},...pres.surface?{surface:pres.surface}:{},owner:{kind:"pool",poolId:pool.id,poolLabel:pool.label,source:{kind:"class",slug:classSlug,level:pool.anchorLevel}}})}}return out}function poolSaveDC(resolved,derived,pool){var _a,_b;const rc=resolved.classes[pool.classIndex];const ability=(_b=(_a=rc==null?void 0:rc.subclass)==null?void 0:_a.spellcasting)==null?void 0:_b.ability;if(!rc||!ability)return null;if(resolveSpellcasting(rc)!==null)return null;return 8+derived.proficiencyBonus+derived.mods[ability]}export{resourceLevelFor,resolveRecovery,resolveFeatureResources,pickResourceId,resolveResourceIndex,poolSaveDC};
@@ -0,0 +1 @@
1
+ import{slugify}from"./chunk-63YJPWTM.js";function findSubspeciesParent(registry,child){var _a;const link=child.subspecies_of;if(typeof link!=="string"||!link.trim())return void 0;const inner=link.trim().replace(/^\[\[/,"").replace(/\]\]$/,"").split("|")[0].replace(/\.md$/,"").trim();if(!inner)return void 0;const tail=((_a=inner.split("/").pop())!=null?_a:inner).trim();const prefix=child.slug.includes("_")?child.slug.slice(0,child.slug.indexOf("_")):null;const notSelf=e=>e&&e.slug!==child.slug?e:void 0;let all=null;const races=()=>all!=null?all:all=registry.search("","race",Number.POSITIVE_INFINITY);const tiers=[()=>notSelf(registry.getByTypeAndSlug("race",inner)),()=>notSelf(races().find(e=>e.filePath===`${inner}.md`||e.filePath.endsWith(`/${inner}.md`))),()=>prefix?notSelf(registry.getByTypeAndSlug("race",`${prefix}_race_${slugify(tail)}`)):void 0,()=>prefix?notSelf(races().find(e=>e.slug.startsWith(`${prefix}_race_`)&&e.name===tail)):void 0];for(const tier of tiers){const hit=tier();if(hit)return hit}return void 0}var nonEmpty=s=>typeof s==="string"&&s.trim().length>0;var asList=v=>v===void 0?[]:Array.isArray(v)?v:[v];function mergeSubspecies(child,parent){var _a,_b,_c,_d,_e,_f,_g,_h,_i,_j,_k,_l,_m,_n,_o,_p,_q,_r,_s,_t;const fixed=[...(_b=(_a=parent.languages)==null?void 0:_a.fixed)!=null?_b:[]];for(const l of(_d=(_c=child.languages)==null?void 0:_c.fixed)!=null?_d:[])if(!fixed.includes(l))fixed.push(l);const choice=(_g=(_e=child.languages)==null?void 0:_e.choice)!=null?_g:(_f=parent.languages)==null?void 0:_f.choice;const choices=[...(_h=parent.choices)!=null?_h:[],...(_i=child.choices)!=null?_i:[]];const spells=[...asList(parent.additional_spells),...asList(child.additional_spells)];return{...parent,...child,size:(_j=parent.size)!=null?_j:child.size,speed:{...(_k=parent.speed)!=null?_k:{},...(_l=child.speed)!=null?_l:{}},vision:{...(_m=parent.vision)!=null?_m:{},...(_n=child.vision)!=null?_n:{}},ability_score_increases:[...(_o=parent.ability_score_increases)!=null?_o:[],...(_p=child.ability_score_increases)!=null?_p:[]],age:nonEmpty(child.age)?child.age:parent.age,alignment:nonEmpty(child.alignment)?child.alignment:parent.alignment,languages:{fixed,...choice?{choice}:{}},traits:[...(_q=parent.traits)!=null?_q:[],...(_r=child.traits)!=null?_r:[]],...choices.length?{choices}:{},...spells.length?{additional_spells:spells}:{},...((_s=child.creature_type)!=null?_s:parent.creature_type)?{creature_type:(_t=child.creature_type)!=null?_t:parent.creature_type}:{}}}function withSubspeciesParent(race,registry){if(!race||!race.subspecies_of)return race;let out=race;const seen=new Set([race.slug]);let link=race;for(let depth=0;depth<3&&link.subspecies_of;depth++){const hit=findSubspeciesParent(registry,link);if(!hit||seen.has(hit.slug))break;seen.add(hit.slug);const data=hit.data;const parent=data.slug==null?{...data,slug:hit.slug}:data;out=mergeSubspecies(out,parent);link=parent}return out}export{findSubspeciesParent,mergeSubspecies,withSubspeciesParent};
@@ -0,0 +1 @@
1
+ import{normalizeRollScope}from"./chunk-FOLHTMSC.js";import{toProfSlug}from"./chunk-VTQ4RWEG.js";import{memberSpellTargets}from"./chunk-J27N3KUE.js";import{heldPicks}from"./chunk-E4E6YEN6.js";import{warnOnce}from"./chunk-DZITM5AG.js";import{bareEntitySlug}from"./chunk-63YJPWTM.js";import{normalizeAbility}from"./chunk-EVT7MGAC.js";function emptyFeatureEffectTotals(){return{initiative_bonus:0,initiative_terms:[],initiative_amount_terms:[],skill_bonus_terms:[],save_bonus_terms:[],half_proficiency_terms:[],hp_per_level_bonus:0,hp_per_level_terms:[],speed_walk_bonus:0,speed_walk_terms:[],speed_terms:[],ignore_armor_strength:[],speed_walk_set:0,attunement_set:0,ability_bonus:{},ability_bonus_terms:[],senses:{darkvision:0,blindsight:0,tremorsense:0,truesight:0},ac_terms:[],resistances:[],immunities:[],vulnerabilities:[],condition_immunities:[],proficiencies:{skills:[],skillExpertise:[],tools:[],languages:[],saves:[],armor:[],weapons:[]},weaponAbilities:[],rollModifiers:[],saveOutcomes:[],critRange:20,conditionalCrits:[],extraAttack:0,scopedExtraAttacks:[],attackNotes:[],damageBonuses:[],spellDamageBonuses:[],damageRollOptions:[]}}function pushUnique(list,value){const key=value.trim().toLowerCase();if(!key)return;if(!list.some(v=>v.trim().toLowerCase()===key))list.push(value.trim())}function pushDefenseGrant(list,value,source,condition,item){var _a;const key=value.trim().toLowerCase();if(!key)return;const existing=list.find(g=>g.value.trim().toLowerCase()===key);if(existing){if(!existing.sources.includes(source))existing.sources.push(source);if(!existing.condition&&condition)existing.condition=condition;if(item)mergeDefenseItems((_a=existing.items)!=null?_a:existing.items=[],[item]);return}list.push({value:value.trim(),sources:[source],...condition?{condition}:{},...item?{items:[item]}:{}})}function mergeDefenseItems(into,from){for(const it of from)if(!into.some(x=>x.index===it.index))into.push({...it})}function ownerItem(owner,label){return(owner==null?void 0:owner.kind)==="item"?{index:owner.index,name:label}:void 0}var NAMED_COLUMN=/^column\(\s*'([^']+)'\s*\)$/;function foldsNow(rf,activeBuffs){if(rf.feature.activatable!==true)return true;const id=rf.feature.id;return!!id&&activeBuffs.has(id)}function assembleEffectFeatures(resolved){var _a,_b,_c,_d,_e,_f,_g,_h,_i,_j;const activeBuffs=new Set((_b=(_a=resolved.state)==null?void 0:_a.active_buffs)!=null?_b:[]);const featureIds=new Set(((_c=resolved.features)!=null?_c:[]).map(f=>f.feature.id).filter(id=>!!id));const aliases=[];for(const pool of(_d=resolved.pools)!=null?_d:[]){for(const entry of[...(_e=pool.selected)!=null?_e:[],...(_f=pool.grants)!=null?_f:[]]){if(activeBuffs.has(entry.slug))continue;const bare=bareEntitySlug(entry.slug);for(const stored of activeBuffs){if(featureIds.has(stored))continue;if(bareEntitySlug(stored)===bare){aliases.push(entry.slug);break}}}}for(const a of aliases)activeBuffs.add(a);const buffFeatures=[];const pushBoon=(item,pool)=>{var _a2,_b2,_c2,_d2,_e2,_f2,_g2,_h2,_i2,_j2,_k;const e=item.entity;if(!e||item.itemBound===true||((_b2=(_a2=e.effects)==null?void 0:_a2.length)!=null?_b2:0)===0)return;const block=(_f2=(_e2=(_d2=(_c2=resolved.classes)==null?void 0:_c2[pool.classIndex])==null?void 0:_d2.choices)==null?void 0:_e2[pool.anchorLevel])!=null?_f2:{};const spellTargets=memberSpellTargets(e,id=>{var _a3;return block[`${pool.id}:${(_a3=item.key)!=null?_a3:item.slug}:${id}`]});buffFeatures.push({feature:{id:item.slug,name:e.name,activatable:(_g2=e.activatable)!=null?_g2:false,effects:e.effects},source:{kind:"class",slug:(_k=(_j2=(_i2=(_h2=resolved.classes)==null?void 0:_h2[pool.classIndex])==null?void 0:_i2.entity)==null?void 0:_j2.slug)!=null?_k:pool.id,level:pool.anchorLevel},...spellTargets?{spellTargets}:{}})};for(const pool of(_g=resolved.pools)!=null?_g:[]){for(const sel of heldPicks(pool))pushBoon(sel,pool);for(const g of(_h=pool.grants)!=null?_h:[])pushBoon(g,pool)}return{features:[...(_i=resolved.features)!=null?_i:[],...buffFeatures,...(_j=resolved.itemFeatures)!=null?_j:[]],activeBuffs}}function foldsOnSelf(eff){if(eff.subject===void 0||eff.subject==="self")return true;warnOnce(eff.subject,`archivist: unrecognised effect subject "${eff.subject}" (only "self" folds)`);return false}function selfEffectsOf(f){var _a;return((_a=f.effects)!=null?_a:[]).filter(foldsOnSelf)}function computeFeatureEffects(features,opts){var _a,_b,_c;const out=emptyFeatureEffectTotals();for(const rf of features){if(!foldsNow(rf,(_a=opts==null?void 0:opts.activeBuffs)!=null?_a:new Set))continue;const level=(_b=opts==null?void 0:opts.levelFor)==null?void 0:_b.call(opts,rf.source);for(const eff of selfEffectsOf(rf.feature)){const effect=columnScaledRider(eff,rf,level,opts==null?void 0:opts.tableDiceFor,opts==null?void 0:opts.tableCellFor);if(effect)applyEffect(out,effect,(_c=rf.feature.name)!=null?_c:"Feature",level,rf.source,rf.spellTargets)}}return out}function classifyProficiencyEffect(eff){if(eff.kind!=="proficiency")return null;const raw=eff.value;const expertise=eff.expertise===true;switch(eff.proficiency_type){case"skill":return{bucket:"skills",value:toProfSlug(raw),raw,expertise};case"tool":return{bucket:"tools",value:toProfSlug(raw),raw,expertise};case"language":return{bucket:"languages",value:toProfSlug(raw),raw,expertise};case"armor":return{bucket:"armor",value:raw.toLowerCase(),raw,expertise};case"weapon":return{bucket:"weapons",value:raw.toLowerCase(),raw,expertise};default:{const ab=normalizeAbility(raw);return ab?{bucket:"saves",value:ab,raw,expertise}:null}}}function collectProficiencyEffectGrants(features,activeBuffs){const out={skills:[],tools:[],languages:[],saves:[],armor:[],weapons:[]};for(const rf of features){if(!foldsNow(rf,activeBuffs))continue;for(const eff of selfEffectsOf(rf.feature)){const c=classifyProficiencyEffect(eff);if(!c)continue;out[c.bucket].push({value:c.value,raw:c.raw,sourceKind:rf.source.kind,sourceSlug:rf.source.slug,...c.expertise?{expertise:true}:{}})}}return out}function scaled(base,key,scalesAt,level){if(level===void 0||!(scalesAt==null?void 0:scalesAt.length))return base;let best=base;let bestLevel=-1;for(const step of scalesAt){if(step.level>level||step.level<=bestLevel)continue;const v=step[key];if(typeof v!=="number")continue;best=v;bestLevel=step.level}return best}function columnScaledRider(eff,rf,level,tableDiceFor,tableCellFor){var _a;if(eff.kind!=="damage-bonus")return eff;const named=NAMED_COLUMN.exec(eff.amount.trim());if(named){const cell=(_a=tableCellFor==null?void 0:tableCellFor(rf.source,named[1]))!=null?_a:null;return cell?{...eff,amount:cell}:null}if(level===void 0||!tableDiceFor)return eff;const src=rf.source;const column=rf.feature.name;if(src.kind!=="class"&&src.kind!=="subclass"||!column)return eff;const atGain=tableDiceFor(src,column,src.level);if(!atGain||atGain.toLowerCase()!==eff.amount.trim().toLowerCase())return eff;const now=tableDiceFor(src,column,level);return now?{...eff,amount:now}:eff}function riderScope(appliesTo){if(appliesTo===void 0||appliesTo==="all"||appliesTo==="spell")return void 0;return Array.isArray(appliesTo)?[...appliesTo]:[appliesTo]}function applyEffect(out,eff,label,level,owner,targets){var _a,_b,_c,_d,_e,_f,_g,_h,_i,_j,_k,_l,_m,_n,_o,_p,_q;switch(eff.kind){case"initiative-bonus":if(typeof eff.value==="number"){out.initiative_bonus+=eff.value;out.initiative_terms.push({label,value:eff.value})}else if(typeof eff.amount==="string"){out.initiative_amount_terms.push({label,amount:eff.amount,...owner?{owner}:{}})}break;case"skill-bonus":out.skill_bonus_terms.push({skills:eff.skills.map(toProfSlug),ability:eff.ability,minimum:(_a=eff.minimum)!=null?_a:0,label});break;case"save-bonus":out.save_bonus_terms.push({saves:[...(_b=eff.saves)!=null?_b:[]],ability:eff.ability,minimum:(_c=eff.minimum)!=null?_c:0,...eff.inactive_while?{inactiveWhile:eff.inactive_while}:{},label});break;case"half-proficiency":out.half_proficiency_terms.push({skills:((_d=eff.skills)!=null?_d:[]).map(toProfSlug),round:(_e=eff.round)!=null?_e:"down",label});break;case"hp-per-level-bonus":out.hp_per_level_bonus+=eff.value;out.hp_per_level_terms.push({label,value:eff.value});break;case"speed-bonus":{const gate=eff.inactive_while===void 0?void 0:[].concat(eff.inactive_while);const qualifiers={...eff.condition?{condition:eff.condition}:{},...gate?{inactiveWhile:gate}:{}};if(eff.equal_to==="walk"){out.speed_terms.push({mode:eff.mode,label,value:0,set:false,equalsWalk:true,...qualifiers});break}const value=scaled((_f=eff.value)!=null?_f:0,"value",eff.scales_at,level);out.speed_terms.push({mode:eff.mode,label,value,set:eff.set===true,...qualifiers});if(eff.mode==="walk"&&!gate){if(eff.set)out.speed_walk_set=Math.max(out.speed_walk_set,value);else{out.speed_walk_bonus+=value;out.speed_walk_terms.push({label,value})}}break}case"speed-rule":if(eff.flag==="ignore-armor-strength")out.ignore_armor_strength.push(label);break;case"attunement-limit":{out.attunement_set=Math.max(out.attunement_set,scaled(eff.value,"value",eff.scales_at,level));break}case"sense":out.senses[eff.type]=Math.max(out.senses[eff.type],eff.range);break;case"resistance":pushDefenseGrant(out.resistances,eff.damage_type,label,eff.condition,ownerItem(owner,label));break;case"immunity":pushDefenseGrant(out.immunities,eff.damage_type,label,eff.condition,ownerItem(owner,label));break;case"vulnerability":pushDefenseGrant(out.vulnerabilities,eff.damage_type,label,eff.condition,ownerItem(owner,label));break;case"immune-condition":if(!eff.while)pushDefenseGrant(out.condition_immunities,eff.condition,label,void 0,ownerItem(owner,label));else if((owner==null?void 0:owner.kind)==="item")pushDefenseGrant(out.condition_immunities,eff.condition,label,eff.while,ownerItem(owner,label));break;case"proficiency":{const c=classifyProficiencyEffect(eff);if(!c)break;if(c.bucket==="saves"){pushUnique(out.proficiencies.saves,c.value)}else{pushUnique(out.proficiencies[c.bucket],c.value)}if(c.expertise&&c.bucket==="skills")pushUnique(out.proficiencies.skillExpertise,c.value);break}case"ac-bonus":out.ac_terms.push({value:eff.value,requires_armor:eff.requires_armor===true,label,condition:eff.condition});break;case"weapon-ability":{if(eff.ability!=="spellcasting"){const w=eff.weapons;if(w==="pact-weapon"){out.weaponAbilities.push({ability:eff.ability,pactWeapon:true});break}const weaponSlugs=!w||w==="chosen"?void 0:Array.isArray(w)?w.map(bareEntitySlug):[bareEntitySlug(w)];out.weaponAbilities.push({ability:eff.ability,weaponSlugs})}break}case"roll-modifier":{const rolls=eff.roll==="any"?["ability-check","saving-throw","attack"]:[eff.roll];const scopes=(_g=normalizeRollScope(eff.scope,rolls[0]))!=null?_g:[eff.scope];for(const roll of rolls)for(const scope of scopes)out.rollModifiers.push({mode:eff.mode,roll,scope,condition:eff.condition,label});break}case"save-outcome":out.saveOutcomes.push({ability:eff.ability==="any"?void 0:eff.ability,on_success:eff.on_success,on_failure:eff.on_failure,appliesTo:(_h=eff.applies_to)!=null?_h:void 0,condition:eff.condition,label});break;case"crit-range":if(((_i=eff.applies_to)!=null?_i:"weapon")==="spell")break;if((_j=eff.condition)==null?void 0:_j.trim())out.conditionalCrits.push({minRoll:eff.min_roll,condition:eff.condition.trim(),source:label});else out.critRange=Math.min(out.critRange,eff.min_roll);break;case"extra-attack":{const count=scaled(eff.count,"count",eff.scales_at,level);const scope=riderScope(eff.applies_to);if(scope)out.scopedExtraAttacks.push({count,scope});else out.extraAttack=Math.max(out.extraAttack,count)}break;case"reroll-damage":{const qualifiers=[eff.once_per_die?"once/die":"",(_l=(_k=eff.condition)==null?void 0:_k.trim())!=null?_l:""].filter(q=>q!=="");out.attackNotes.push(`Reroll ${eff.max_reroll}s${qualifiers.length?` (${qualifiers.join(", ")})`:""}`)}break;case"attack-rule":if(eff.flag==="no-ranged-in-melee-disadvantage")out.attackNotes.push("No disadvantage firing in melee");break;case"damage-roll-option":{const scope=eff.applies_to===void 0?void 0:[].concat(eff.applies_to);out.damageRollOptions.push({mode:eff.mode,...eff.value!==void 0?{value:eff.value}:{},...eff.two_handed?{twoHanded:true}:{},...eff.once_per_turn?{oncePerTurn:true}:{},...((_m=eff.condition)==null?void 0:_m.trim())?{condition:eff.condition.trim()}:{},source:label,...scope?{scope}:{}});break}case"damage-bonus":if(((_n=eff.applies_to)!=null?_n:"weapon")!=="spell"){const scope=riderScope(eff.applies_to);out.damageBonuses.push({amount:eff.amount,damage_type:eff.damage_type,source:label,...eff.condition?{condition:eff.condition}:{},...scope?{scope}:{},...owner?{owner}:{}})}if(eff.applies_to==="spell"||eff.applies_to==="all"){const spellScope=(_o=eff.spell_scope)!=null?_o:eff.applies_to==="all"?{}:void 0;out.spellDamageBonuses.push({amount:eff.amount,damage_type:eff.damage_type,source:label,...eff.condition?{condition:eff.condition}:{},...owner?{owner}:{},...targets?{targets}:{},...spellScope?{scope:spellScope}:{}})}break;case"ability-score-increase":if(eff.abilities==="chosen")break;for(const ab of eff.abilities){out.ability_bonus[ab]=((_p=out.ability_bonus[ab])!=null?_p:0)+eff.amount;((_q=out.ability_bonus_terms)!=null?_q:out.ability_bonus_terms=[]).push({ability:ab,source:label,amount:eff.amount})}break;default:break}}export{emptyFeatureEffectTotals,pushDefenseGrant,mergeDefenseItems,foldsNow,assembleEffectFeatures,foldsOnSelf,selfEffectsOf,computeFeatureEffects,classifyProficiencyEffect,collectProficiencyEffectGrants};
@@ -1 +1 @@
1
- import{spellSource}from"./chunk-PZ3ZZ5H5.js";import{resourceLevelFor}from"./chunk-KEXSF3CH.js";import{addToRoll}from"./chunk-VIP3FH2O.js";import{baseClassName}from"./chunk-CAPYNIGK.js";function ownerClassSlug(source,resolved){var _a,_b,_c;if(!source)return null;if(source.kind==="class")return source.slug;if(source.kind==="subclass")return(_c=(_b=(_a=resolved.classes.find(c=>{var _a2;return((_a2=c.subclass)==null?void 0:_a2.slug)===source.slug}))==null?void 0:_a.entity)==null?void 0:_b.slug)!=null?_c:null;if(source.kind==="feat"&&source.via){if(source.via.kind==="class")return source.via.slug;if(source.via.kind==="pool")return source.via.classSlug}return null}function casterRow(classSlug,derived){var _a,_b;const rows=(_a=derived.spellcastingClasses)!=null?_a:[];const own=classSlug?rows.find(c=>baseClassName(c.classSlug)===baseClassName(classSlug)):void 0;return(_b=own!=null?own:rows[0])!=null?_b:null}function amountBindingsFor(owner,resolved,derived){var _a,_b;const classSlug=ownerClassSlug(owner,resolved);const classSource=classSlug?{kind:"class",slug:classSlug,level:0}:owner;const classLevel=classSource?resourceLevelFor(classSource,resolved):resolved.totalLevel;const row=casterRow(classSlug,derived);const className=classSlug?(_b=(_a=resolved.classes.find(c=>{var _a2;return((_a2=c.entity)==null?void 0:_a2.slug)===classSlug}))==null?void 0:_a.entity)==null?void 0:_b.name:void 0;const classNames=resolved.classes.map(c=>{var _a2;return(_a2=c.entity)==null?void 0:_a2.name}).filter(n=>typeof n==="string"&&n.length>0);return{level:resolved.totalLevel,class_level:classLevel,prof:derived.proficiencyBonus,str_mod:derived.mods.str,dex_mod:derived.mods.dex,con_mod:derived.mods.con,int_mod:derived.mods.int,wis_mod:derived.mods.wis,cha_mod:derived.mods.cha,columns:{},...row?{spell_mod:derived.mods[row.ability],spell_dc:row.saveDC}:{},...className?{class_name:className}:{},...classNames.length>0?{class_names:classNames}:{}}}function spellcastingFor(spell,derived){var _a,_b,_c,_d,_e;const caster=casterOf(spell,derived);const own=spell.itemCasting;if(!own)return caster;return{ability:(_a=caster==null?void 0:caster.ability)!=null?_a:null,saveDC:(_c=(_b=own.saveDC)!=null?_b:caster==null?void 0:caster.saveDC)!=null?_c:0,attackBonus:(_e=(_d=own.attackBonus)!=null?_d:caster==null?void 0:caster.attackBonus)!=null?_e:0}}function casterOf(spell,derived){var _a,_b;if((spellSource(spell).ownAbility||spell.classSlug==null)&&spell.ability){const own=(_a=derived.abilitySpellcasting)==null?void 0:_a[spell.ability];if(own)return{ability:spell.ability,saveDC:own.saveDC,attackBonus:own.attackBonus}}const row=casterRow((_b=spell.classSlug)!=null?_b:null,derived);return row?{ability:row.ability,saveDC:row.saveDC,attackBonus:row.attackBonus}:null}function spellAmountBindings(spell,resolved,derived){const cast=spellcastingFor(spell,derived);const base=amountBindingsFor(spell.classSlug?{kind:"class",slug:spell.classSlug,level:0}:void 0,resolved,derived);const out={...base};delete out.spell_mod;delete out.spell_dc;if(!cast)return out;return cast.ability?{...out,spell_mod:derived.mods[cast.ability],spell_dc:cast.saveDC}:{...out,spell_dc:cast.saveDC}}function spellRollBonus(spell){var _a;const roll=(_a=spell.damage_roll)==null?void 0:_a.trim();const text=spell.description;if(!roll||!text)return null;const esc=roll.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");const re=new RegExp(`(?<![\\w])${esc}\`?\\s*(?:plus|\\+)\\s*your\\s+spellcasting\\s+(?:ability\\s+)?modifier`,"i");return re.test(text)?"{spell_mod}":null}function foldsIntoRoll(rider,spell){var _a,_b;const own=((_b=(_a=spell.entity.damage)==null?void 0:_a.types)!=null?_b:[]).map(t=>t.toLowerCase());return!rider.condition&&(!rider.damage_type||own.includes(rider.damage_type.toLowerCase()))}var reaching=(spell,derived)=>{var _a;return((_a=derived.spellDamageRiders)!=null?_a:[]).filter(r=>{var _a2;return(_a2=r.spells)==null?void 0:_a2.includes(spell.slug)})};function addSpellDamageRiders(roll,spell,derived){return addToRoll(roll,reaching(spell,derived).filter(r=>foldsIntoRoll(r,spell)).map(r=>r.amount))}function spellDamageRiderLines(spell,derived){return reaching(spell,derived).filter(r=>!foldsIntoRoll(r,spell)).map(r=>({amount:r.amount,...r.damage_type?{damage_type:r.damage_type}:{},...r.source?{source:r.source}:{},...r.condition?{condition:r.condition}:{}}))}export{ownerClassSlug,amountBindingsFor,spellcastingFor,spellAmountBindings,spellRollBonus,addSpellDamageRiders,spellDamageRiderLines};
1
+ import{spellSource}from"./chunk-PZ3ZZ5H5.js";import{resourceLevelFor}from"./chunk-2OVDSMPY.js";import{addToRoll}from"./chunk-VIP3FH2O.js";import{baseClassName}from"./chunk-CAPYNIGK.js";function ownerClassSlug(source,resolved){var _a,_b,_c;if(!source)return null;if(source.kind==="class")return source.slug;if(source.kind==="subclass")return(_c=(_b=(_a=resolved.classes.find(c=>{var _a2;return((_a2=c.subclass)==null?void 0:_a2.slug)===source.slug}))==null?void 0:_a.entity)==null?void 0:_b.slug)!=null?_c:null;if(source.kind==="feat"&&source.via){if(source.via.kind==="class")return source.via.slug;if(source.via.kind==="pool")return source.via.classSlug}return null}function casterRow(classSlug,derived){var _a,_b;const rows=(_a=derived.spellcastingClasses)!=null?_a:[];const own=classSlug?rows.find(c=>baseClassName(c.classSlug)===baseClassName(classSlug)):void 0;return(_b=own!=null?own:rows[0])!=null?_b:null}function amountBindingsFor(owner,resolved,derived){var _a,_b;const classSlug=ownerClassSlug(owner,resolved);const classSource=classSlug?{kind:"class",slug:classSlug,level:0}:owner;const classLevel=classSource?resourceLevelFor(classSource,resolved):resolved.totalLevel;const row=casterRow(classSlug,derived);const className=classSlug?(_b=(_a=resolved.classes.find(c=>{var _a2;return((_a2=c.entity)==null?void 0:_a2.slug)===classSlug}))==null?void 0:_a.entity)==null?void 0:_b.name:void 0;const classNames=resolved.classes.map(c=>{var _a2;return(_a2=c.entity)==null?void 0:_a2.name}).filter(n=>typeof n==="string"&&n.length>0);return{level:resolved.totalLevel,class_level:classLevel,prof:derived.proficiencyBonus,str_mod:derived.mods.str,dex_mod:derived.mods.dex,con_mod:derived.mods.con,int_mod:derived.mods.int,wis_mod:derived.mods.wis,cha_mod:derived.mods.cha,columns:{},...row?{spell_mod:derived.mods[row.ability],spell_dc:row.saveDC}:{},...className?{class_name:className}:{},...classNames.length>0?{class_names:classNames}:{}}}function spellcastingFor(spell,derived){var _a,_b,_c,_d,_e;const caster=casterOf(spell,derived);const own=spell.itemCasting;if(!own)return caster;return{ability:(_a=caster==null?void 0:caster.ability)!=null?_a:null,saveDC:(_c=(_b=own.saveDC)!=null?_b:caster==null?void 0:caster.saveDC)!=null?_c:0,attackBonus:(_e=(_d=own.attackBonus)!=null?_d:caster==null?void 0:caster.attackBonus)!=null?_e:0}}function casterOf(spell,derived){var _a,_b;if((spellSource(spell).ownAbility||spell.classSlug==null)&&spell.ability){const own=(_a=derived.abilitySpellcasting)==null?void 0:_a[spell.ability];if(own)return{ability:spell.ability,saveDC:own.saveDC,attackBonus:own.attackBonus}}const row=casterRow((_b=spell.classSlug)!=null?_b:null,derived);return row?{ability:row.ability,saveDC:row.saveDC,attackBonus:row.attackBonus}:null}function spellAmountBindings(spell,resolved,derived){const cast=spellcastingFor(spell,derived);const base=amountBindingsFor(spell.classSlug?{kind:"class",slug:spell.classSlug,level:0}:void 0,resolved,derived);const out={...base};delete out.spell_mod;delete out.spell_dc;if(!cast)return out;return cast.ability?{...out,spell_mod:derived.mods[cast.ability],spell_dc:cast.saveDC}:{...out,spell_dc:cast.saveDC}}function spellRollBonus(spell){var _a;const roll=(_a=spell.damage_roll)==null?void 0:_a.trim();const text=spell.description;if(!roll||!text)return null;const esc=roll.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");const re=new RegExp(`(?<![\\w])${esc}\`?\\s*(?:plus|\\+)\\s*your\\s+spellcasting\\s+(?:ability\\s+)?modifier`,"i");return re.test(text)?"{spell_mod}":null}function foldsIntoRoll(rider,spell){var _a,_b;const own=((_b=(_a=spell.entity.damage)==null?void 0:_a.types)!=null?_b:[]).map(t=>t.toLowerCase());return!rider.condition&&(!rider.damage_type||own.includes(rider.damage_type.toLowerCase()))}var reaching=(spell,derived)=>{var _a;return((_a=derived.spellDamageRiders)!=null?_a:[]).filter(r=>{var _a2;return(_a2=r.spells)==null?void 0:_a2.includes(spell.slug)})};function addSpellDamageRiders(roll,spell,derived){return addToRoll(roll,reaching(spell,derived).filter(r=>foldsIntoRoll(r,spell)).map(r=>r.amount))}function spellDamageRiderLines(spell,derived){return reaching(spell,derived).filter(r=>!foldsIntoRoll(r,spell)).map(r=>({amount:r.amount,...r.damage_type?{damage_type:r.damage_type}:{},...r.source?{source:r.source}:{},...r.condition?{condition:r.condition}:{}}))}export{ownerClassSlug,amountBindingsFor,spellcastingFor,spellAmountBindings,spellRollBonus,addSpellDamageRiders,spellDamageRiderLines};
@@ -1 +1 @@
1
- import{featureObjectSchema}from"./chunk-ZREOQMHM.js";import{imageField}from"./chunk-I26FHSI6.js";import{z}from"zod";var str=z.string();var num=z.number();var bool=z.boolean();var strArr=z.array(z.string());var damageQualifierSchema=z.object({get types(){return z.array(z.union([str,damageQualifierSchema])).optional()},note:str.optional(),pre_note:str.optional(),cond:bool.optional(),special:str.optional()});var qualifierList=z.array(z.union([str,damageQualifierSchema])).optional();var speedValue=z.union([num,z.object({number:num,condition:str.optional()})]);var monsterSpeedSchema=z.object({walk:speedValue.optional(),fly:speedValue.optional(),swim:speedValue.optional(),climb:speedValue.optional(),burrow:speedValue.optional(),hover:bool.optional(),can_hover:bool.optional(),alternate:z.record(str,z.array(z.object({number:num,condition:str.optional()}))).optional(),choose:z.object({from:strArr,amount:num,note:str.optional()}).optional()});var monsterTypeSchema=z.object({type:z.union([str,z.object({choose:strArr})]),tags:z.array(z.union([str,z.object({tag:str,prefix:str,prefix_hidden:bool.optional()})])).optional(),sidekick_type:str.optional(),sidekick_tags:strArr.optional(),swarm_size:str.optional(),sidekick_hidden:bool.optional()});var monsterCRSchema=z.object({cr:str,lair:str.optional(),coven:str.optional(),xp:num.optional(),xp_lair:num.optional()});var monsterACSchema=z.object({ac:num.optional(),from:strArr.optional(),condition:str.optional(),braces:bool.optional(),special:str.optional()});var monsterHPSchema=z.object({average:num.optional(),formula:str.optional(),special:str.optional()});var alignmentEntrySchema=z.object({alignment:strArr.optional(),chance:num.optional(),note:str.optional(),special:str.optional()});var spellEntry=z.union([str,z.object({entry:str,hidden:bool.optional()})]);var spellList=z.array(spellEntry);var spellLevel=z.object({slots:num.optional(),lower:num.optional(),spells:strArr});var monsterSpellcastingSchema=z.object({name:str.optional(),type:str.optional(),headerEntries:strArr.optional(),footerEntries:strArr.optional(),ability:str.optional(),displayAs:str.optional(),hidden:strArr.optional(),spells:z.record(str,spellLevel).optional(),will:spellList.optional(),ritual:spellList.optional(),daily:z.record(str,spellList).optional(),rest:z.record(str,spellList).optional(),restLong:z.record(str,spellList).optional(),recharge:z.record(str,spellList).optional(),legendary:z.record(str,spellList).optional(),charges:z.record(str,spellList).optional(),chargesItem:str.optional()});var initiativeSchema=z.union([num,z.object({proficiency:num.optional(),advantage_mode:str.optional()})]);var gearEntrySchema=z.union([str,z.object({item:str,quantity:num.optional(),displayName:str.optional()})]);var featureArr=z.array(featureObjectSchema).optional();var monsterSchema=z.object({name:str.min(1),size:z.union([str,strArr]).optional(),size_note:str.optional(),type:z.union([str,monsterTypeSchema]).optional(),subtype:str.optional(),alignment:z.union([str,z.array(z.union([str,alignmentEntrySchema]))]).optional(),alignment_prefix:str.optional(),cr:z.union([str,monsterCRSchema]).optional(),pb_note:str.optional(),ac:z.array(monsterACSchema).optional(),hp:monsterHPSchema.optional(),speed:monsterSpeedSchema.optional(),abilities:z.object({str:num,dex:num,con:num,int:num,wis:num,cha:num}).optional(),saves:z.record(str,num).optional(),skills:z.record(str,num).optional(),skills_other:z.array(z.unknown()).optional(),senses:strArr.nullable().optional(),passive_perception:num.optional(),languages:strArr.nullable().optional(),damage_vulnerabilities:qualifierList,damage_resistances:qualifierList,damage_immunities:qualifierList,condition_immunities:qualifierList,traits:featureArr,actions:featureArr,bonus_actions:featureArr,reactions:featureArr,legendary_actions:featureArr,mythic:featureArr,mythic_header:strArr.optional(),legendary_action_uses:num.optional(),legendary_resistance:num.optional(),legendary_actions_lair_count:num.optional(),section_headers:z.array(z.object({section:str,header:strArr})).optional(),action_note:str.optional(),reaction_note:str.optional(),spellcasting:z.array(monsterSpellcastingSchema).optional(),legendary_group:z.object({name:str,source:str}).optional(),lair_actions:z.array(z.unknown()).optional(),regional_actions:z.array(z.unknown()).optional(),variant:z.array(z.unknown()).optional(),initiative:initiativeSchema.optional(),gear:z.array(gearEntrySchema).optional(),is_named_creature:bool.optional(),is_npc:bool.optional(),familiar:bool.optional(),short_name:z.union([str,bool]).optional(),level:num.optional(),dragon_age:str.optional(),dragon_casting_color:str.optional(),environment:strArr.optional(),treasure:strArr.optional(),attached_items:strArr.optional(),group:strArr.nullable().optional(),summoned_by_spell:str.optional(),summoned_by_spell_level:num.optional(),summoned_by_class:str.optional(),trait_tags:strArr.optional(),action_tags:strArr.optional(),sense_tags:strArr.optional(),language_tags:strArr.optional(),spellcasting_tags:strArr.optional(),misc_tags:strArr.optional(),damage_tags:strArr.optional(),damage_tags_spell:strArr.optional(),damage_tags_legendary:strArr.optional(),condition_inflict:strArr.optional(),condition_inflict_spell:strArr.optional(),condition_inflict_legendary:strArr.optional(),saving_throw_forced:strArr.optional(),saving_throw_forced_spell:strArr.optional(),saving_throw_forced_legendary:strArr.optional(),has_fluff:bool.optional(),has_fluff_images:bool.optional(),has_token:bool.optional(),token_credit:str.optional(),token_custom:bool.optional(),sound_clip:z.object({type:str,path:str}).optional(),alt_art:z.array(z.object({name:str,source:str.optional(),page:num.optional()})).optional(),image:imageField,thumbnail:imageField,rendering_hint:str.optional(),columns:num.optional(),slug:str.optional(),edition:str.optional(),source:str.optional(),raw:z.record(str,z.unknown()).optional()});var MONSTER_KNOWN_KEYS=new Set(Object.keys(monsterSchema.shape));export{damageQualifierSchema,monsterSpeedSchema,monsterTypeSchema,monsterCRSchema,monsterACSchema,monsterHPSchema,alignmentEntrySchema,monsterSpellcastingSchema,initiativeSchema,gearEntrySchema,monsterSchema,MONSTER_KNOWN_KEYS};
1
+ import{featureObjectSchema}from"./chunk-M2UA2FAK.js";import{imageField}from"./chunk-I26FHSI6.js";import{z}from"zod";var str=z.string();var num=z.number();var bool=z.boolean();var strArr=z.array(z.string());var damageQualifierSchema=z.object({get types(){return z.array(z.union([str,damageQualifierSchema])).optional()},note:str.optional(),pre_note:str.optional(),cond:bool.optional(),special:str.optional()});var qualifierList=z.array(z.union([str,damageQualifierSchema])).optional();var speedValue=z.union([num,z.object({number:num,condition:str.optional()})]);var monsterSpeedSchema=z.object({walk:speedValue.optional(),fly:speedValue.optional(),swim:speedValue.optional(),climb:speedValue.optional(),burrow:speedValue.optional(),hover:bool.optional(),can_hover:bool.optional(),alternate:z.record(str,z.array(z.object({number:num,condition:str.optional()}))).optional(),choose:z.object({from:strArr,amount:num,note:str.optional()}).optional()});var monsterTypeSchema=z.object({type:z.union([str,z.object({choose:strArr})]),tags:z.array(z.union([str,z.object({tag:str,prefix:str,prefix_hidden:bool.optional()})])).optional(),sidekick_type:str.optional(),sidekick_tags:strArr.optional(),swarm_size:str.optional(),sidekick_hidden:bool.optional()});var monsterCRSchema=z.object({cr:str,lair:str.optional(),coven:str.optional(),xp:num.optional(),xp_lair:num.optional()});var monsterACSchema=z.object({ac:num.optional(),from:strArr.optional(),condition:str.optional(),braces:bool.optional(),special:str.optional()});var monsterHPSchema=z.object({average:num.optional(),formula:str.optional(),special:str.optional()});var alignmentEntrySchema=z.object({alignment:strArr.optional(),chance:num.optional(),note:str.optional(),special:str.optional()});var spellEntry=z.union([str,z.object({entry:str,hidden:bool.optional()})]);var spellList=z.array(spellEntry);var spellLevel=z.object({slots:num.optional(),lower:num.optional(),spells:strArr});var monsterSpellcastingSchema=z.object({name:str.optional(),type:str.optional(),headerEntries:strArr.optional(),footerEntries:strArr.optional(),ability:str.optional(),displayAs:str.optional(),hidden:strArr.optional(),spells:z.record(str,spellLevel).optional(),will:spellList.optional(),ritual:spellList.optional(),daily:z.record(str,spellList).optional(),rest:z.record(str,spellList).optional(),restLong:z.record(str,spellList).optional(),recharge:z.record(str,spellList).optional(),legendary:z.record(str,spellList).optional(),charges:z.record(str,spellList).optional(),chargesItem:str.optional()});var initiativeSchema=z.union([num,z.object({proficiency:num.optional(),advantage_mode:str.optional()})]);var gearEntrySchema=z.union([str,z.object({item:str,quantity:num.optional(),displayName:str.optional()})]);var featureArr=z.array(featureObjectSchema).optional();var monsterSchema=z.object({name:str.min(1),size:z.union([str,strArr]).optional(),size_note:str.optional(),type:z.union([str,monsterTypeSchema]).optional(),subtype:str.optional(),alignment:z.union([str,z.array(z.union([str,alignmentEntrySchema]))]).optional(),alignment_prefix:str.optional(),cr:z.union([str,monsterCRSchema]).optional(),pb_note:str.optional(),ac:z.array(monsterACSchema).optional(),hp:monsterHPSchema.optional(),speed:monsterSpeedSchema.optional(),abilities:z.object({str:num,dex:num,con:num,int:num,wis:num,cha:num}).optional(),saves:z.record(str,num).optional(),skills:z.record(str,num).optional(),skills_other:z.array(z.unknown()).optional(),senses:strArr.nullable().optional(),passive_perception:num.optional(),languages:strArr.nullable().optional(),damage_vulnerabilities:qualifierList,damage_resistances:qualifierList,damage_immunities:qualifierList,condition_immunities:qualifierList,traits:featureArr,actions:featureArr,bonus_actions:featureArr,reactions:featureArr,legendary_actions:featureArr,mythic:featureArr,mythic_header:strArr.optional(),legendary_action_uses:num.optional(),legendary_resistance:num.optional(),legendary_actions_lair_count:num.optional(),section_headers:z.array(z.object({section:str,header:strArr})).optional(),action_note:str.optional(),reaction_note:str.optional(),spellcasting:z.array(monsterSpellcastingSchema).optional(),legendary_group:z.object({name:str,source:str}).optional(),lair_actions:z.array(z.unknown()).optional(),regional_actions:z.array(z.unknown()).optional(),variant:z.array(z.unknown()).optional(),initiative:initiativeSchema.optional(),gear:z.array(gearEntrySchema).optional(),is_named_creature:bool.optional(),is_npc:bool.optional(),familiar:bool.optional(),short_name:z.union([str,bool]).optional(),level:num.optional(),dragon_age:str.optional(),dragon_casting_color:str.optional(),environment:strArr.optional(),treasure:strArr.optional(),attached_items:strArr.optional(),group:strArr.nullable().optional(),summoned_by_spell:str.optional(),summoned_by_spell_level:num.optional(),summoned_by_class:str.optional(),trait_tags:strArr.optional(),action_tags:strArr.optional(),sense_tags:strArr.optional(),language_tags:strArr.optional(),spellcasting_tags:strArr.optional(),misc_tags:strArr.optional(),damage_tags:strArr.optional(),damage_tags_spell:strArr.optional(),damage_tags_legendary:strArr.optional(),condition_inflict:strArr.optional(),condition_inflict_spell:strArr.optional(),condition_inflict_legendary:strArr.optional(),saving_throw_forced:strArr.optional(),saving_throw_forced_spell:strArr.optional(),saving_throw_forced_legendary:strArr.optional(),has_fluff:bool.optional(),has_fluff_images:bool.optional(),has_token:bool.optional(),token_credit:str.optional(),token_custom:bool.optional(),sound_clip:z.object({type:str,path:str}).optional(),alt_art:z.array(z.object({name:str,source:str.optional(),page:num.optional()})).optional(),image:imageField,thumbnail:imageField,rendering_hint:str.optional(),columns:num.optional(),slug:str.optional(),edition:str.optional(),source:str.optional(),raw:z.record(str,z.unknown()).optional()});var MONSTER_KNOWN_KEYS=new Set(Object.keys(monsterSchema.shape));export{damageQualifierSchema,monsterSpeedSchema,monsterTypeSchema,monsterCRSchema,monsterACSchema,monsterHPSchema,alignmentEntrySchema,monsterSpellcastingSchema,initiativeSchema,gearEntrySchema,monsterSchema,MONSTER_KNOWN_KEYS};
@@ -0,0 +1 @@
1
+ var hasAbilityPoints=h=>{var _a;return((_a=h==null?void 0:h.choices)!=null?_a:[]).some(c=>c.kind==="ability-points")};function backgroundGrantsAbilityIncreases(bg){if(!bg)return false;const pool=bg.ability_score_increases;if(pool)return true;return hasAbilityPoints(bg)||hasAbilityPoints(bg.feature)}function speciesGrantsAbilityIncreases(race){var _a,_b,_c;if(!race)return false;if(((_a=race.ability_score_increases)!=null?_a:[]).some(a=>"ability"in a))return true;if(hasAbilityPoints(race))return true;if(((_b=race.traits)!=null?_b:[]).some(t=>hasAbilityPoints(t)))return true;const subs=(_c=race.subraces)!=null?_c:[];return subs.some(s=>{var _a2;return((_a2=s.ability_score_increases)!=null?_a2:[]).some(a=>a.ability!=null)})}function isOlderSpecies(race){return(race==null?void 0:race.edition)==="2014"}function speciesIncreaseRule(resolved){var _a;const applies=backgroundGrantsAbilityIncreases(resolved.background)&&isOlderSpecies(resolved.race)&&speciesGrantsAbilityIncreases(resolved.race);const kept=((_a=resolved.definition)==null?void 0:_a.keep_species_ability_increases)===true;return{applies,kept,suppressed:applies&&!kept}}export{backgroundGrantsAbilityIncreases,speciesGrantsAbilityIncreases,isOlderSpecies,speciesIncreaseRule};
@@ -1 +1 @@
1
- import{aliasFeaturesByLevelActionCost}from"./chunk-S5UCI27C.js";import{classEntitySchema}from"./chunk-7CFLU2XL.js";import{parseYaml}from"@archivist-gg/core";function parseClass(source){const raw=parseYaml(source,["name","slug"]);if(!raw.success)return raw;aliasFeaturesByLevelActionCost(raw.data.features_by_level);const result=classEntitySchema.safeParse({edition:"2014",...raw.data});if(!result.success){return{success:false,error:`class schema validation failed: ${result.error.message}`}}return{success:true,data:result.data}}export{parseClass};
1
+ import{aliasFeaturesByLevelActionCost}from"./chunk-S5UCI27C.js";import{classEntitySchema}from"./chunk-ADX7435T.js";import{parseYaml}from"@archivist-gg/core";function parseClass(source){const raw=parseYaml(source,["name","slug"]);if(!raw.success)return raw;aliasFeaturesByLevelActionCost(raw.data.features_by_level);const result=classEntitySchema.safeParse({edition:"2014",...raw.data});if(!result.success){return{success:false,error:`class schema validation failed: ${result.error.message}`}}return{success:true,data:result.data}}export{parseClass};
@@ -1 +1 @@
1
- import{poolGrantSchema,selectionPoolSchema,tabDeclSchema}from"./chunk-GCYUCIDN.js";import{casterTypeEnum}from"./chunk-X22SISGM.js";import{featureSchema}from"./chunk-ZREOQMHM.js";import{resourceSchema}from"./chunk-CCFIINBA.js";import{startingEquipmentEntrySchema,startingGoldSchema}from"./chunk-TKIEPC6F.js";import{choiceSchema}from"./chunk-VHIE2KYQ.js";import{additionalSpellsEntrySchema,imageField,progressionSchema}from"./chunk-I26FHSI6.js";import{z}from"zod";var abilityEnum=z.enum(["str","dex","con","int","wis","cha"]);var skillEnum=z.enum(["acrobatics","animal-handling","arcana","athletics","deception","history","insight","intimidation","investigation","medicine","nature","perception","performance","persuasion","religion","sleight-of-hand","stealth","survival"]);var armorCategoryEnum=z.enum(["light","medium","heavy","shield"]);var weaponCategoryEnum=z.enum(["simple","martial"]);var hitDieEnum=z.enum(["d6","d8","d10","d12"]);var editionEnum=z.enum(["2014","2024"]);var weaponProficiencySchema=z.object({fixed:z.array(z.string()).optional(),categories:z.array(weaponCategoryEnum).optional(),conditional:z.array(z.object({category:weaponCategoryEnum,where_property:z.array(z.string()).nonempty()})).optional()}).refine(w=>{var _a,_b,_c,_d,_e,_f;return((_b=(_a=w.fixed)==null?void 0:_a.length)!=null?_b:0)+((_d=(_c=w.categories)==null?void 0:_c.length)!=null?_d:0)+((_f=(_e=w.conditional)==null?void 0:_e.length)!=null?_f:0)>0},{message:"weapon proficiency must declare at least one of fixed/categories/conditional"});var toolProficiencySchema=z.object({fixed:z.array(z.string()).optional(),choice:z.object({count:z.number().int().positive(),from:z.array(z.string()).nonempty()}).optional()}).refine(t=>{var _a,_b;return((_b=(_a=t.fixed)==null?void 0:_a.length)!=null?_b:0)>0||t.choice!==void 0},{message:"tool proficiency must declare fixed or choice"});var spellcastingSchema=z.object({caster_type:casterTypeEnum,ability:abilityEnum,preparation:z.enum(["known","prepared"]),spell_list:z.string().min(1)});var weaponMasterySchema=z.object({starting_count:z.number().int().nonnegative().optional(),scaling:z.record(z.string(),z.number().int().nonnegative()).optional()});var classTableRowSchema=z.object({prof_bonus:z.number().int().positive(),columns:z.record(z.string(),z.union([z.string(),z.number()])).optional(),feature_ids:z.array(z.string())});var classEntitySchema=z.object({slug:z.string().min(1),name:z.string().min(1),edition:editionEnum,source:z.string().min(1),description:z.string(),hit_die:hitDieEnum,primary_abilities:z.array(abilityEnum).nonempty(),standard_array:z.strictObject({str:z.number().int(),dex:z.number().int(),con:z.number().int(),int:z.number().int(),wis:z.number().int(),cha:z.number().int()}).optional(),saving_throws:z.array(abilityEnum).length(2),proficiencies:z.object({armor:z.array(armorCategoryEnum),weapons:weaponProficiencySchema,tools:toolProficiencySchema.optional()}),skill_choices:z.object({count:z.number().int().positive(),from:z.array(skillEnum).nonempty()}),choices:z.array(choiceSchema).optional(),starting_equipment:z.array(startingEquipmentEntrySchema),starting_gold:startingGoldSchema.optional(),spellcasting:spellcastingSchema.nullable(),subclass_level:z.number().int().positive(),subclass_feature_name:z.string().min(1),weapon_mastery:weaponMasterySchema.nullable(),epic_boon_level:z.number().int().positive().nullable(),table:z.record(z.string(),classTableRowSchema),features_by_level:z.record(z.string(),z.array(featureSchema)),resources:z.array(resourceSchema),selection_pools:z.array(selectionPoolSchema).optional(),pool_grants:z.array(poolGrantSchema).optional(),tabs:z.array(tabDeclSchema).optional(),rendering_hint:z.string().optional(),has_fluff:z.boolean().optional(),has_fluff_images:z.boolean().optional(),table_col_labels:z.array(z.string().min(1)).optional(),starting_equipment_additional_from_background:z.boolean().optional(),multiclassing:z.unknown().optional(),cantrip_progression:z.array(z.number()).optional(),prepared_spells:z.string().min(1).optional(),prepared_spells_change:z.string().min(1).optional(),prepared_spells_progression:z.array(z.number()).optional(),spells_known_progression:z.array(z.number()).optional(),spells_known_progression_fixed:z.array(z.number()).optional(),spells_known_progression_fixed_allow_lower_level:z.boolean().optional(),spells_known_progression_fixed_by_level:z.record(z.string(),z.record(z.string(),z.number())).optional(),feat_progression:z.array(progressionSchema).optional(),optionalfeature_progression:z.array(progressionSchema).optional(),additional_spells:z.array(additionalSpellsEntrySchema).optional(),image:imageField});export{classEntitySchema};
1
+ import{poolGrantSchema,selectionPoolSchema,tabDeclSchema}from"./chunk-GCYUCIDN.js";import{casterTypeEnum}from"./chunk-X22SISGM.js";import{featureSchema}from"./chunk-M2UA2FAK.js";import{resourceSchema}from"./chunk-CCFIINBA.js";import{startingEquipmentEntrySchema,startingGoldSchema}from"./chunk-TKIEPC6F.js";import{choiceSchema}from"./chunk-VHIE2KYQ.js";import{additionalSpellsEntrySchema,imageField,progressionSchema}from"./chunk-I26FHSI6.js";import{z}from"zod";var abilityEnum=z.enum(["str","dex","con","int","wis","cha"]);var skillEnum=z.enum(["acrobatics","animal-handling","arcana","athletics","deception","history","insight","intimidation","investigation","medicine","nature","perception","performance","persuasion","religion","sleight-of-hand","stealth","survival"]);var armorCategoryEnum=z.enum(["light","medium","heavy","shield"]);var weaponCategoryEnum=z.enum(["simple","martial"]);var hitDieEnum=z.enum(["d6","d8","d10","d12"]);var editionEnum=z.enum(["2014","2024"]);var weaponProficiencySchema=z.object({fixed:z.array(z.string()).optional(),categories:z.array(weaponCategoryEnum).optional(),conditional:z.array(z.object({category:weaponCategoryEnum,where_property:z.array(z.string()).nonempty()})).optional()}).refine(w=>{var _a,_b,_c,_d,_e,_f;return((_b=(_a=w.fixed)==null?void 0:_a.length)!=null?_b:0)+((_d=(_c=w.categories)==null?void 0:_c.length)!=null?_d:0)+((_f=(_e=w.conditional)==null?void 0:_e.length)!=null?_f:0)>0},{message:"weapon proficiency must declare at least one of fixed/categories/conditional"});var toolProficiencySchema=z.object({fixed:z.array(z.string()).optional(),choice:z.object({count:z.number().int().positive(),from:z.array(z.string()).nonempty()}).optional()}).refine(t=>{var _a,_b;return((_b=(_a=t.fixed)==null?void 0:_a.length)!=null?_b:0)>0||t.choice!==void 0},{message:"tool proficiency must declare fixed or choice"});var spellcastingSchema=z.object({caster_type:casterTypeEnum,ability:abilityEnum,preparation:z.enum(["known","prepared"]),spell_list:z.string().min(1)});var weaponMasterySchema=z.object({starting_count:z.number().int().nonnegative().optional(),scaling:z.record(z.string(),z.number().int().nonnegative()).optional()});var classTableRowSchema=z.object({prof_bonus:z.number().int().positive(),columns:z.record(z.string(),z.union([z.string(),z.number()])).optional(),feature_ids:z.array(z.string())});var classEntitySchema=z.object({slug:z.string().min(1),name:z.string().min(1),edition:editionEnum,source:z.string().min(1),description:z.string(),hit_die:hitDieEnum,primary_abilities:z.array(abilityEnum).nonempty(),standard_array:z.strictObject({str:z.number().int(),dex:z.number().int(),con:z.number().int(),int:z.number().int(),wis:z.number().int(),cha:z.number().int()}).optional(),saving_throws:z.array(abilityEnum).length(2),proficiencies:z.object({armor:z.array(armorCategoryEnum),weapons:weaponProficiencySchema,tools:toolProficiencySchema.optional()}),skill_choices:z.object({count:z.number().int().positive(),from:z.array(skillEnum).nonempty()}),choices:z.array(choiceSchema).optional(),starting_equipment:z.array(startingEquipmentEntrySchema),starting_gold:startingGoldSchema.optional(),spellcasting:spellcastingSchema.nullable(),subclass_level:z.number().int().positive(),subclass_feature_name:z.string().min(1),weapon_mastery:weaponMasterySchema.nullable(),epic_boon_level:z.number().int().positive().nullable(),table:z.record(z.string(),classTableRowSchema),features_by_level:z.record(z.string(),z.array(featureSchema)),resources:z.array(resourceSchema),selection_pools:z.array(selectionPoolSchema).optional(),pool_grants:z.array(poolGrantSchema).optional(),tabs:z.array(tabDeclSchema).optional(),rendering_hint:z.string().optional(),has_fluff:z.boolean().optional(),has_fluff_images:z.boolean().optional(),table_col_labels:z.array(z.string().min(1)).optional(),starting_equipment_additional_from_background:z.boolean().optional(),multiclassing:z.unknown().optional(),cantrip_progression:z.array(z.number()).optional(),prepared_spells:z.string().min(1).optional(),prepared_spells_change:z.string().min(1).optional(),prepared_spells_progression:z.array(z.number()).optional(),spells_known_progression:z.array(z.number()).optional(),spells_known_progression_fixed:z.array(z.number()).optional(),spells_known_progression_fixed_allow_lower_level:z.boolean().optional(),spells_known_progression_fixed_by_level:z.record(z.string(),z.record(z.string(),z.number())).optional(),feat_progression:z.array(progressionSchema).optional(),optionalfeature_progression:z.array(progressionSchema).optional(),additional_spells:z.array(additionalSpellsEntrySchema).optional(),image:imageField});export{classEntitySchema};
@@ -1 +1 @@
1
- import{parseClass}from"./chunk-BAOZAXB3.js";import yaml from"js-yaml";var classCodec={parse(doc){return parseClass(doc.body)},serialize(entity){return yaml.dump(entity,{lineWidth:-1,sortKeys:false})}};export{classCodec};
1
+ import{parseClass}from"./chunk-7HOOPNF5.js";import yaml from"js-yaml";var classCodec={parse(doc){return parseClass(doc.body)},serialize(entity){return yaml.dump(entity,{lineWidth:-1,sortKeys:false})}};export{classCodec};
@@ -0,0 +1 @@
1
+ import{toProfSlug}from"./chunk-VTQ4RWEG.js";function replacementChoiceId(domain,value){return`replace-${domain}-${value}`}function replacementKey(r){return`${r.carrier.kind}:${r.choice.id}`}function isReplacementKey(key){return/^(race|background):replace-(skill|tool)-/.test(key)}function replacementOwner(r){return`${r.carrier.name}, in place of ${r.label}`}function replacementPick(r,originChoices){const raw=originChoices==null?void 0:originChoices[replacementKey(r)];const v=Array.isArray(raw)?raw[0]:raw;return typeof v==="string"&&v.trim()?toProfSlug(v):null}function replacementDescription(r){const who=r.others.map(n=>`**${n}**`).join(" and ");const verb=r.others.length>1?"give":"gives";return`Your ${who} already ${verb} you ${r.label}, so ${r.carrier.name}'s ${r.label} adds nothing. The rules let you take a different ${r.domain} instead.`}export{replacementChoiceId,replacementKey,isReplacementKey,replacementOwner,replacementPick,replacementDescription};
@@ -1 +1 @@
1
- import{CONDITION_SLUGS}from"./chunk-KM75CC6Q.js";import{z}from"zod";var conditionSlugEnum=z.enum(CONDITION_SLUGS);var abilityEnum=z.enum(["str","dex","con","int","wis","cha"]);var skillEnum=z.enum(["acrobatics","animal-handling","arcana","athletics","deception","history","insight","intimidation","investigation","medicine","nature","perception","performance","persuasion","religion","sleight-of-hand","stealth","survival"]);var proficiencyTri=z.enum(["none","proficient","expertise"]);var slotEnum=z.enum(["mainhand","offhand","armor","shield"]);var equipmentEntryOverridesSchema=z.object({name:z.string().optional(),bonus:z.number().int().optional(),damage_bonus:z.number().int().optional(),extra_damage:z.string().optional(),ac_bonus:z.number().int().optional(),action:z.enum(["action","bonus-action","reaction","free","special"]).optional(),range:z.string().optional(),resist:z.array(z.string()).optional(),immune:z.array(z.string()).optional(),vulnerable:z.array(z.string()).optional(),condition_immune:z.array(z.string()).optional(),spell:z.string().optional(),spell_ability:abilityEnum.optional()}).strict();var equipmentEntryStateSchema=z.object({charges:z.object({current:z.number().int().nonnegative(),max:z.number().int().nonnegative()}).optional(),recovery:z.object({amount:z.string(),reset:z.enum(["dawn","short","long","special"])}).optional(),depletion_risk:z.object({trigger:z.string(),roll:z.string(),threshold:z.number().int(),effect:z.string()}).optional()}).strict();var entryRefField=z.preprocess(v=>typeof v==="number"?String(v):typeof v==="string"&&v.length>0?v:void 0,z.string().optional());var infusionMarkerSchema=z.object({kind:z.enum(["infused","created"]),by:z.string().min(1),seq:z.number().int().min(1),choice:z.string().min(1).optional(),charges:z.object({current:z.number().int().nonnegative()}).optional()});var equipmentEntrySchema=z.object({item:z.string().min(1),equipped:z.boolean().optional(),attuned:z.boolean().optional(),qty:z.number().int().positive().optional(),notes:z.string().optional(),slot:slotEnum.nullable().optional(),overrides:equipmentEntryOverridesSchema.optional(),state:equipmentEntryStateSchema.optional(),granted_by:z.string().optional(),id:entryRefField,in:entryRefField,infusion:infusionMarkerSchema.optional()});var characterOverridesShape=z.object({scores:z.partialRecord(abilityEnum,z.number().int()).optional(),saves:z.partialRecord(abilityEnum,z.object({bonus:z.number().int().optional(),proficient:z.boolean().optional()})).optional(),skills:z.partialRecord(skillEnum,z.object({bonus:z.number().int(),proficiency:proficiencyTri.optional()})).optional(),passives:z.object({perception:z.number().int().optional(),investigation:z.number().int().optional(),insight:z.number().int().optional()}).partial().optional(),hp:z.object({max:z.number().int().positive().optional(),rolled:z.number().int().positive().optional(),modifier:z.number().int().optional()}).optional(),ac:z.number().int().optional(),speed:z.number().int().optional(),initiative:z.number().int().optional(),spellcasting_ability_by_class:z.record(z.string(),abilityEnum).optional(),spellcasting_ability:abilityEnum.optional(),spell_slots:z.record(z.coerce.number().int(),z.number().int().nonnegative()).optional(),attunement_limit:z.number().int().nonnegative().optional(),languages:z.object({add:z.array(z.string()).optional(),remove:z.array(z.string()).optional()}).optional(),tools:z.object({add:z.array(z.string()).optional(),remove:z.array(z.string()).optional(),proficiency:z.record(z.string(),proficiencyTri).optional()}).optional(),weapons:z.object({add:z.array(z.string()).optional(),remove:z.array(z.string()).optional()}).optional(),armor:z.object({add:z.array(z.string()).optional(),remove:z.array(z.string()).optional()}).optional(),defenses:z.object({resistances:z.object({remove:z.array(z.string()).optional()}).optional(),immunities:z.object({remove:z.array(z.string()).optional()}).optional(),vulnerabilities:z.object({remove:z.array(z.string()).optional()}).optional(),condition_immunities:z.object({remove:z.array(z.string()).optional()}).optional()}).optional()});var characterOverridesSchema=characterOverridesShape.default({});var characterStateSchema=z.object({hp:z.object({current:z.number().int(),max:z.number().int(),temp:z.number().int().nonnegative()}),hit_dice:z.record(z.string(),z.object({used:z.number().int().nonnegative(),total:z.number().int().nonnegative()})).default({}),spell_slots:z.record(z.coerce.number().int(),z.object({used:z.number().int().nonnegative(),total:z.number().int().nonnegative()})).default({}),spell_slots_pact:z.object({level:z.number().int().nonnegative(),used:z.number().int().nonnegative(),total:z.number().int().nonnegative()}).optional(),concentration:z.string().nullable().default(null),conditions:z.array(conditionSlugEnum).default([]),exhaustion:z.number().int().min(0).max(6).default(0),death_saves:z.object({successes:z.number().int().min(0).max(3),failures:z.number().int().min(0).max(3)}).optional(),inspiration:z.number().int().nonnegative().default(0),currency:z.object({cp:z.number().int().nonnegative(),sp:z.number().int().nonnegative(),ep:z.number().int().nonnegative(),gp:z.number().int().nonnegative(),pp:z.number().int().nonnegative()}).optional(),feature_uses:z.record(z.string(),z.object({used:z.number().int().nonnegative(),max:z.number().int().nonnegative()})).default({}),feature_rolls:z.record(z.string(),z.array(z.number().int().refine(n=>n!==0&&Math.abs(n)<=999,"banked rolls are nonzero, |value| 1..999"))).default({}),active_buffs:z.array(z.string()).optional(),attuned_items:z.array(z.string()).optional()});var choiceValueSchema=z.union([z.string(),z.array(z.string()),z.record(z.string(),z.unknown())]).catch(ctx=>ctx.value);var classEntrySchema=z.object({name:z.string().min(1),level:z.number().int().min(1).max(20),subclass:z.string().nullable().default(null),choices:z.record(z.coerce.number().int(),z.record(z.string(),choiceValueSchema).catch(ctx=>ctx.value)).default({})});var spellOverrideSchema=z.object({slug:z.string().min(1),overrides:z.record(z.string(),z.unknown()).default({})});var knownSpellObjectSchema=z.object({spell:z.string().min(1),class:z.string().optional(),source:z.enum(["class","feat","item","race","domain"]).optional(),prepared:z.boolean().optional(),always_prepared:z.boolean().optional()}).strict();var knownSpellEntrySchema=z.union([z.string().min(1),knownSpellObjectSchema]);var sheetViewFilterSchema=z.object({show:z.array(z.string().min(1)).optional(),hide:z.array(z.string().min(1)).optional()});var sheetPoolViewSchema=z.object({show:z.enum(["known","granted","not-known"]).optional().catch(void 0),off:z.record(z.string(),z.array(z.string())).optional(),folded:z.array(z.string().min(1)).optional()});var sheetSavedRollSchema=z.object({name:z.string().min(1),on:z.string().min(1),hit:z.enum(["normal","advantage","disadvantage"]).optional(),damage:z.array(z.string().min(1)).optional(),extra:z.string().optional()});var sheetRollsSchema=z.array(z.unknown()).transform(list=>list.flatMap(entry=>{const r=sheetSavedRollSchema.safeParse(entry);return r.success?[r.data]:[]}));var sheetStateSchema=z.object({layout:z.object({saves:z.enum(["section"]).optional().catch(void 0),body:z.enum(["wide"]).optional().catch(void 0)}).optional(),favorites:z.array(z.string().min(1)).optional(),rolls:sheetRollsSchema.optional(),filters:z.object({actions:sheetViewFilterSchema.optional(),passive:sheetViewFilterSchema.optional()}).optional(),pools:z.record(z.string(),sheetPoolViewSchema).optional()});var characterSchema=z.object({name:z.string().min(1),edition:z.enum(["2014","2024"]),builder:z.boolean().optional(),alignment:z.string().optional(),age:z.string().optional(),race:z.string().nullable().default(null),subrace:z.string().nullable().default(null),background:z.string().nullable().default(null),class:z.array(classEntrySchema).default([]),origin_choices:z.record(z.string(),choiceValueSchema).default({}),abilities:z.object({str:z.number().int(),dex:z.number().int(),con:z.number().int(),int:z.number().int(),wis:z.number().int(),cha:z.number().int()}),ability_method:z.enum(["standard-array","point-buy","archivist-point-buy","rolled","manual"]),builder_rolls:z.array(z.number().int()).optional(),builder_equipment_mode:z.enum(["starting","gold","empty"]).optional(),skills:z.object({proficient:z.array(skillEnum).default([]),expertise:z.array(skillEnum).default([]),half:z.array(skillEnum).optional()}).default({proficient:[],expertise:[]}),spells:z.object({known:z.array(knownSpellEntrySchema).default([]),overrides:z.array(spellOverrideSchema).default([]),view:z.enum(["by-level","table"]).optional()}).default({known:[],overrides:[]}),equipment:z.array(equipmentEntrySchema).default([]),overrides:characterOverridesSchema,currency:z.object({cp:z.number().int().nonnegative(),sp:z.number().int().nonnegative(),ep:z.number().int().nonnegative(),gp:z.number().int().nonnegative(),pp:z.number().int().nonnegative()}).optional(),additional_features:z.array(z.string().min(1)).default([]),notes:z.string().optional(),defenses:z.object({resistances:z.array(z.string()).default([]),immunities:z.array(z.string()).default([]),vulnerabilities:z.array(z.string()).default([]),condition_immunities:z.array(z.string()).default([])}).partial().optional(),sheet:sheetStateSchema.optional(),state:characterStateSchema});export{characterOverridesShape,characterSchema};
1
+ import{CONDITION_SLUGS}from"./chunk-KM75CC6Q.js";import{z}from"zod";var conditionSlugEnum=z.enum(CONDITION_SLUGS);var abilityEnum=z.enum(["str","dex","con","int","wis","cha"]);var skillEnum=z.enum(["acrobatics","animal-handling","arcana","athletics","deception","history","insight","intimidation","investigation","medicine","nature","perception","performance","persuasion","religion","sleight-of-hand","stealth","survival"]);var proficiencyTri=z.enum(["none","proficient","expertise"]);var slotEnum=z.enum(["mainhand","offhand","armor","shield"]);var equipmentEntryOverridesSchema=z.object({name:z.string().optional(),bonus:z.number().int().optional(),damage_bonus:z.number().int().optional(),extra_damage:z.string().optional(),ac_bonus:z.number().int().optional(),action:z.enum(["action","bonus-action","reaction","free","special"]).optional(),range:z.string().optional(),resist:z.array(z.string()).optional(),immune:z.array(z.string()).optional(),vulnerable:z.array(z.string()).optional(),condition_immune:z.array(z.string()).optional(),spell:z.string().optional(),spell_ability:abilityEnum.optional()}).strict();var equipmentEntryStateSchema=z.object({charges:z.object({current:z.number().int().nonnegative(),max:z.number().int().nonnegative()}).optional(),recovery:z.object({amount:z.string(),reset:z.enum(["dawn","short","long","special"])}).optional(),depletion_risk:z.object({trigger:z.string(),roll:z.string(),threshold:z.number().int(),effect:z.string()}).optional()}).strict();var entryRefField=z.preprocess(v=>typeof v==="number"?String(v):typeof v==="string"&&v.length>0?v:void 0,z.string().optional());var infusionMarkerSchema=z.object({kind:z.enum(["infused","created"]),by:z.string().min(1),seq:z.number().int().min(1),choice:z.string().min(1).optional(),charges:z.object({current:z.number().int().nonnegative()}).optional()});var equipmentEntrySchema=z.object({item:z.string().min(1),equipped:z.boolean().optional(),attuned:z.boolean().optional(),qty:z.number().int().positive().optional(),notes:z.string().optional(),slot:slotEnum.nullable().optional(),overrides:equipmentEntryOverridesSchema.optional(),state:equipmentEntryStateSchema.optional(),granted_by:z.string().optional(),id:entryRefField,in:entryRefField,infusion:infusionMarkerSchema.optional()});var characterOverridesShape=z.object({scores:z.partialRecord(abilityEnum,z.number().int()).optional(),saves:z.partialRecord(abilityEnum,z.object({bonus:z.number().int().optional(),proficient:z.boolean().optional()})).optional(),skills:z.partialRecord(skillEnum,z.object({bonus:z.number().int(),proficiency:proficiencyTri.optional()})).optional(),passives:z.object({perception:z.number().int().optional(),investigation:z.number().int().optional(),insight:z.number().int().optional()}).partial().optional(),hp:z.object({max:z.number().int().positive().optional(),rolled:z.number().int().positive().optional(),modifier:z.number().int().optional()}).optional(),ac:z.number().int().optional(),speed:z.number().int().optional(),initiative:z.number().int().optional(),spellcasting_ability_by_class:z.record(z.string(),abilityEnum).optional(),spellcasting_ability:abilityEnum.optional(),spell_slots:z.record(z.coerce.number().int(),z.number().int().nonnegative()).optional(),attunement_limit:z.number().int().nonnegative().optional(),languages:z.object({add:z.array(z.string()).optional(),remove:z.array(z.string()).optional()}).optional(),tools:z.object({add:z.array(z.string()).optional(),remove:z.array(z.string()).optional(),proficiency:z.record(z.string(),proficiencyTri).optional()}).optional(),weapons:z.object({add:z.array(z.string()).optional(),remove:z.array(z.string()).optional()}).optional(),armor:z.object({add:z.array(z.string()).optional(),remove:z.array(z.string()).optional()}).optional(),defenses:z.object({resistances:z.object({remove:z.array(z.string()).optional()}).optional(),immunities:z.object({remove:z.array(z.string()).optional()}).optional(),vulnerabilities:z.object({remove:z.array(z.string()).optional()}).optional(),condition_immunities:z.object({remove:z.array(z.string()).optional()}).optional()}).optional()});var characterOverridesSchema=characterOverridesShape.default({});var characterStateSchema=z.object({hp:z.object({current:z.number().int(),max:z.number().int(),temp:z.number().int().nonnegative()}),hit_dice:z.record(z.string(),z.object({used:z.number().int().nonnegative(),total:z.number().int().nonnegative()})).default({}),spell_slots:z.record(z.coerce.number().int(),z.object({used:z.number().int().nonnegative(),total:z.number().int().nonnegative()})).default({}),spell_slots_pact:z.object({level:z.number().int().nonnegative(),used:z.number().int().nonnegative(),total:z.number().int().nonnegative()}).optional(),concentration:z.string().nullable().default(null),conditions:z.array(conditionSlugEnum).default([]),exhaustion:z.number().int().min(0).max(6).default(0),death_saves:z.object({successes:z.number().int().min(0).max(3),failures:z.number().int().min(0).max(3)}).optional(),inspiration:z.number().int().nonnegative().default(0),currency:z.object({cp:z.number().int().nonnegative(),sp:z.number().int().nonnegative(),ep:z.number().int().nonnegative(),gp:z.number().int().nonnegative(),pp:z.number().int().nonnegative()}).optional(),feature_uses:z.record(z.string(),z.object({used:z.number().int().nonnegative(),max:z.number().int().nonnegative()})).default({}),feature_rolls:z.record(z.string(),z.array(z.number().int().refine(n=>n!==0&&Math.abs(n)<=999,"banked rolls are nonzero, |value| 1..999"))).default({}),active_buffs:z.array(z.string()).optional(),attuned_items:z.array(z.string()).optional()});var choiceValueSchema=z.union([z.string(),z.array(z.string()),z.record(z.string(),z.unknown())]).catch(ctx=>ctx.value);var classEntrySchema=z.object({name:z.string().min(1),level:z.number().int().min(1).max(20),subclass:z.string().nullable().default(null),choices:z.record(z.coerce.number().int(),z.record(z.string(),choiceValueSchema).catch(ctx=>ctx.value)).default({})});var spellOverrideSchema=z.object({slug:z.string().min(1),overrides:z.record(z.string(),z.unknown()).default({})});var knownSpellObjectSchema=z.object({spell:z.string().min(1),class:z.string().optional(),source:z.enum(["class","feat","item","race","domain"]).optional(),prepared:z.boolean().optional(),always_prepared:z.boolean().optional()}).strict();var knownSpellEntrySchema=z.union([z.string().min(1),knownSpellObjectSchema]);var sheetViewFilterSchema=z.object({show:z.array(z.string().min(1)).optional(),hide:z.array(z.string().min(1)).optional()});var sheetPoolViewSchema=z.object({show:z.enum(["known","granted","not-known"]).optional().catch(void 0),off:z.record(z.string(),z.array(z.string())).optional(),folded:z.array(z.string().min(1)).optional()});var sheetSavedRollSchema=z.object({name:z.string().min(1),on:z.string().min(1),hit:z.enum(["normal","advantage","disadvantage"]).optional(),damage:z.array(z.string().min(1)).optional(),extra:z.string().optional()});var sheetRollsSchema=z.array(z.unknown()).transform(list=>list.flatMap(entry=>{const r=sheetSavedRollSchema.safeParse(entry);return r.success?[r.data]:[]}));var sheetStateSchema=z.object({layout:z.object({saves:z.enum(["section"]).optional().catch(void 0),body:z.enum(["wide"]).optional().catch(void 0)}).optional(),favorites:z.array(z.string().min(1)).optional(),rolls:sheetRollsSchema.optional(),filters:z.object({actions:sheetViewFilterSchema.optional(),passive:sheetViewFilterSchema.optional()}).optional(),pools:z.record(z.string(),sheetPoolViewSchema).optional()});var characterSchema=z.object({name:z.string().min(1),edition:z.enum(["2014","2024"]),builder:z.boolean().optional(),alignment:z.string().optional(),age:z.string().optional(),race:z.string().nullable().default(null),subrace:z.string().nullable().default(null),background:z.string().nullable().default(null),class:z.array(classEntrySchema).default([]),origin_choices:z.record(z.string(),choiceValueSchema).default({}),abilities:z.object({str:z.number().int(),dex:z.number().int(),con:z.number().int(),int:z.number().int(),wis:z.number().int(),cha:z.number().int()}),ability_method:z.enum(["standard-array","point-buy","archivist-point-buy","rolled","manual"]),keep_species_ability_increases:z.boolean().optional().catch(void 0),builder_rolls:z.array(z.number().int()).optional(),builder_equipment_mode:z.enum(["starting","gold","empty"]).optional(),skills:z.object({proficient:z.array(skillEnum).default([]),expertise:z.array(skillEnum).default([]),half:z.array(skillEnum).optional()}).default({proficient:[],expertise:[]}),spells:z.object({known:z.array(knownSpellEntrySchema).default([]),overrides:z.array(spellOverrideSchema).default([]),view:z.enum(["by-level","table"]).optional()}).default({known:[],overrides:[]}),equipment:z.array(equipmentEntrySchema).default([]),overrides:characterOverridesSchema,currency:z.object({cp:z.number().int().nonnegative(),sp:z.number().int().nonnegative(),ep:z.number().int().nonnegative(),gp:z.number().int().nonnegative(),pp:z.number().int().nonnegative()}).optional(),additional_features:z.array(z.string().min(1)).default([]),notes:z.string().optional(),defenses:z.object({resistances:z.array(z.string()).default([]),immunities:z.array(z.string()).default([]),vulnerabilities:z.array(z.string()).default([]),condition_immunities:z.array(z.string()).default([])}).partial().optional(),sheet:sheetStateSchema.optional(),state:characterStateSchema});export{characterOverridesShape,characterSchema};
@@ -1 +1 @@
1
- import{featureSchema}from"./chunk-ZREOQMHM.js";import{choiceSchema}from"./chunk-VHIE2KYQ.js";import{additionalSpellsEntrySchema,imageField}from"./chunk-I26FHSI6.js";import{z}from"zod";var abilityEnum=z.enum(["str","dex","con","int","wis","cha"]);var editionEnum=z.enum(["2014","2024"]);var sizeEnum=z.enum(["tiny","small","medium","large","huge"]);var wikilinkRegex=/^\[\[[^[\]]+\]\]$/;var speedSchema=z.object({walk:z.number().int().nonnegative().optional(),fly:z.number().int().nonnegative().optional(),swim:z.number().int().nonnegative().optional(),climb:z.number().int().nonnegative().optional(),burrow:z.number().int().nonnegative().optional(),hover:z.boolean().optional()});var visionSchema=z.object({darkvision:z.number().int().nonnegative().optional(),blindsight:z.number().int().nonnegative().optional(),tremorsense:z.number().int().nonnegative().optional(),truesight:z.number().int().nonnegative().optional()});var fixedAsiSchema=z.object({ability:abilityEnum,amount:z.number().int()});var choiceAsiSchema=z.object({choose:z.number().int().positive(),pool:z.array(abilityEnum).nonempty(),amount:z.number().int()});var asiSchema=z.union([fixedAsiSchema,choiceAsiSchema]);var languagesSchema=z.object({fixed:z.array(z.string()),choice:z.object({count:z.number().int().positive(),from:z.union([z.string(),z.array(z.string())])}).optional()});var raceEntitySchema=z.object({slug:z.string().min(1),name:z.string().min(1),edition:editionEnum,source:z.string().min(1),description:z.string(),size:sizeEnum,speed:speedSchema,ability_score_increases:z.array(asiSchema),age:z.string(),alignment:z.string(),vision:visionSchema,languages:languagesSchema,variant_label:z.string().min(1),traits:z.array(featureSchema),choices:z.array(choiceSchema).optional(),subspecies_of:z.string().regex(wikilinkRegex).optional(),rendering_hint:z.string().optional(),has_fluff:z.boolean().optional(),has_fluff_images:z.boolean().optional(),creature_type:z.array(z.string().min(1)).optional(),creature_type_tags:z.array(z.string().min(1)).optional(),additional_spells:z.union([z.array(additionalSpellsEntrySchema),additionalSpellsEntrySchema]).optional(),trait_tags:z.unknown().optional(),lineage:z.unknown().optional(),height_and_weight:z.unknown().optional(),sound_clip:z.unknown().optional(),image:imageField});export{fixedAsiSchema,raceEntitySchema};
1
+ import{featureSchema}from"./chunk-M2UA2FAK.js";import{choiceSchema}from"./chunk-VHIE2KYQ.js";import{additionalSpellsEntrySchema,imageField}from"./chunk-I26FHSI6.js";import{z}from"zod";var abilityEnum=z.enum(["str","dex","con","int","wis","cha"]);var editionEnum=z.enum(["2014","2024"]);var sizeEnum=z.enum(["tiny","small","medium","large","huge"]);var wikilinkRegex=/^\[\[[^[\]]+\]\]$/;var speedSchema=z.object({walk:z.number().int().nonnegative().optional(),fly:z.number().int().nonnegative().optional(),swim:z.number().int().nonnegative().optional(),climb:z.number().int().nonnegative().optional(),burrow:z.number().int().nonnegative().optional(),hover:z.boolean().optional()});var visionSchema=z.object({darkvision:z.number().int().nonnegative().optional(),blindsight:z.number().int().nonnegative().optional(),tremorsense:z.number().int().nonnegative().optional(),truesight:z.number().int().nonnegative().optional()});var fixedAsiSchema=z.object({ability:abilityEnum,amount:z.number().int()});var choiceAsiSchema=z.object({choose:z.number().int().positive(),pool:z.array(abilityEnum).nonempty(),amount:z.number().int()});var asiSchema=z.union([fixedAsiSchema,choiceAsiSchema]);var languagesSchema=z.object({fixed:z.array(z.string()),choice:z.object({count:z.number().int().positive(),from:z.union([z.string(),z.array(z.string())])}).optional()});var raceEntitySchema=z.object({slug:z.string().min(1),name:z.string().min(1),edition:editionEnum,source:z.string().min(1),description:z.string(),size:sizeEnum,speed:speedSchema,ability_score_increases:z.array(asiSchema),age:z.string(),alignment:z.string(),vision:visionSchema,languages:languagesSchema,variant_label:z.string().min(1),traits:z.array(featureSchema),choices:z.array(choiceSchema).optional(),subspecies_of:z.string().regex(wikilinkRegex).optional(),rendering_hint:z.string().optional(),has_fluff:z.boolean().optional(),has_fluff_images:z.boolean().optional(),creature_type:z.array(z.string().min(1)).optional(),creature_type_tags:z.array(z.string().min(1)).optional(),additional_spells:z.union([z.array(additionalSpellsEntrySchema),additionalSpellsEntrySchema]).optional(),trait_tags:z.unknown().optional(),lineage:z.unknown().optional(),height_and_weight:z.unknown().optional(),sound_clip:z.unknown().optional(),image:imageField});export{fixedAsiSchema,raceEntitySchema};