@archivist-gg/dnd5e 0.3.24 → 0.3.26

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 (111) hide show
  1. package/dist/background/background.codec.js +1 -1
  2. package/dist/background/background.parser.js +1 -1
  3. package/dist/background/background.schema.js +1 -1
  4. package/dist/{chunk-6LCNV26D.js → chunk-4SYAKWY4.js} +1 -1
  5. package/dist/{chunk-RL4VY2AL.js → chunk-5XDCM6YK.js} +1 -1
  6. package/dist/{chunk-HR5MKCP2.js → chunk-6R46KYGU.js} +1 -1
  7. package/dist/{chunk-XQMKH4R4.js → chunk-72PRMZRD.js} +1 -1
  8. package/dist/chunk-757KM22B.js +1 -0
  9. package/dist/chunk-CCAVZANF.js +1 -0
  10. package/dist/{chunk-A7H6LX47.js → chunk-CEHL7PPC.js} +1 -1
  11. package/dist/{chunk-BPKG6RZ7.js → chunk-CNMHADNV.js} +1 -1
  12. package/dist/{chunk-BGX36NPE.js → chunk-CSTAQQGX.js} +1 -1
  13. package/dist/{chunk-OTFNINUY.js → chunk-DTB7YBMZ.js} +1 -1
  14. package/dist/{chunk-7UPYRKMF.js → chunk-E3MS4M3N.js} +1 -1
  15. package/dist/{chunk-5FEXHY4U.js → chunk-E7KFJLDR.js} +1 -1
  16. package/dist/{chunk-RDXQAZBA.js → chunk-EPA24PVZ.js} +1 -1
  17. package/dist/{chunk-TLXFGGWH.js → chunk-ETDMOGFO.js} +1 -1
  18. package/dist/chunk-GD7WRCNH.js +1 -0
  19. package/dist/{chunk-GIOV6JW7.js → chunk-GGQDQSIF.js} +1 -1
  20. package/dist/{chunk-334WLI7V.js → chunk-GIQLIBC7.js} +1 -1
  21. package/dist/{chunk-QFIGPOFW.js → chunk-HX7WBOKR.js} +1 -1
  22. package/dist/chunk-J3RP5C7L.js +1 -0
  23. package/dist/chunk-J5GL6FLP.js +1 -0
  24. package/dist/{chunk-PZUPZBTN.js → chunk-KEXSF3CH.js} +1 -1
  25. package/dist/{chunk-N3RYJ7RE.js → chunk-L2DXF7YS.js} +1 -1
  26. package/dist/{chunk-KBFSJ5WE.js → chunk-LHH5XSEA.js} +1 -1
  27. package/dist/{chunk-V6NQ547U.js → chunk-NIWLD33X.js} +1 -1
  28. package/dist/{chunk-2LCGKNVM.js → chunk-NU2Z7MTS.js} +1 -1
  29. package/dist/{chunk-I4O2FIDT.js → chunk-NYPH7RQN.js} +1 -1
  30. package/dist/{chunk-WUHTSLG4.js → chunk-NYTR6NJS.js} +1 -1
  31. package/dist/{chunk-7J5BNH2D.js → chunk-ONCXJMJM.js} +1 -1
  32. package/dist/{chunk-IOCJIWCV.js → chunk-OTRH62HY.js} +1 -1
  33. package/dist/{chunk-NI364WV7.js → chunk-PFQPP77Q.js} +1 -1
  34. package/dist/{chunk-DY6FVAGA.js → chunk-PKIMOVQG.js} +1 -1
  35. package/dist/{chunk-7AKJBRBD.js → chunk-RHIEOYDX.js} +1 -1
  36. package/dist/{chunk-DZKSXSJF.js → chunk-SFK57JAA.js} +1 -1
  37. package/dist/{chunk-KZDDFG4O.js → chunk-VVJXZZ4Z.js} +1 -1
  38. package/dist/{chunk-QBA757AU.js → chunk-WAUNLUFQ.js} +1 -1
  39. package/dist/{chunk-RQGTBHJW.js → chunk-XPF53K54.js} +1 -1
  40. package/dist/{chunk-6ASJ3MVB.js → chunk-ZS5BMNXC.js} +1 -1
  41. package/dist/chunk-ZVL5FXXO.js +1 -0
  42. package/dist/class/class.codec.js +1 -1
  43. package/dist/class/class.parser.js +1 -1
  44. package/dist/class/class.schema.d.ts +2 -2
  45. package/dist/class/class.schema.js +1 -1
  46. package/dist/feat/feat.codec.js +1 -1
  47. package/dist/feat/feat.parser.js +1 -1
  48. package/dist/feat/feat.schema.d.ts +24 -3
  49. package/dist/feat/feat.schema.js +1 -1
  50. package/dist/index.js +9 -9
  51. package/dist/item/item.codec.js +1 -1
  52. package/dist/item/item.parser.js +1 -1
  53. package/dist/item/item.schema.d.ts +3 -0
  54. package/dist/item/item.schema.js +1 -1
  55. package/dist/item/item.types.d.ts +3 -0
  56. package/dist/monster/monster.parser.js +1 -1
  57. package/dist/monster/monster.schema.js +1 -1
  58. package/dist/optional-feature/optional-feature.codec.js +1 -1
  59. package/dist/optional-feature/optional-feature.parser.js +1 -1
  60. package/dist/optional-feature/optional-feature.schema.d.ts +23 -2
  61. package/dist/optional-feature/optional-feature.schema.js +1 -1
  62. package/dist/pc/pc.additional-spells.js +1 -1
  63. package/dist/pc/pc.amount-bindings.d.ts +3 -3
  64. package/dist/pc/pc.amount-bindings.js +1 -1
  65. package/dist/pc/pc.decision-engine.d.ts +6 -0
  66. package/dist/pc/pc.decision-engine.js +1 -1
  67. package/dist/pc/pc.entry-overrides.d.ts +19 -0
  68. package/dist/pc/pc.entry-overrides.js +1 -1
  69. package/dist/pc/pc.equipment.js +1 -1
  70. package/dist/pc/pc.feature-effects.d.ts +13 -8
  71. package/dist/pc/pc.feature-effects.js +1 -1
  72. package/dist/pc/pc.infusions.js +1 -1
  73. package/dist/pc/pc.item-effects.d.ts +1 -0
  74. package/dist/pc/pc.item-effects.js +1 -0
  75. package/dist/pc/pc.member-choices.js +1 -1
  76. package/dist/pc/pc.parser.js +1 -1
  77. package/dist/pc/pc.pools.js +1 -1
  78. package/dist/pc/pc.proficiencies.js +1 -1
  79. package/dist/pc/pc.proficiency-grants.d.ts +3 -1
  80. package/dist/pc/pc.recalc.d.ts +1 -0
  81. package/dist/pc/pc.recalc.js +1 -1
  82. package/dist/pc/pc.resolver.d.ts +9 -0
  83. package/dist/pc/pc.resolver.js +1 -1
  84. package/dist/pc/pc.resource-seed.js +1 -1
  85. package/dist/pc/pc.resources.js +1 -1
  86. package/dist/pc/pc.rest.js +1 -1
  87. package/dist/pc/pc.schema.d.ts +20 -0
  88. package/dist/pc/pc.schema.js +1 -1
  89. package/dist/pc/pc.speeds.d.ts +20 -3
  90. package/dist/pc/pc.spellcasting.js +1 -1
  91. package/dist/pc/pc.table-column.d.ts +3 -0
  92. package/dist/pc/pc.table-column.js +1 -1
  93. package/dist/pc/pc.types.d.ts +5 -0
  94. package/dist/race/race.codec.js +1 -1
  95. package/dist/race/race.parser.js +1 -1
  96. package/dist/race/race.schema.js +1 -1
  97. package/dist/schemas/choice-schema.js +1 -1
  98. package/dist/schemas/feature-effect-schema.d.ts +23 -2
  99. package/dist/schemas/feature-effect-schema.js +1 -1
  100. package/dist/schemas/feature-schema.js +1 -1
  101. package/dist/subclass/subclass.codec.js +1 -1
  102. package/dist/subclass/subclass.parser.js +1 -1
  103. package/dist/subclass/subclass.schema.js +1 -1
  104. package/dist/types/feature-effect.d.ts +8 -2
  105. package/package.json +1 -1
  106. package/dist/chunk-6IC53O3Q.js +0 -1
  107. package/dist/chunk-7LPKI27J.js +0 -1
  108. package/dist/chunk-HCK6IUB3.js +0 -1
  109. package/dist/chunk-IGVRLGLM.js +0 -1
  110. package/dist/chunk-MC6PLWRZ.js +0 -1
  111. package/dist/chunk-PQAVMK3T.js +0 -1
@@ -0,0 +1 @@
1
+ import{equipmentCategoryKey,isCategoryGrant}from"./chunk-2EOGK6R6.js";import{TOOL_CATEGORIES,backgroundToolPicks,categoryWords,classToolPicks,expandToolPool,toolCategoriesOf}from"./chunk-RQZCGXUZ.js";import{assembleEffectFeatures,classifyProficiencyEffect,collectProficiencyEffectGrants,foldsNow,selfEffectsOf}from"./chunk-GD7WRCNH.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-J3RP5C7L.js";import{classPactWeaponPick,featOfSite,featPickSites,isTargetChoice,memberChoices,pactWeaponPick,poolMemberSites,poolMemberSitesOf,raceFeatSites}from"./chunk-WAUNLUFQ.js";import{collectAdditionalSpells}from"./chunk-CEHL7PPC.js";import{resolveFeatureResources,resolveResourceIndex}from"./chunk-KEXSF3CH.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-PKIMOVQG.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}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;const walk=(choices,read,owner)=>{for(const ch of choices!=null?choices:[]){visit(ch,read(ch.id),owner);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)}}};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,_f,_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)}if(i===0)walk(entity.choices,readAt(1),className);if(i===0)walk(classToolPicks(entity).decisions,readAt(1),className);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);walk(rf.feature.choices,readAt(rf.source.level),featureOwner)}for(const site of featSites){if(site.classIndex!==i)continue;const feat=(_g=featBySlug.get(stripRef(site.slug)))!=null?_g:featOfSite(site,(_f=resolved.feats)!=null?_f:[]);if(!feat)continue;walk(feat.choices,site.read,feat.name)}for(const site of memberSites)if(site.classIndex===i)walk(site.choices,site.read,(_h=site.member.name)!=null?_h:className)});if(resolved.race){const raceName=resolved.race.name;walk(resolved.race.choices,originRead("race"),raceName);for(const t of(_c=resolved.race.traits)!=null?_c:[])walk(t.choices,originRead("race"),raceName)}if(resolved.background){const bgName=resolved.background.name;walk(resolved.background.choices,originRead("background"),bgName);walk(backgroundToolPicks(resolved.background).decisions,originRead("background"),bgName);if(resolved.background.feature){const feature=resolved.background.feature;walk(feature.choices,originRead("background"),bgName)}}if(resolved.originFeatSlug){const of=featBySlug.get(resolved.originFeatSlug);if(of)walk(of.choices,id=>oc[`background:feat:${id}`],of.name)}for(const site of raceFeatSites(resolved.race,oc)){const rf=(_e=featBySlug.get(stripRef(site.slug)))!=null?_e:((_d=resolved.feats)!=null?_d:[]).find(f=>bareEntitySlug(f.slug)===bareEntitySlug(site.slug));if(rf)walk(rf.choices,site.read,rf.name)}}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)=>{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)}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);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)})}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;if(bg)for(const sk of(_d=bg.skill_proficiencies)!=null?_d:[])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;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 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];for(const b of grantBuckets)for(const g of b)push(g.value,"grant",g.source,g.expertise);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}))}};if(resolved.race){const bare=bareEntitySlug(resolved.race.slug);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);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=lookup(character.race,"race");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;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,computeEffectiveProficiencies,computeSuppressedProficiencies,collectChosenAbilityPoints,buildDecisionLedger};
@@ -1 +1 @@
1
- import{resolveSpellcasting}from"./chunk-NI364WV7.js";import{heldPicks}from"./chunk-DY6FVAGA.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-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 +1 @@
1
- import{startingEquipmentEntrySchema}from"./chunk-TKIEPC6F.js";import{choiceSchema}from"./chunk-KBFSJ5WE.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 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 wikilinkRegex=/^\[\[[^[\]]+\]\]$/;var toolProfSchema=z.discriminatedUnion("kind",[z.object({kind:z.literal("fixed"),items:z.array(z.string()).nonempty()}),z.object({kind:z.literal("choice"),count:z.number().int().positive(),from:z.array(z.string()).nonempty()})]);var langProfSchema=z.discriminatedUnion("kind",[z.object({kind:z.literal("fixed"),languages:z.array(z.string()).nonempty()}),z.object({kind:z.literal("choice"),count:z.number().int().positive(),from:z.union([z.string(),z.array(z.string())])})]);var suggestedCharSchema=z.object({personality_traits:z.record(z.string(),z.string()).optional(),ideals:z.record(z.string(),z.object({name:z.string().optional(),desc:z.string(),alignment:z.string().optional()})).optional(),bonds:z.record(z.string(),z.string()).optional(),flaws:z.record(z.string(),z.string()).optional()});var backgroundEntitySchema=z.object({slug:z.string().min(1),name:z.string().min(1),edition:editionEnum,source:z.string().min(1),description:z.string(),skill_proficiencies:z.array(skillEnum),tool_proficiencies:z.array(toolProfSchema),language_proficiencies:z.array(langProfSchema),equipment:z.array(startingEquipmentEntrySchema),feature:z.object({name:z.string().min(1),description:z.string().min(1)}),ability_score_increases:z.object({pool:z.array(abilityEnum).length(3)}).nullable(),origin_feat:z.string().regex(wikilinkRegex).nullable(),suggested_characteristics:suggestedCharSchema.nullable(),choices:z.array(choiceSchema).optional(),rendering_hint:z.string().optional(),has_fluff_images:z.boolean().optional(),tables:z.array(z.object({name:z.string().min(1),dice:z.string().min(1),rows:z.array(z.object({roll:z.string(),text:z.string()}))})).optional(),additional_spells:z.array(additionalSpellsEntrySchema).optional(),prerequisites:z.array(z.object({kind:z.literal("campaign"),slug:z.string().min(1)})).optional(),image:imageField});export{langProfSchema,backgroundEntitySchema};
1
+ import{startingEquipmentEntrySchema}from"./chunk-TKIEPC6F.js";import{choiceSchema}from"./chunk-LHH5XSEA.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 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 wikilinkRegex=/^\[\[[^[\]]+\]\]$/;var toolProfSchema=z.discriminatedUnion("kind",[z.object({kind:z.literal("fixed"),items:z.array(z.string()).nonempty()}),z.object({kind:z.literal("choice"),count:z.number().int().positive(),from:z.array(z.string()).nonempty()})]);var langProfSchema=z.discriminatedUnion("kind",[z.object({kind:z.literal("fixed"),languages:z.array(z.string()).nonempty()}),z.object({kind:z.literal("choice"),count:z.number().int().positive(),from:z.union([z.string(),z.array(z.string())])})]);var suggestedCharSchema=z.object({personality_traits:z.record(z.string(),z.string()).optional(),ideals:z.record(z.string(),z.object({name:z.string().optional(),desc:z.string(),alignment:z.string().optional()})).optional(),bonds:z.record(z.string(),z.string()).optional(),flaws:z.record(z.string(),z.string()).optional()});var backgroundEntitySchema=z.object({slug:z.string().min(1),name:z.string().min(1),edition:editionEnum,source:z.string().min(1),description:z.string(),skill_proficiencies:z.array(skillEnum),tool_proficiencies:z.array(toolProfSchema),language_proficiencies:z.array(langProfSchema),equipment:z.array(startingEquipmentEntrySchema),feature:z.object({name:z.string().min(1),description:z.string().min(1)}),ability_score_increases:z.object({pool:z.array(abilityEnum).length(3)}).nullable(),origin_feat:z.string().regex(wikilinkRegex).nullable(),suggested_characteristics:suggestedCharSchema.nullable(),choices:z.array(choiceSchema).optional(),rendering_hint:z.string().optional(),has_fluff_images:z.boolean().optional(),tables:z.array(z.object({name:z.string().min(1),dice:z.string().min(1),rows:z.array(z.object({roll:z.string(),text:z.string()}))})).optional(),additional_spells:z.array(additionalSpellsEntrySchema).optional(),prerequisites:z.array(z.object({kind:z.literal("campaign"),slug:z.string().min(1)})).optional(),image:imageField});export{langProfSchema,backgroundEntitySchema};
@@ -1 +1 @@
1
- import{featureEffectSchema}from"./chunk-6IC53O3Q.js";import{z}from"zod";var abilityEnum=z.enum(["str","dex","con","int","wis","cha"]);var entityFilterSchema=z.object({feature_type:z.string().min(1).optional(),category:z.string().min(1).optional(),parent_class:z.literal("self").optional(),available_to:z.literal("self").optional(),weapon_category:z.enum(["simple","martial"]).optional(),armor_category:z.enum(["light","medium","heavy","shield"]).optional(),item_type:z.array(z.string().min(1)).nonempty().optional(),mundane:z.boolean().optional(),list:z.string().min(1).optional(),level:z.number().int().min(0).max(9).optional(),edition:z.string().min(1).optional(),ritual:z.boolean().optional(),inventory:z.boolean().optional()}).strict();var inlineOptionSchema=z.lazy(()=>z.object({value:z.string().min(1),label:z.string().min(1),description:z.string().optional(),effects:z.array(featureEffectSchema).optional(),choices:z.array(choiceSchema).optional()}).strict());var choiceSchema=z.lazy(()=>z.discriminatedUnion("kind",[z.object({kind:z.literal("select-inline"),id:z.string().min(1),label:z.string().optional(),count:z.number().int().positive().optional(),options:z.array(inlineOptionSchema).nonempty()}).strict(),z.object({kind:z.literal("select-entity"),id:z.string().min(1),label:z.string().optional(),count:z.number().int().positive().optional(),entity_type:z.string().min(1),from:z.array(z.string().min(1)).nonempty().optional(),where:entityFilterSchema.optional(),target:z.literal(true).optional()}).strict(),z.object({kind:z.literal("select-proficiency"),id:z.string().min(1),label:z.string().optional(),count:z.number().int().positive(),domain:z.enum(["skill","tool","language","save"]),from:z.array(z.string().min(1)).nonempty().optional(),from_proficient:z.boolean().optional(),expertise:z.boolean().optional()}).strict(),z.object({kind:z.literal("ability-points"),id:z.string().min(1),label:z.string().optional(),points:z.number().int().positive(),max_per:z.number().int().positive(),pool:z.array(abilityEnum).nonempty().optional()}).strict()]));export{choiceSchema};
1
+ import{featureEffectSchema}from"./chunk-ZVL5FXXO.js";import{z}from"zod";var abilityEnum=z.enum(["str","dex","con","int","wis","cha"]);var entityFilterSchema=z.object({feature_type:z.string().min(1).optional(),category:z.string().min(1).optional(),parent_class:z.literal("self").optional(),available_to:z.literal("self").optional(),weapon_category:z.enum(["simple","martial"]).optional(),armor_category:z.enum(["light","medium","heavy","shield"]).optional(),item_type:z.array(z.string().min(1)).nonempty().optional(),mundane:z.boolean().optional(),list:z.string().min(1).optional(),level:z.number().int().min(0).max(9).optional(),edition:z.string().min(1).optional(),ritual:z.boolean().optional(),inventory:z.boolean().optional()}).strict();var inlineOptionSchema=z.lazy(()=>z.object({value:z.string().min(1),label:z.string().min(1),description:z.string().optional(),effects:z.array(featureEffectSchema).optional(),choices:z.array(choiceSchema).optional()}).strict());var choiceSchema=z.lazy(()=>z.discriminatedUnion("kind",[z.object({kind:z.literal("select-inline"),id:z.string().min(1),label:z.string().optional(),count:z.number().int().positive().optional(),options:z.array(inlineOptionSchema).nonempty()}).strict(),z.object({kind:z.literal("select-entity"),id:z.string().min(1),label:z.string().optional(),count:z.number().int().positive().optional(),entity_type:z.string().min(1),from:z.array(z.string().min(1)).nonempty().optional(),where:entityFilterSchema.optional(),target:z.literal(true).optional()}).strict(),z.object({kind:z.literal("select-proficiency"),id:z.string().min(1),label:z.string().optional(),count:z.number().int().positive(),domain:z.enum(["skill","tool","language","save"]),from:z.array(z.string().min(1)).nonempty().optional(),from_proficient:z.boolean().optional(),expertise:z.boolean().optional()}).strict(),z.object({kind:z.literal("ability-points"),id:z.string().min(1),label:z.string().optional(),points:z.number().int().positive(),max_per:z.number().int().positive(),pool:z.array(abilityEnum).nonempty().optional()}).strict()]));export{choiceSchema};
@@ -1 +1 @@
1
- import{durationSchema}from"./chunk-ZE46ADXS.js";import{actionCostEnum,resourceConsumptionSchema,resourceSchema}from"./chunk-CCFIINBA.js";import{choiceSchema}from"./chunk-KBFSJ5WE.js";import{featureEffectSchema}from"./chunk-6IC53O3Q.js";import{z as z2}from"zod";import{z}from"zod";var abilityEnum=z.enum(["str","dex","con","int","wis","cha"]);var attackSchema=z.object({name:z.string().min(1),type:z.enum(["melee","ranged","spell"]),ability:z.union([abilityEnum,z.array(abilityEnum).nonempty()]).optional(),damage:z.string().optional(),damage_type:z.string().optional(),action:z.enum(["action","bonus-action","reaction"]).optional(),properties:z.array(z.string()).optional(),range:z.object({normal:z.number().int().nonnegative().optional(),long:z.number().int().nonnegative().optional(),reach:z.number().int().nonnegative().optional()}).optional(),condition:z.string().optional(),bonus:z.number().optional(),extra_damage:z.object({dice:z.string(),type:z.string()}).optional(),weapon_category:z.enum(["simple","martial"]).optional(),mastery:z.string().min(1).optional()});var companionSchema=z2.object({statblock:z2.string().optional(),statblock_wikilink:z2.string().nullable().optional(),count:z2.string().optional(),count_scaling:z2.array(z2.object({level:z2.number().optional(),count:z2.string().optional(),source_quote:z2.string().optional()})).optional(),shares_action_economy:z2.boolean().optional(),turn_order:z2.string().optional(),turn_order_source_quote:z2.string().nullable().optional(),proficiency_bonus_scaled:z2.array(z2.object({stat:z2.string().optional(),formula:z2.string().optional(),source_quote:z2.string().optional()})).optional(),lifecycle:z2.object({created_by:z2.string().optional(),recreate_on:z2.string().nullable().optional(),previous_instance_perishes:z2.boolean().nullable().optional(),vanishes_if_owner_dies:z2.boolean().nullable().optional(),vanishes_after:z2.string().nullable().optional(),source_quote:z2.string().optional()}).nullable().optional(),autonomy:z2.object({when:z2.string().optional(),behaviour:z2.string().optional(),source_quote:z2.string().optional()}).nullable().optional(),variants:z2.array(z2.object({axis:z2.string().optional(),choices:z2.array(z2.string()).optional(),chosen_at:z2.string().optional(),source_quote:z2.string().optional()})).optional(),base_statblock:z2.string().nullable().optional(),overrides:z2.array(z2.object({field:z2.string().optional(),value:z2.string().optional(),source_quote:z2.string().optional()})).optional(),source_quote:z2.string().optional()});var featureObjectSchema=z2.lazy(()=>z2.object({id:z2.string().min(1).optional(),name:z2.string().min(1),description:z2.string().optional(),entries:z2.array(z2.string()).optional(),choices:z2.array(choiceSchema).optional(),grants_resource:z2.string().optional(),consumes:resourceConsumptionSchema.optional(),attacks:z2.array(attackSchema).optional(),action:z2.enum(["action","bonus-action","reaction","free","special"]).optional(),trigger:z2.string().optional(),dc_formula:z2.string().optional(),effects:z2.array(featureEffectSchema).optional(),sub_features:z2.array(featureSchemaTyped).optional(),resources:z2.array(resourceSchema).optional(),activatable:z2.boolean().optional(),passive:z2.boolean().optional(),duration:durationSchema.optional(),class_source:z2.string().min(1).optional(),rendering_hint:z2.string().optional(),subclass_short_name:z2.string().min(1).optional(),subclass_source:z2.string().min(1).optional(),header:z2.number().optional(),is_class_feature_variant:z2.boolean().optional(),gain_subclass_feature:z2.boolean().optional(),gain_subclass_feature_has_content:z2.boolean().optional(),type:z2.string().min(1).optional(),recharge:z2.object({type:z2.enum(["recharge_on_roll","per_day","per_short_rest","per_long_rest"]),param:z2.number()}).optional(),action_cost:actionCostEnum.optional(),save:z2.object({ability:z2.string().min(1),dc_formula:z2.string().min(1)}).optional(),companion:companionSchema.optional()}));var featureSchemaTyped=featureObjectSchema.refine(f=>f.description!==void 0||f.entries!==void 0&&f.entries.length>0,{message:"feature requires either description or non-empty entries"});var featureSchema=featureSchemaTyped;export{featureObjectSchema,featureSchema};
1
+ import{durationSchema}from"./chunk-ZE46ADXS.js";import{actionCostEnum,resourceConsumptionSchema,resourceSchema}from"./chunk-CCFIINBA.js";import{choiceSchema}from"./chunk-LHH5XSEA.js";import{featureEffectSchema}from"./chunk-ZVL5FXXO.js";import{z as z2}from"zod";import{z}from"zod";var abilityEnum=z.enum(["str","dex","con","int","wis","cha"]);var attackSchema=z.object({name:z.string().min(1),type:z.enum(["melee","ranged","spell"]),ability:z.union([abilityEnum,z.array(abilityEnum).nonempty()]).optional(),damage:z.string().optional(),damage_type:z.string().optional(),action:z.enum(["action","bonus-action","reaction"]).optional(),properties:z.array(z.string()).optional(),range:z.object({normal:z.number().int().nonnegative().optional(),long:z.number().int().nonnegative().optional(),reach:z.number().int().nonnegative().optional()}).optional(),condition:z.string().optional(),bonus:z.number().optional(),extra_damage:z.object({dice:z.string(),type:z.string()}).optional(),weapon_category:z.enum(["simple","martial"]).optional(),mastery:z.string().min(1).optional()});var companionSchema=z2.object({statblock:z2.string().optional(),statblock_wikilink:z2.string().nullable().optional(),count:z2.string().optional(),count_scaling:z2.array(z2.object({level:z2.number().optional(),count:z2.string().optional(),source_quote:z2.string().optional()})).optional(),shares_action_economy:z2.boolean().optional(),turn_order:z2.string().optional(),turn_order_source_quote:z2.string().nullable().optional(),proficiency_bonus_scaled:z2.array(z2.object({stat:z2.string().optional(),formula:z2.string().optional(),source_quote:z2.string().optional()})).optional(),lifecycle:z2.object({created_by:z2.string().optional(),recreate_on:z2.string().nullable().optional(),previous_instance_perishes:z2.boolean().nullable().optional(),vanishes_if_owner_dies:z2.boolean().nullable().optional(),vanishes_after:z2.string().nullable().optional(),source_quote:z2.string().optional()}).nullable().optional(),autonomy:z2.object({when:z2.string().optional(),behaviour:z2.string().optional(),source_quote:z2.string().optional()}).nullable().optional(),variants:z2.array(z2.object({axis:z2.string().optional(),choices:z2.array(z2.string()).optional(),chosen_at:z2.string().optional(),source_quote:z2.string().optional()})).optional(),base_statblock:z2.string().nullable().optional(),overrides:z2.array(z2.object({field:z2.string().optional(),value:z2.string().optional(),source_quote:z2.string().optional()})).optional(),source_quote:z2.string().optional()});var featureObjectSchema=z2.lazy(()=>z2.object({id:z2.string().min(1).optional(),name:z2.string().min(1),description:z2.string().optional(),entries:z2.array(z2.string()).optional(),choices:z2.array(choiceSchema).optional(),grants_resource:z2.string().optional(),consumes:resourceConsumptionSchema.optional(),attacks:z2.array(attackSchema).optional(),action:z2.enum(["action","bonus-action","reaction","free","special"]).optional(),trigger:z2.string().optional(),dc_formula:z2.string().optional(),effects:z2.array(featureEffectSchema).optional(),sub_features:z2.array(featureSchemaTyped).optional(),resources:z2.array(resourceSchema).optional(),activatable:z2.boolean().optional(),passive:z2.boolean().optional(),duration:durationSchema.optional(),class_source:z2.string().min(1).optional(),rendering_hint:z2.string().optional(),subclass_short_name:z2.string().min(1).optional(),subclass_source:z2.string().min(1).optional(),header:z2.number().optional(),is_class_feature_variant:z2.boolean().optional(),gain_subclass_feature:z2.boolean().optional(),gain_subclass_feature_has_content:z2.boolean().optional(),type:z2.string().min(1).optional(),recharge:z2.object({type:z2.enum(["recharge_on_roll","per_day","per_short_rest","per_long_rest"]),param:z2.number()}).optional(),action_cost:actionCostEnum.optional(),save:z2.object({ability:z2.string().min(1),dc_formula:z2.string().min(1)}).optional(),companion:companionSchema.optional()}));var featureSchemaTyped=featureObjectSchema.refine(f=>f.description!==void 0||f.entries!==void 0&&f.entries.length>0,{message:"feature requires either description or non-empty entries"});var featureSchema=featureSchemaTyped;export{featureObjectSchema,featureSchema};
@@ -1 +1 @@
1
- import{parseFeat}from"./chunk-IOCJIWCV.js";import yaml from"js-yaml";var featCodec={parse(doc){return parseFeat(doc.body)},serialize(entity){return yaml.dump(entity,{lineWidth:-1,sortKeys:false})}};export{featCodec};
1
+ import{parseFeat}from"./chunk-OTRH62HY.js";import yaml from"js-yaml";var featCodec={parse(doc){return parseFeat(doc.body)},serialize(entity){return yaml.dump(entity,{lineWidth:-1,sortKeys:false})}};export{featCodec};
@@ -1 +1 @@
1
- import{durationSchema}from"./chunk-ZE46ADXS.js";import{actionCostEnum,resetTriggerEnum,resourceConsumptionSchema}from"./chunk-CCFIINBA.js";import{choiceSchema}from"./chunk-KBFSJ5WE.js";import{featureEffectSchema}from"./chunk-6IC53O3Q.js";import{additionalSpellsEntrySchema,imageField,progressionSchema}from"./chunk-I26FHSI6.js";import{z}from"zod";var editionEnum=z.enum(["2014","2024"]);var abilityEnum=z.enum(["str","dex","con","int","wis","cha"]);var wikilinkRegex=/^\[\[[^[\]]+\]\]$/;var namedRefSchema=z.object({name:z.string().min(1),source:z.string().min(1).optional(),visible_stats:z.boolean().optional()});var prerequisiteSchema=z.discriminatedUnion("kind",[z.object({kind:z.literal("level"),min:z.number().int().positive(),class:namedRefSchema.optional(),subclass:namedRefSchema.optional()}),z.object({kind:z.literal("spell-known"),spell:z.string().regex(wikilinkRegex)}),z.object({kind:z.literal("pact"),pact:z.enum(["tome","blade","chain","talisman"])}),z.object({kind:z.literal("class"),class:z.string().regex(wikilinkRegex)}),z.object({kind:z.literal("ability"),ability:abilityEnum,min:z.number().int().positive()}),z.object({kind:z.literal("other"),detail:z.string()}),z.object({kind:z.literal("optionalfeature"),optionalfeature:z.string().regex(wikilinkRegex)}),z.object({kind:z.literal("spell-choose"),choose:z.string().min(1),entry:z.string().optional(),entry_summary:z.string().optional()})]);var usesSchema=z.object({max:z.union([z.number(),z.string()]),recharge:resetTriggerEnum,recovery:z.array(z.object({id:z.string().min(1),name:z.string().min(1),amount:z.union([z.number(),z.string()]),reset:resetTriggerEnum,restores:z.enum(["uses","spell-slots"]).optional()})).optional()});var filterSpecSchema=z.object({rarity:z.array(z.string().min(1)).min(1),types:z.array(z.string().min(1)).optional(),exclude_types:z.array(z.string().min(1)).optional(),cursed:z.literal(false).optional()}).strict();var optionCreatesSchema=z.object({item:z.string().regex(wikilinkRegex).optional(),variant:z.object({candidates:z.array(z.string().regex(wikilinkRegex)).min(1)}).strict().optional(),filter:filterSpecSchema.optional()}).strict().refine(c=>[c.item,c.variant,c.filter].filter(a=>a!==void 0).length===1,{message:"creates needs exactly one of item, variant, filter"});var optionRowSchema=z.object({key:z.string().regex(/^[a-z0-9][a-z0-9._-]*$/,"an option key is lower-case, with no '#' and no whitespace"),name:z.string().min(1),min_level:z.number().int().min(1).max(20),attunement:z.boolean().optional(),creates:optionCreatesSchema}).strict();var infuseItemSchema=z.object({bonuses:z.object({ac:z.number().int().optional(),weapon_attack:z.number().int().optional(),weapon_damage:z.number().int().optional(),spell_attack:z.number().int().optional(),saving_throws:z.number().int().optional(),speed:z.object({walk:z.number().int().optional(),fly:z.number().int().optional(),swim:z.number().int().optional(),climb:z.number().int().optional()}).strict().optional()}).strict().optional(),resist:z.array(z.string().min(1)).optional(),charges:z.object({max:z.number().int().min(1),dice:z.string().optional(),recharge:z.string().optional(),recharge_amount:z.string().optional()}).strict().optional(),action:actionCostEnum.optional(),range:z.string().min(1).optional()}).strict();var infuseBlockSchema=z.object({targets:z.array(z.object({kind:z.enum(["armor","shield","weapon","gear"]),category:z.array(z.string().min(1)).min(1).optional(),property:z.string().min(1).optional(),name_any:z.array(z.string().min(1)).min(1).optional()}).strict()).min(1),targets_label:z.string().min(1).optional(),new_object:z.string().min(1).optional(),rarity:z.string().min(1).optional(),attunement:z.object({required:z.literal(true)}).strict().optional(),choice:z.object({kind:z.literal("damage-type"),options:z.array(z.string().min(1)).min(1).optional()}).strict().optional(),item:infuseItemSchema.optional(),scales_at:z.array(z.object({level:z.number().int().min(1).max(20),item:infuseItemSchema}).strict()).optional()}).strict().refine(b=>{var _a;return((_a=b.scales_at)!=null?_a:[]).every((r,i,a)=>i===0||a[i-1].level<r.level)},{message:"scales_at levels ascend"});var optionalFeatureEntitySchema=z.object({slug:z.string().min(1),name:z.string().min(1),edition:editionEnum,source:z.string().min(1),feature_type:z.string().min(1),description:z.string(),prerequisites:z.array(prerequisiteSchema),available_to:z.array(z.string().regex(wikilinkRegex)),effects:z.array(featureEffectSchema),action_cost:actionCostEnum.nullable().optional(),uses:usesSchema.nullable().optional(),consumes:resourceConsumptionSchema.nullable().optional(),duration:durationSchema.nullable().optional(),passive:z.boolean().optional(),activatable:z.boolean().optional(),rendering_hint:z.string().optional(),surface:z.enum(["band","tab"]).optional(),additional_spells:z.array(additionalSpellsEntrySchema).optional(),is_class_feature_variant:z.boolean().optional(),has_fluff_images:z.boolean().optional(),feat_progression:z.array(progressionSchema).optional(),optionalfeature_progression:z.array(progressionSchema).optional(),image:imageField,repeatable:z.literal(true).optional(),item_choice:z.enum(["learn","create"]).optional(),options:z.array(optionRowSchema).optional(),infuse:infuseBlockSchema.optional(),choices:z.array(choiceSchema).optional()}).superRefine((d,ctx)=>{var _a;if(d.repeatable&&(!d.options||!d.item_choice))ctx.addIssue({code:"custom",message:"a repeatable note needs options and item_choice"});const keys=((_a=d.options)!=null?_a:[]).map(o=>o.key);if(new Set(keys).size!==keys.length)ctx.addIssue({code:"custom",message:"option keys are unique"})});export{optionRowSchema,infuseBlockSchema,optionalFeatureEntitySchema};
1
+ import{durationSchema}from"./chunk-ZE46ADXS.js";import{actionCostEnum,resetTriggerEnum,resourceConsumptionSchema}from"./chunk-CCFIINBA.js";import{choiceSchema}from"./chunk-LHH5XSEA.js";import{featureEffectSchema}from"./chunk-ZVL5FXXO.js";import{additionalSpellsEntrySchema,imageField,progressionSchema}from"./chunk-I26FHSI6.js";import{z}from"zod";var editionEnum=z.enum(["2014","2024"]);var abilityEnum=z.enum(["str","dex","con","int","wis","cha"]);var wikilinkRegex=/^\[\[[^[\]]+\]\]$/;var namedRefSchema=z.object({name:z.string().min(1),source:z.string().min(1).optional(),visible_stats:z.boolean().optional()});var prerequisiteSchema=z.discriminatedUnion("kind",[z.object({kind:z.literal("level"),min:z.number().int().positive(),class:namedRefSchema.optional(),subclass:namedRefSchema.optional()}),z.object({kind:z.literal("spell-known"),spell:z.string().regex(wikilinkRegex)}),z.object({kind:z.literal("pact"),pact:z.enum(["tome","blade","chain","talisman"])}),z.object({kind:z.literal("class"),class:z.string().regex(wikilinkRegex)}),z.object({kind:z.literal("ability"),ability:abilityEnum,min:z.number().int().positive()}),z.object({kind:z.literal("other"),detail:z.string()}),z.object({kind:z.literal("optionalfeature"),optionalfeature:z.string().regex(wikilinkRegex)}),z.object({kind:z.literal("spell-choose"),choose:z.string().min(1),entry:z.string().optional(),entry_summary:z.string().optional()})]);var usesSchema=z.object({max:z.union([z.number(),z.string()]),recharge:resetTriggerEnum,recovery:z.array(z.object({id:z.string().min(1),name:z.string().min(1),amount:z.union([z.number(),z.string()]),reset:resetTriggerEnum,restores:z.enum(["uses","spell-slots"]).optional()})).optional()});var filterSpecSchema=z.object({rarity:z.array(z.string().min(1)).min(1),types:z.array(z.string().min(1)).optional(),exclude_types:z.array(z.string().min(1)).optional(),cursed:z.literal(false).optional()}).strict();var optionCreatesSchema=z.object({item:z.string().regex(wikilinkRegex).optional(),variant:z.object({candidates:z.array(z.string().regex(wikilinkRegex)).min(1)}).strict().optional(),filter:filterSpecSchema.optional()}).strict().refine(c=>[c.item,c.variant,c.filter].filter(a=>a!==void 0).length===1,{message:"creates needs exactly one of item, variant, filter"});var optionRowSchema=z.object({key:z.string().regex(/^[a-z0-9][a-z0-9._-]*$/,"an option key is lower-case, with no '#' and no whitespace"),name:z.string().min(1),min_level:z.number().int().min(1).max(20),attunement:z.boolean().optional(),creates:optionCreatesSchema}).strict();var infuseItemSchema=z.object({bonuses:z.object({ac:z.number().int().optional(),weapon_attack:z.number().int().optional(),weapon_damage:z.number().int().optional(),spell_attack:z.number().int().optional(),saving_throws:z.number().int().optional(),speed:z.object({walk:z.number().int().optional(),fly:z.number().int().optional(),swim:z.number().int().optional(),climb:z.number().int().optional()}).strict().optional()}).strict().optional(),resist:z.array(z.string().min(1)).optional(),charges:z.object({max:z.number().int().min(1),dice:z.string().optional(),recharge:z.string().optional(),recharge_amount:z.string().optional()}).strict().optional(),action:actionCostEnum.optional(),range:z.string().min(1).optional()}).strict();var infuseBlockSchema=z.object({targets:z.array(z.object({kind:z.enum(["armor","shield","weapon","gear"]),category:z.array(z.string().min(1)).min(1).optional(),property:z.string().min(1).optional(),name_any:z.array(z.string().min(1)).min(1).optional()}).strict()).min(1),targets_label:z.string().min(1).optional(),new_object:z.string().min(1).optional(),rarity:z.string().min(1).optional(),attunement:z.object({required:z.literal(true)}).strict().optional(),choice:z.object({kind:z.literal("damage-type"),options:z.array(z.string().min(1)).min(1).optional()}).strict().optional(),item:infuseItemSchema.optional(),scales_at:z.array(z.object({level:z.number().int().min(1).max(20),item:infuseItemSchema}).strict()).optional()}).strict().refine(b=>{var _a;return((_a=b.scales_at)!=null?_a:[]).every((r,i,a)=>i===0||a[i-1].level<r.level)},{message:"scales_at levels ascend"});var optionalFeatureEntitySchema=z.object({slug:z.string().min(1),name:z.string().min(1),edition:editionEnum,source:z.string().min(1),feature_type:z.string().min(1),description:z.string(),prerequisites:z.array(prerequisiteSchema),available_to:z.array(z.string().regex(wikilinkRegex)),effects:z.array(featureEffectSchema),action_cost:actionCostEnum.nullable().optional(),uses:usesSchema.nullable().optional(),consumes:resourceConsumptionSchema.nullable().optional(),duration:durationSchema.nullable().optional(),passive:z.boolean().optional(),activatable:z.boolean().optional(),rendering_hint:z.string().optional(),surface:z.enum(["band","tab"]).optional(),additional_spells:z.array(additionalSpellsEntrySchema).optional(),is_class_feature_variant:z.boolean().optional(),has_fluff_images:z.boolean().optional(),feat_progression:z.array(progressionSchema).optional(),optionalfeature_progression:z.array(progressionSchema).optional(),image:imageField,repeatable:z.literal(true).optional(),item_choice:z.enum(["learn","create"]).optional(),options:z.array(optionRowSchema).optional(),infuse:infuseBlockSchema.optional(),choices:z.array(choiceSchema).optional()}).superRefine((d,ctx)=>{var _a;if(d.repeatable&&(!d.options||!d.item_choice))ctx.addIssue({code:"custom",message:"a repeatable note needs options and item_choice"});const keys=((_a=d.options)!=null?_a:[]).map(o=>o.key);if(new Set(keys).size!==keys.length)ctx.addIssue({code:"custom",message:"option keys are unique"})});export{optionRowSchema,infuseBlockSchema,optionalFeatureEntitySchema};
@@ -1 +1 @@
1
- import{parseBackground}from"./chunk-KZDDFG4O.js";import yaml from"js-yaml";var backgroundCodec={parse(doc){return parseBackground(doc.body)},serialize(entity){return yaml.dump(entity,{lineWidth:-1,sortKeys:false})}};export{backgroundCodec};
1
+ import{parseBackground}from"./chunk-VVJXZZ4Z.js";import yaml from"js-yaml";var backgroundCodec={parse(doc){return parseBackground(doc.body)},serialize(entity){return yaml.dump(entity,{lineWidth:-1,sortKeys:false})}};export{backgroundCodec};
@@ -1 +1 @@
1
- import{poolGrantSchema,selectionPoolSchema,tabDeclSchema}from"./chunk-GCYUCIDN.js";import{casterTypeEnum}from"./chunk-X22SISGM.js";import{featureSchema}from"./chunk-V6NQ547U.js";import{resourceSchema}from"./chunk-CCFIINBA.js";import{additionalSpellsEntrySchema,imageField,progressionSchema}from"./chunk-I26FHSI6.js";import{z}from"zod";var editionEnum=z.enum(["2014","2024"]);var wikilinkRegex=/^\[\[[^[\]]+\]\]$/;var abilityEnum=z.enum(["str","dex","con","int","wis","cha"]);var spellcastingSchema=z.object({caster_type:casterTypeEnum.optional(),ability:abilityEnum,preparation:z.enum(["known","prepared"]).optional(),spell_list:z.string().min(1).optional()});var subclassTableRowSchema=z.object({columns:z.record(z.string(),z.union([z.string(),z.number()])).optional()});var subclassEntitySchema=z.object({slug:z.string().min(1),name:z.string().min(1),parent_class:z.string().regex(wikilinkRegex,"parent_class must be a wikilink like [[rogue]]"),edition:editionEnum,source:z.string().min(1),description:z.string(),spellcasting:spellcastingSchema.nullable().optional(),table:z.record(z.string(),subclassTableRowSchema).optional(),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(),short_name:z.string().min(1).optional(),has_fluff:z.boolean().optional(),has_fluff_images:z.boolean().optional(),fluff:z.unknown().optional(),table_col_labels:z.array(z.string().min(1)).optional(),cantrip_progression:z.array(z.number()).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(),feat_progression:z.array(progressionSchema).optional(),optionalfeature_progression:z.array(progressionSchema).optional(),additional_spells:z.array(additionalSpellsEntrySchema).optional(),image:imageField});export{subclassEntitySchema};
1
+ import{poolGrantSchema,selectionPoolSchema,tabDeclSchema}from"./chunk-GCYUCIDN.js";import{casterTypeEnum}from"./chunk-X22SISGM.js";import{featureSchema}from"./chunk-NIWLD33X.js";import{resourceSchema}from"./chunk-CCFIINBA.js";import{additionalSpellsEntrySchema,imageField,progressionSchema}from"./chunk-I26FHSI6.js";import{z}from"zod";var editionEnum=z.enum(["2014","2024"]);var wikilinkRegex=/^\[\[[^[\]]+\]\]$/;var abilityEnum=z.enum(["str","dex","con","int","wis","cha"]);var spellcastingSchema=z.object({caster_type:casterTypeEnum.optional(),ability:abilityEnum,preparation:z.enum(["known","prepared"]).optional(),spell_list:z.string().min(1).optional()});var subclassTableRowSchema=z.object({columns:z.record(z.string(),z.union([z.string(),z.number()])).optional()});var subclassEntitySchema=z.object({slug:z.string().min(1),name:z.string().min(1),parent_class:z.string().regex(wikilinkRegex,"parent_class must be a wikilink like [[rogue]]"),edition:editionEnum,source:z.string().min(1),description:z.string(),spellcasting:spellcastingSchema.nullable().optional(),table:z.record(z.string(),subclassTableRowSchema).optional(),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(),short_name:z.string().min(1).optional(),has_fluff:z.boolean().optional(),has_fluff_images:z.boolean().optional(),fluff:z.unknown().optional(),table_col_labels:z.array(z.string().min(1)).optional(),cantrip_progression:z.array(z.number()).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(),feat_progression:z.array(progressionSchema).optional(),optionalfeature_progression:z.array(progressionSchema).optional(),additional_spells:z.array(additionalSpellsEntrySchema).optional(),image:imageField});export{subclassEntitySchema};
@@ -1 +1 @@
1
- import{featEntitySchema}from"./chunk-334WLI7V.js";import{parseYaml}from"@archivist-gg/core";function parseFeat(source){const raw=parseYaml(source,["name","slug"]);if(!raw.success)return raw;const result=featEntitySchema.safeParse({edition:"2014",...raw.data});if(!result.success){return{success:false,error:`feat schema validation failed: ${result.error.message}`}}return{success:true,data:result.data}}export{parseFeat};
1
+ import{featEntitySchema}from"./chunk-GIQLIBC7.js";import{parseYaml}from"@archivist-gg/core";function parseFeat(source){const raw=parseYaml(source,["name","slug"]);if(!raw.success)return raw;const result=featEntitySchema.safeParse({edition:"2014",...raw.data});if(!result.success){return{success:false,error:`feat schema validation failed: ${result.error.message}`}}return{success:true,data:result.data}}export{parseFeat};
@@ -1 +1 @@
1
- import{readTableColumn}from"./chunk-BGX36NPE.js";import{bareSlug,baseClassName}from"./chunk-CAPYNIGK.js";import{abilityModifier}from"./chunk-7FPQJDFD.js";function hasPreparedColumn(table){return Object.values(table).some(row=>PREPARED_COLUMNS.some(k=>{var _a;return((_a=row==null?void 0:row.columns)==null?void 0:_a[k])!==void 0}))}function resolveSpellcasting(rc){var _a,_b,_c,_d,_e,_f,_g,_h,_i,_j,_k,_l,_m,_n,_o,_p;const sub=(_b=(_a=rc.subclass)==null?void 0:_a.spellcasting)!=null?_b:null;const cls=(_d=(_c=rc.entity)==null?void 0:_c.spellcasting)!=null?_d:null;const casterType=(_f=(_e=sub==null?void 0:sub.caster_type)!=null?_e:cls==null?void 0:cls.caster_type)!=null?_f:null;const ability=(_h=(_g=sub==null?void 0:sub.ability)!=null?_g:cls==null?void 0:cls.ability)!=null?_h:null;if(!casterType||!ability)return null;const table=(_l=(_k=(sub==null?void 0:sub.caster_type)?(_i=rc.subclass)==null?void 0:_i.table:void 0)!=null?_k:(_j=rc.entity)==null?void 0:_j.table)!=null?_l:{};const preparation=(_n=(_m=sub==null?void 0:sub.preparation)!=null?_m:cls==null?void 0:cls.preparation)!=null?_n:hasPreparedColumn(table)?"prepared":"known";const spellList=(_p=(_o=sub==null?void 0:sub.spell_list)!=null?_o:cls==null?void 0:cls.spell_list)!=null?_p:null;return{ability,casterType,preparation,spellList,table}}function effectiveSpellcastingAbility(classSlug,dataAbility,overrides){var _a,_b;return(_b=(_a=overrides.spellcasting_ability_by_class)==null?void 0:_a[classSlug])!=null?_b:dataAbility}function normalizeKnownSpell(entry){var _a,_b;if(typeof entry==="string"){return{slug:bareSlug(entry),classSlug:null,source:"class",preparedFlag:void 0,alwaysPrepared:false}}return{slug:bareSlug(entry.spell),classSlug:entry.class?bareSlug(entry.class):null,source:(_a=entry.source)!=null?_a:"class",preparedFlag:entry.prepared,alwaysPrepared:(_b=entry.always_prepared)!=null?_b:false}}function firstListedCasterClass(spellClasses,casterClassSlugs){var _a;if(!Array.isArray(spellClasses)||spellClasses.length===0)return null;const listed=new Set(spellClasses.map(c=>baseClassName(String(c))));return(_a=casterClassSlugs.find(slug=>listed.has(baseClassName(slug))))!=null?_a:null}var LISTED_CLASS_NAMES=new WeakMap;var NO_NAMES=new Set;function listedSpellClassNames(registry,compendium){var _a;const count=registry.count();let cached=LISTED_CLASS_NAMES.get(registry);if(!cached||cached.count!==count){const byCompendium=new Map;for(const e of registry.search("","spell",Number.POSITIVE_INFINITY)){const classes=e.data.classes;if(!Array.isArray(classes))continue;let names=byCompendium.get(e.compendium);if(!names)byCompendium.set(e.compendium,names=new Set);for(const c of classes)names.add(baseClassName(String(c)))}cached={count,byCompendium};LISTED_CLASS_NAMES.set(registry,cached)}return(_a=cached.byCompendium.get(compendium))!=null?_a:NO_NAMES}function attributeUnclassedSpell(spellClasses,casters,registry){var _a;const first=casters[0];if(!first)return null;const listed=firstListedCasterClass(spellClasses,casters.map(c=>c.classSlug));if(listed==null||listed===first.classSlug)return first.classSlug;if(first.spellList==null)return first.classSlug;const compendium=(_a=registry.getByTypeAndSlug("class",first.classSlug))==null?void 0:_a.compendium;if(compendium==null||!listedSpellClassNames(registry,compendium).has(baseClassName(first.classSlug)))return first.classSlug;return listed}var FULL_CASTER_SLOTS=[[2,0,0,0,0,0,0,0,0],[3,0,0,0,0,0,0,0,0],[4,2,0,0,0,0,0,0,0],[4,3,0,0,0,0,0,0,0],[4,3,2,0,0,0,0,0,0],[4,3,3,0,0,0,0,0,0],[4,3,3,1,0,0,0,0,0],[4,3,3,2,0,0,0,0,0],[4,3,3,3,1,0,0,0,0],[4,3,3,3,2,0,0,0,0],[4,3,3,3,2,1,0,0,0],[4,3,3,3,2,1,0,0,0],[4,3,3,3,2,1,1,0,0],[4,3,3,3,2,1,1,0,0],[4,3,3,3,2,1,1,1,0],[4,3,3,3,2,1,1,1,0],[4,3,3,3,2,1,1,1,1],[4,3,3,3,3,1,1,1,1],[4,3,3,3,3,2,1,1,1],[4,3,3,3,3,2,2,1,1]];var HALF_CASTER_SLOTS=[[0,0,0,0,0],[2,0,0,0,0],[3,0,0,0,0],[3,0,0,0,0],[4,2,0,0,0],[4,2,0,0,0],[4,3,0,0,0],[4,3,0,0,0],[4,3,2,0,0],[4,3,2,0,0],[4,3,3,0,0],[4,3,3,0,0],[4,3,3,1,0],[4,3,3,1,0],[4,3,3,2,0],[4,3,3,2,0],[4,3,3,3,1],[4,3,3,3,1],[4,3,3,3,2],[4,3,3,3,2]];var THIRD_CASTER_SLOTS=[[0,0,0,0],[0,0,0,0],[2,0,0,0],[3,0,0,0],[3,0,0,0],[3,0,0,0],[4,2,0,0],[4,2,0,0],[4,2,0,0],[4,3,0,0],[4,3,0,0],[4,3,0,0],[4,3,2,0],[4,3,2,0],[4,3,2,0],[4,3,3,0],[4,3,3,0],[4,3,3,0],[4,3,3,1],[4,3,3,1]];var PACT_MAGIC=[{level:1,total:1},{level:1,total:2},{level:2,total:2},{level:2,total:2},{level:3,total:2},{level:3,total:2},{level:4,total:2},{level:4,total:2},{level:5,total:2},{level:5,total:2},{level:5,total:3},{level:5,total:3},{level:5,total:3},{level:5,total:3},{level:5,total:3},{level:5,total:3},{level:5,total:4},{level:5,total:4},{level:5,total:4},{level:5,total:4}];var HALF_UP_CASTER_SLOTS=HALF_CASTER_SLOTS.map(row=>[...row]);HALF_UP_CASTER_SLOTS[0]=[2,0,0,0,0];function slotTableFor(caster){switch(caster){case"full":return FULL_CASTER_SLOTS;case"half":return HALF_CASTER_SLOTS;case"third":return THIRD_CASTER_SLOTS;case"half-up":return HALF_UP_CASTER_SLOTS;default:{const _n=caster;throw new Error(`unknown caster type ${String(_n)}`)}}}function rowToRecord(row){const out={};row.forEach((n,i)=>{if(n>0)out[i+1]=n});return out}function deriveSpellSlots(classes){let fullLevels=0,halfLevels=0,thirdLevels=0,halfUpLevels=0,warlockLevel=0;const regular=[];for(const c of classes){if(c.casterType==="pact"){warlockLevel+=c.level;continue}regular.push({caster:c.casterType,level:c.level});switch(c.casterType){case"full":fullLevels+=c.level;break;case"half":halfLevels+=c.level;break;case"third":thirdLevels+=c.level;break;case"half-up":halfUpLevels+=c.level;break;default:{const _n=c.casterType;throw new Error(`unknown caster type ${String(_n)}`)}}}let standard={};if(regular.length===1){const only=regular[0];const table=slotTableFor(only.caster);const idx=only.level-1;if(idx>=0&&idx<table.length)standard=rowToRecord(table[idx])}else if(regular.length>=2){const cl=fullLevels+Math.floor(halfLevels/2)+Math.floor(thirdLevels/3)+Math.ceil(halfUpLevels/2);if(cl>=1&&cl<=FULL_CASTER_SLOTS.length)standard=rowToRecord(FULL_CASTER_SLOTS[cl-1])}const pact=warlockLevel>=1&&warlockLevel<=PACT_MAGIC.length?PACT_MAGIC[warlockLevel-1]:null;return{standard,pact}}var PREPARED_COLUMNS=["Prepared Spells","Spells Prepared"];function preparedLevelTerm(caster,level){switch(caster){case"full":case"pact":return level;case"half":case"half-up":return Math.floor(level/2);case"third":return Math.floor(level/3);default:{const _n=caster;throw new Error(`unknown caster type ${String(_n)}`)}}}function computeSpellLimits(inputs){const out=[];for(const i of inputs){const p=i.profile;const cantripsKnown=readTableColumn(p.table,i.level,["Cantrips Known","Cantrips"]);const mod=abilityModifier(i.abilityScore);let preparedOrKnown;if(p.preparation==="prepared"){const fromTable=readTableColumn(p.table,i.level,PREPARED_COLUMNS);preparedOrKnown=fromTable!==null?fromTable:Math.max(1,mod+preparedLevelTerm(p.casterType,i.level))}else{preparedOrKnown=readTableColumn(p.table,i.level,["Spells Known","Prepared Spells"])}out.push({classSlug:i.classSlug,kind:p.preparation,cantripsKnown,preparedOrKnown})}return out}export{resolveSpellcasting,effectiveSpellcastingAbility,normalizeKnownSpell,listedSpellClassNames,attributeUnclassedSpell,slotTableFor,deriveSpellSlots,PREPARED_COLUMNS,preparedLevelTerm,computeSpellLimits};
1
+ import{readTableColumn}from"./chunk-CSTAQQGX.js";import{bareSlug,baseClassName}from"./chunk-CAPYNIGK.js";import{abilityModifier}from"./chunk-7FPQJDFD.js";function hasPreparedColumn(table){return Object.values(table).some(row=>PREPARED_COLUMNS.some(k=>{var _a;return((_a=row==null?void 0:row.columns)==null?void 0:_a[k])!==void 0}))}function resolveSpellcasting(rc){var _a,_b,_c,_d,_e,_f,_g,_h,_i,_j,_k,_l,_m,_n,_o,_p;const sub=(_b=(_a=rc.subclass)==null?void 0:_a.spellcasting)!=null?_b:null;const cls=(_d=(_c=rc.entity)==null?void 0:_c.spellcasting)!=null?_d:null;const casterType=(_f=(_e=sub==null?void 0:sub.caster_type)!=null?_e:cls==null?void 0:cls.caster_type)!=null?_f:null;const ability=(_h=(_g=sub==null?void 0:sub.ability)!=null?_g:cls==null?void 0:cls.ability)!=null?_h:null;if(!casterType||!ability)return null;const table=(_l=(_k=(sub==null?void 0:sub.caster_type)?(_i=rc.subclass)==null?void 0:_i.table:void 0)!=null?_k:(_j=rc.entity)==null?void 0:_j.table)!=null?_l:{};const preparation=(_n=(_m=sub==null?void 0:sub.preparation)!=null?_m:cls==null?void 0:cls.preparation)!=null?_n:hasPreparedColumn(table)?"prepared":"known";const spellList=(_p=(_o=sub==null?void 0:sub.spell_list)!=null?_o:cls==null?void 0:cls.spell_list)!=null?_p:null;return{ability,casterType,preparation,spellList,table}}function effectiveSpellcastingAbility(classSlug,dataAbility,overrides){var _a,_b;return(_b=(_a=overrides.spellcasting_ability_by_class)==null?void 0:_a[classSlug])!=null?_b:dataAbility}function normalizeKnownSpell(entry){var _a,_b;if(typeof entry==="string"){return{slug:bareSlug(entry),classSlug:null,source:"class",preparedFlag:void 0,alwaysPrepared:false}}return{slug:bareSlug(entry.spell),classSlug:entry.class?bareSlug(entry.class):null,source:(_a=entry.source)!=null?_a:"class",preparedFlag:entry.prepared,alwaysPrepared:(_b=entry.always_prepared)!=null?_b:false}}function firstListedCasterClass(spellClasses,casterClassSlugs){var _a;if(!Array.isArray(spellClasses)||spellClasses.length===0)return null;const listed=new Set(spellClasses.map(c=>baseClassName(String(c))));return(_a=casterClassSlugs.find(slug=>listed.has(baseClassName(slug))))!=null?_a:null}var LISTED_CLASS_NAMES=new WeakMap;var NO_NAMES=new Set;function listedSpellClassNames(registry,compendium){var _a;const count=registry.count();let cached=LISTED_CLASS_NAMES.get(registry);if(!cached||cached.count!==count){const byCompendium=new Map;for(const e of registry.search("","spell",Number.POSITIVE_INFINITY)){const classes=e.data.classes;if(!Array.isArray(classes))continue;let names=byCompendium.get(e.compendium);if(!names)byCompendium.set(e.compendium,names=new Set);for(const c of classes)names.add(baseClassName(String(c)))}cached={count,byCompendium};LISTED_CLASS_NAMES.set(registry,cached)}return(_a=cached.byCompendium.get(compendium))!=null?_a:NO_NAMES}function attributeUnclassedSpell(spellClasses,casters,registry){var _a;const first=casters[0];if(!first)return null;const listed=firstListedCasterClass(spellClasses,casters.map(c=>c.classSlug));if(listed==null||listed===first.classSlug)return first.classSlug;if(first.spellList==null)return first.classSlug;const compendium=(_a=registry.getByTypeAndSlug("class",first.classSlug))==null?void 0:_a.compendium;if(compendium==null||!listedSpellClassNames(registry,compendium).has(baseClassName(first.classSlug)))return first.classSlug;return listed}var FULL_CASTER_SLOTS=[[2,0,0,0,0,0,0,0,0],[3,0,0,0,0,0,0,0,0],[4,2,0,0,0,0,0,0,0],[4,3,0,0,0,0,0,0,0],[4,3,2,0,0,0,0,0,0],[4,3,3,0,0,0,0,0,0],[4,3,3,1,0,0,0,0,0],[4,3,3,2,0,0,0,0,0],[4,3,3,3,1,0,0,0,0],[4,3,3,3,2,0,0,0,0],[4,3,3,3,2,1,0,0,0],[4,3,3,3,2,1,0,0,0],[4,3,3,3,2,1,1,0,0],[4,3,3,3,2,1,1,0,0],[4,3,3,3,2,1,1,1,0],[4,3,3,3,2,1,1,1,0],[4,3,3,3,2,1,1,1,1],[4,3,3,3,3,1,1,1,1],[4,3,3,3,3,2,1,1,1],[4,3,3,3,3,2,2,1,1]];var HALF_CASTER_SLOTS=[[0,0,0,0,0],[2,0,0,0,0],[3,0,0,0,0],[3,0,0,0,0],[4,2,0,0,0],[4,2,0,0,0],[4,3,0,0,0],[4,3,0,0,0],[4,3,2,0,0],[4,3,2,0,0],[4,3,3,0,0],[4,3,3,0,0],[4,3,3,1,0],[4,3,3,1,0],[4,3,3,2,0],[4,3,3,2,0],[4,3,3,3,1],[4,3,3,3,1],[4,3,3,3,2],[4,3,3,3,2]];var THIRD_CASTER_SLOTS=[[0,0,0,0],[0,0,0,0],[2,0,0,0],[3,0,0,0],[3,0,0,0],[3,0,0,0],[4,2,0,0],[4,2,0,0],[4,2,0,0],[4,3,0,0],[4,3,0,0],[4,3,0,0],[4,3,2,0],[4,3,2,0],[4,3,2,0],[4,3,3,0],[4,3,3,0],[4,3,3,0],[4,3,3,1],[4,3,3,1]];var PACT_MAGIC=[{level:1,total:1},{level:1,total:2},{level:2,total:2},{level:2,total:2},{level:3,total:2},{level:3,total:2},{level:4,total:2},{level:4,total:2},{level:5,total:2},{level:5,total:2},{level:5,total:3},{level:5,total:3},{level:5,total:3},{level:5,total:3},{level:5,total:3},{level:5,total:3},{level:5,total:4},{level:5,total:4},{level:5,total:4},{level:5,total:4}];var HALF_UP_CASTER_SLOTS=HALF_CASTER_SLOTS.map(row=>[...row]);HALF_UP_CASTER_SLOTS[0]=[2,0,0,0,0];function slotTableFor(caster){switch(caster){case"full":return FULL_CASTER_SLOTS;case"half":return HALF_CASTER_SLOTS;case"third":return THIRD_CASTER_SLOTS;case"half-up":return HALF_UP_CASTER_SLOTS;default:{const _n=caster;throw new Error(`unknown caster type ${String(_n)}`)}}}function rowToRecord(row){const out={};row.forEach((n,i)=>{if(n>0)out[i+1]=n});return out}function deriveSpellSlots(classes){let fullLevels=0,halfLevels=0,thirdLevels=0,halfUpLevels=0,warlockLevel=0;const regular=[];for(const c of classes){if(c.casterType==="pact"){warlockLevel+=c.level;continue}regular.push({caster:c.casterType,level:c.level});switch(c.casterType){case"full":fullLevels+=c.level;break;case"half":halfLevels+=c.level;break;case"third":thirdLevels+=c.level;break;case"half-up":halfUpLevels+=c.level;break;default:{const _n=c.casterType;throw new Error(`unknown caster type ${String(_n)}`)}}}let standard={};if(regular.length===1){const only=regular[0];const table=slotTableFor(only.caster);const idx=only.level-1;if(idx>=0&&idx<table.length)standard=rowToRecord(table[idx])}else if(regular.length>=2){const cl=fullLevels+Math.floor(halfLevels/2)+Math.floor(thirdLevels/3)+Math.ceil(halfUpLevels/2);if(cl>=1&&cl<=FULL_CASTER_SLOTS.length)standard=rowToRecord(FULL_CASTER_SLOTS[cl-1])}const pact=warlockLevel>=1&&warlockLevel<=PACT_MAGIC.length?PACT_MAGIC[warlockLevel-1]:null;return{standard,pact}}var PREPARED_COLUMNS=["Prepared Spells","Spells Prepared"];function preparedLevelTerm(caster,level){switch(caster){case"full":case"pact":return level;case"half":case"half-up":return Math.floor(level/2);case"third":return Math.floor(level/3);default:{const _n=caster;throw new Error(`unknown caster type ${String(_n)}`)}}}function computeSpellLimits(inputs){const out=[];for(const i of inputs){const p=i.profile;const cantripsKnown=readTableColumn(p.table,i.level,["Cantrips Known","Cantrips"]);const mod=abilityModifier(i.abilityScore);let preparedOrKnown;if(p.preparation==="prepared"){const fromTable=readTableColumn(p.table,i.level,PREPARED_COLUMNS);preparedOrKnown=fromTable!==null?fromTable:Math.max(1,mod+preparedLevelTerm(p.casterType,i.level))}else{preparedOrKnown=readTableColumn(p.table,i.level,["Spells Known","Prepared Spells"])}out.push({classSlug:i.classSlug,kind:p.preparation,cantripsKnown,preparedOrKnown})}return out}export{resolveSpellcasting,effectiveSpellcastingAbility,normalizeKnownSpell,listedSpellClassNames,attributeUnclassedSpell,slotTableFor,deriveSpellSlots,PREPARED_COLUMNS,preparedLevelTerm,computeSpellLimits};
@@ -1 +1 @@
1
- import{parseCastingTime}from"./chunk-CMIEZQL4.js";import{readTableColumn}from"./chunk-BGX36NPE.js";import{derivePoolLayout}from"./chunk-O776WL7O.js";import{findItemAction,isReadOnceItem,resolveItemAction}from"./chunk-DVUXUIPV.js";import{requiresAttunement}from"./chunk-YGH7S5ZF.js";import{defaultSlotForType,effectiveArmor,isItemEntity,isShieldArmor,resolveEntityForEntry,slotAcTerms}from"./chunk-4IAMSRHD.js";import{warnOnce}from"./chunk-DZITM5AG.js";import{keptSlugFor,resolveBaseItem}from"./chunk-PZ4L2EEG.js";import{bucketOf,memoByRevision}from"./chunk-QMEKQTUT.js";import{bareEntitySlug,slugify,twinKey,wikilinkTailSlug}from"./chunk-63YJPWTM.js";import{parseInlineTag}from"./chunk-BREHZNTL.js";import{isCanonicalDamageType}from"./chunk-7FPQJDFD.js";function equivalentResourceIds(id,index){var _a,_b,_c;const out=[];const add=other=>{if(other!==id&&index.has(other)&&!out.includes(other))out.push(other)};for(const other of(_b=(_a=index.get(id))==null?void 0:_a.equivalentIds)!=null?_b:[])add(other);for(const res of index.values())if((_c=res.equivalentIds)==null?void 0:_c.includes(id))add(res.id);return out}function ownedByClass(res,rc){var _a,_b;const s=(_a=res==null?void 0:res.owner)==null?void 0:_a.source;if(!s)return false;if(s.kind==="class")return s.slug===((_b=rc.entity)==null?void 0:_b.slug);if(s.kind==="subclass")return!!rc.subclass&&s.slug===rc.subclass.slug;return false}function payingResourceId(id,index,owner){const candidates=[id,...equivalentResourceIds(id,index)].filter(c=>index.has(c));if(candidates.length===0)return void 0;if(owner){const own=candidates.find(c=>ownedByClass(index.get(c),owner));if(own)return own}return candidates[0]}function classOfSource(source,classes){var _a,_b;if(source.kind==="class")return(_a=classes.find(c=>{var _a2;return((_a2=c.entity)==null?void 0:_a2.slug)===source.slug}))!=null?_a:null;if(source.kind==="subclass")return(_b=classes.find(c=>{var _a2;return((_a2=c.subclass)==null?void 0:_a2.slug)===source.slug}))!=null?_b:null;return null}function bindFeatureConsumers(features,index,classes){return features.map(rf=>{const consumes=rf.feature.consumes;const id=consumes==null?void 0:consumes.resource;if(!consumes||typeof id!=="string"||id.length===0)return rf;const payer=payingResourceId(id,index,classOfSource(rf.source,classes));if(payer===void 0||payer===id)return rf;return{...rf,feature:{...rf.feature,consumes:{...consumes,resource:payer}}}})}var SORTED_OPTIONAL_FEATURES=new WeakMap;function sortedOptionalFeatures(registry){return memoByRevision(SORTED_OPTIONAL_FEATURES,registry,()=>bucketOf(registry,"optional-feature").slice().sort((a,b)=>a.name.localeCompare(b.name)||a.slug.localeCompare(b.slug)))}var SRD_OWNER_PREFIXES=new Set(["srd-5e","srd-2024"]);function levelPrereqMax(d){var _a;return((_a=d.prerequisites)!=null?_a:[]).filter(p=>p.kind==="level").reduce((m,p)=>Math.max(m,p.min),0)}function namedRefKey(name){return name?slugify(name.replace(/\s*\([^)]*\)\s*$/,"")):""}function levelPrereqRefsMet(d,rc){var _a,_b;for(const p of(_a=d.prerequisites)!=null?_a:[]){if(p.kind!=="level")continue;if(p.class&&namedRefKey(p.class.name)!==namedRefKey((_b=rc.entity)==null?void 0:_b.name))return false;if(p.subclass){const sub=rc.subclass;const own=[sub==null?void 0:sub.short_name,sub==null?void 0:sub.name].map(namedRefKey).filter(k=>k!=="");if(!own.includes(namedRefKey(p.subclass.name)))return false}}return true}function optionalFeaturePrereqKeys(d){var _a;return((_a=d.prerequisites)!=null?_a:[]).filter(p=>p.kind==="optionalfeature").map(p=>twinKey(wikilinkTailSlug(p.optionalfeature)))}function withOptionalFeaturePrereqsMet(offered,selected,grants){let open=offered;for(;;){const openSlugs=new Set(open.map(e=>e.slug));const held=new Set([...grants,...selected.filter(e=>openSlugs.has(e.slug))].map(e=>twinKey(e.slug)));const next=open.filter(e=>optionalFeaturePrereqKeys(e.entity).every(k=>held.has(k)));if(next.length===open.length)return next;open=next}}function poolAnchorLevel(entity,pool){let anchorLevel=1;let columnSeen=false;for(let l=1;l<=20;l++){const c=readTableColumn(entity.table,l,[pool.count.column]);if(c!=null)columnSeen=true;if(c!=null&&c>=1){anchorLevel=l;break}}return{anchorLevel,columnSeen}}function resolvePool(rc,classIndex,pool,registry,index,edition){var _a,_b,_c,_d,_e,_f,_g,_h,_i;const entity=rc.entity;const level=rc.level;const ownerBare=bareEntitySlug(entity.slug);const ownerPrefix=entity.slug.split("_")[0];const ownEdition=SRD_OWNER_PREFIXES.has(ownerPrefix)?entity.edition:void 0;const col=pool.count.column;const count=(_a=readTableColumn(entity.table,level,[col]))!=null?_a:0;const{anchorLevel,columnSeen}=poolAnchorLevel(entity,pool);if(!columnSeen){warnOnce(`pool-column:${pool.id}`,`Archivist: pool "${pool.id}" declares count column "${col}", which "${entity.slug}"'s class table carries at no level; the pool resolves count 0 at anchor level 1`)}const ft=pool.source.where.feature_type;const all=sortedOptionalFeatures(registry);const entryOf=(slug,entity2,compendium)=>({slug,entity:entity2,...compendium?{compendium}:{},key:slug,param:null,itemBound:isItemBound(entity2)});const byBare=new Map;const candidates=new Map;for(const e of all){const d=e.data;const entry=entryOf(e.slug,d,e.compendium);const bare=bareEntitySlug(e.slug);byBare.set(bare,entry);if(d.feature_type!==ft)continue;if(!((_b=d.available_to)!=null?_b:[]).some(l=>wikilinkTailSlug(l)===ownerBare))continue;if(levelPrereqMax(d)>level)continue;if(!levelPrereqRefsMet(d,rc))continue;if(ownEdition&&d.edition&&d.edition!==ownEdition)continue;const key=twinKey(e.slug);const group=candidates.get(key);if(group)group.push(entry);else candidates.set(key,[entry])}const collapsed=[];for(const group of candidates.values()){if(group.length===1){collapsed.push(group[0]);continue}const bare=bareEntitySlug(group[0].slug);const owned=group.find(e=>e.slug.split("_")[0]===ownerPrefix);if(!owned){warnOnce(`pool-collapse:${bare}`,`Archivist: pool "${pool.id}" holds ${group.length} cross-edition entries for "${bare}" and none shares the owner's compendium prefix "${ownerPrefix}"; keeping "${group[0].slug}"`)}collapsed.push(owned!=null?owned:group[0])}const grantDecls=[...(_d=(_c=rc.entity)==null?void 0:_c.pool_grants)!=null?_d:[],...(_f=(_e=rc.subclass)==null?void 0:_e.pool_grants)!=null?_f:[]];const grantsRaw=grantDecls.filter(g=>g.pool===pool.id).flatMap(g=>g.grants).filter(g=>g.at_level<=level).map(g=>byBare.get(wikilinkTailSlug(g.feature))).filter(e=>e!=null);const grantedBare=new Set;const grants=grantsRaw.filter(e=>{const key=bareEntitySlug(e.slug);if(grantedBare.has(key))return false;grantedBare.add(key);return true});const offered=collapsed.filter(e=>!grantedBare.has(bareEntitySlug(e.slug)));const bySlugAvailable=new Map(offered.map(e=>[e.slug,e]));const byTwinAvailable=new Map(offered.map(e=>[twinKey(e.slug),e]));const resolveStored=s=>{const exact=bySlugAvailable.get(s);if(exact)return exact;const survivor=byTwinAvailable.get(twinKey(s));if(survivor)return survivor;const full=registry.getByTypeAndSlug("optional-feature",s);if(full)return entryOf(full.slug,full.data,full.compendium);return byBare.get(bareEntitySlug(s))};const raw=(_g=rc.choices[anchorLevel])==null?void 0:_g[pool.id];const selectedSlugs=Array.isArray(raw)?raw:typeof raw==="string"?[raw]:[];const selected=[];const seenKeys=new Set;for(const s of selectedSlugs){const{slugPart,param}=parsePickKey(s);const entry=resolveStored(slugPart);if(!entry)continue;const repeatable=entry.entity.repeatable===true;if(!repeatable&&param!==null){warnOnce(`pick-param:${pool.id}:${s}`,`Archivist: pool "${pool.id}" pick "${s}" names a parameter, but "${entry.slug}" is not repeatable; the parameter is ignored`)}const nkey=repeatable?normalizedPickKey(s,true):twinKey(entry.slug);if(grantedBare.has(bareEntitySlug(entry.slug))||seenKeys.has(nkey))continue;seenKeys.add(nkey);selected.push({...entry,key:repeatable||param!==null?s:entry.slug,param:repeatable?param:null,...repeatable?{option:resolveCopyOption(entry.entity,param,{classLevel:level,registry,edition})}:{}})}const available=withOptionalFeaturePrereqsMet(offered,selected,grants);const members=[...available,...grants];const layout=derivePoolLayout(members);const votes=new Map;for(const e of members){const id=(_h=e.entity.consumes)==null?void 0:_h.resource;const payer=id?payingResourceId(id,index,rc):void 0;if(!payer)continue;votes.set(payer,((_i=votes.get(payer))!=null?_i:0)+1)}let resource;let bestN=0;for(const[id,n]of votes)if(n>bestN){resource=id;bestN=n}const bind=poolRebinder(rc,pool.id,resource,index);return{id:pool.id,label:pool.label,classIndex,count,anchorLevel,selected:selected.map(bind),available:available.map(bind),grants:grants.map(bind),...layout?{layout}:{},...resource?{resource}:{},...pool.count.label?{countLabel:pool.count.label}:{},...pool.active?{active:pool.active}:{},...pool.head_resource?{headResource:pool.head_resource}:{}}}function poolRebinder(rc,poolId,vote,index){const declared=declaredResourceIds(rc);const copies=new Map;return e=>{const consumes=e.entity.consumes;const id=consumes==null?void 0:consumes.resource;if(!consumes||typeof id!=="string"||id.length===0)return e;const payer=payingResourceId(id,index,rc);if(payer===id)return e;const target=payer!=null?payer:vote!==void 0&&!declared.has(id)?vote:void 0;if(target===void 0)return e;const done=copies.get(e.key);if(done)return done;if(payer===void 0){warnOnce(`pool-rebind:${poolId}:${id}`,`Archivist: pool "${poolId}" members consume "${id}", which this character does not own; bound to the pool's resource "${target}"`)}const copy={...e,entity:{...e.entity,consumes:{...consumes,resource:target}}};copies.set(e.key,copy);return copy}}function declaredResourceIds(rc){var _a;const out=new Set;const add=list=>{for(const r of list!=null?list:[])if(typeof(r==null?void 0:r.id)==="string")out.add(r.id)};for(const owner of[rc.entity,rc.subclass]){if(!owner)continue;add(owner.resources);for(const features of Object.values((_a=owner.features_by_level)!=null?_a:{}))for(const f of features!=null?features:[])add(f.resources)}return out}function resolveAllPools(resolved,registry,index){const out=[];resolved.classes.forEach((rc,classIndex)=>{var _a,_b,_c,_d;if(!rc.entity)return;const decls=[...(_a=rc.entity.selection_pools)!=null?_a:[],...(_c=(_b=rc.subclass)==null?void 0:_b.selection_pools)!=null?_c:[]];const seen=new Set;for(const pool of decls){if(seen.has(pool.id))continue;seen.add(pool.id);out.push(resolvePool(rc,classIndex,pool,registry,index,(_d=resolved.definition)==null?void 0:_d.edition))}});return out}function strandedPicks(pool){const inAvailable=new Set(pool.available.map(e=>e.slug));return pool.selected.filter(e=>!inAvailable.has(e.slug))}function heldPicks(pool){var _a;const selected=(_a=pool.selected)!=null?_a:[];if(!pool.available)return[...selected];const inAvailable=new Set(pool.available.map(e=>e.slug));return selected.filter(e=>inAvailable.has(e.slug))}function withoutStrandedSites(sites,classes,registry,edition){if(sites.length===0)return sites;const strandedKeys=new Map;const keysOf=(classIndex,poolId)=>{var _a,_b,_c;const at=`${classIndex}:${poolId}`;let keys=strandedKeys.get(at);if(keys)return keys;const rc=classes[classIndex];const decl=(rc==null?void 0:rc.entity)?[...(_a=rc.entity.selection_pools)!=null?_a:[],...(_c=(_b=rc.subclass)==null?void 0:_b.selection_pools)!=null?_c:[]].find(p=>p.id===poolId):void 0;keys=new Set(rc&&decl?strandedPicks(resolvePool(rc,classIndex,decl,registry,new Map,edition)).map(e=>twinKey(e.slug)):[]);strandedKeys.set(at,keys);return keys};return sites.filter(site=>!keysOf(site.classIndex,site.poolId).has(twinKey(site.memberSlug)))}function poolCountLabel(pool){var _a;return(_a=pool.countLabel)!=null?_a:"Known"}function poolActiveWords(pool){var _a,_b,_c;const a=pool.active;if(!a)return null;return{column:a.column,label:a.label,verb:a.verb,counterLabel:(_a=a.counter_label)!=null?_a:a.label,createLabel:(_b=a.create_label)!=null?_b:"Created",createVerb:(_c=a.create_verb)!=null?_c:"Create"}}function parsePickKey(stored){const i=stored.indexOf("#");return i===-1?{slugPart:stored,param:null}:{slugPart:stored.slice(0,i),param:stored.slice(i+1)}}function normalizedPickKey(stored,repeatable){const{slugPart,param}=parsePickKey(stored);return repeatable?`${bareEntitySlug(slugPart)}#${param!=null?param:""}`:bareEntitySlug(slugPart)}function markerKey(by){const{slugPart,param}=parsePickKey(by);return param===null?bareEntitySlug(slugPart):`${bareEntitySlug(slugPart)}#${param}`}function isItemBound(note){var _a;return!!note.infuse||note.repeatable===true&&!!((_a=note.options)==null?void 0:_a.some(r=>!!r.creates))}var SRD_BOOKS=new Set(["SRD 2024","SRD 5e"]);var lc=v=>String(v!=null?v:"").trim().toLowerCase();var linkSlug=link=>link.replace(/^\[\[/,"").replace(/\]\]$/,"").split("|")[0];var itemsOf=registry=>registry.search("","item",Number.POSITIVE_INFINITY);function matchesFilter(data,f){var _a;const type=lc(data.type);if(!f.rarity.map(lc).includes(lc(data.rarity)))return false;if(f.types&&!f.types.map(lc).includes(type))return false;if((_a=f.exclude_types)==null?void 0:_a.map(lc).includes(type))return false;return!(f.cursed===false&&data.cursed===true)}function rowMatches(row,it){const c=row.creates;if(c.item)return lc(it.name)===lc(row.name)||it.slug===linkSlug(c.item);if(c.variant)return c.variant.candidates.some(l=>bareEntitySlug(linkSlug(l))===bareEntitySlug(it.slug));return!!c.filter&&matchesFilter(it.data,c.filter)}function buildItemIndex(items){const lcType=[],lcRarity=[];const byLcName=new Map,bySlug=new Map,byBare=new Map;const push=(m,k,i)=>{const l=m.get(k);if(l)l.push(i);else m.set(k,[i])};items.forEach((it,i)=>{const data=it.data;lcType.push(lc(data.type));lcRarity.push(lc(data.rarity));push(byLcName,lc(it.name),i);if(!bySlug.has(it.slug))bySlug.set(it.slug,i);push(byBare,bareEntitySlug(it.slug),i)});return{items,lcType,lcRarity,byLcName,bySlug,byBare}}var ITEM_INDEX=new WeakMap;var itemIndexOf=registry=>memoByRevision(ITEM_INDEX,registry,()=>buildItemIndex(itemsOf(registry)));var inBucketOrder=(ix,hits)=>[...hits].sort((a,b)=>a-b).map(i=>ix.items[i]);function rowInstalledIn(row,ix){var _a,_b,_c;const c=row.creates;if(c.item){const hits=new Set((_a=ix.byLcName.get(lc(row.name)))!=null?_a:[]);const own=ix.bySlug.get(linkSlug(c.item));if(own!==void 0)hits.add(own);return inBucketOrder(ix,hits)}if(c.variant){const hits=new Set;for(const l of c.variant.candidates)for(const i of(_b=ix.byBare.get(bareEntitySlug(linkSlug(l))))!=null?_b:[])hits.add(i);return inBucketOrder(ix,hits)}const f=c.filter;if(!f)return[];const rarities=new Set(f.rarity.map(lc));const types=f.types?new Set(f.types.map(lc)):null;const excluded=new Set(((_c=f.exclude_types)!=null?_c:[]).map(lc));return ix.items.filter((it,i)=>rarities.has(ix.lcRarity[i])&&(!types||types.has(ix.lcType[i]))&&!excluded.has(ix.lcType[i])&&!(f.cursed===false&&it.data.cursed===true))}var rowInstalled=(row,registry)=>rowInstalledIn(row,itemIndexOf(registry));function candidateOrder(edition){return(a,b)=>{const ea=edition&&lc(a.data.edition)===edition?0:1;const eb=edition&&lc(b.data.edition)===edition?0:1;if(ea!==eb)return ea-eb;const sa=SRD_BOOKS.has(a.compendium)?0:1,sb=SRD_BOOKS.has(b.compendium)?0:1;if(sa!==sb)return sa-sb;return a.slug<b.slug?-1:a.slug>b.slug?1:0}}function optionCandidates(row,registry,opts={}){return candidatesFrom(rowInstalled(row,registry),registry,opts)}function candidatesFrom(installed,registry,opts){var _a,_b;const visible=(_a=opts.isEntityVisible)!=null?_a:(()=>true);const excluded=((_b=opts.exclude)!=null?_b:[]).map(s=>{var _a2;return registry.getByTypeAndSlug("item",(_a2=keptSlugFor(s))!=null?_a2:s)}).filter(e=>!!e);const exNames=new Set(excluded.map(e=>lc(e.name))),exBares=new Set(excluded.map(e=>bareEntitySlug(e.slug)));const seen=new Set,out=[];for(const e of installed.filter(visible).sort(candidateOrder(opts.edition))){const bare=bareEntitySlug(e.slug);if(seen.has(bare))continue;seen.add(bare);if(exNames.has(lc(e.name))||exBares.has(bare))continue;out.push(e.slug)}return out}function resolveOptionRows(note,registry,opts={}){var _a;const ix=itemIndexOf(registry);return((_a=note.options)!=null?_a:[]).map(row=>{var _a2;const rowItems=rowInstalledIn(row,ix);const candidates=candidatesFrom(rowItems,registry,opts);const anyVisible=candidates.length>0||candidatesFrom(rowItems,registry,{...opts,exclude:[]}).length>0;const installed=rowItems.length>0;return{key:row.key,name:row.name,minLevel:row.min_level,...row.attunement!==void 0?{attunement:row.attunement}:{},arm:row.creates.item?"item":row.creates.variant?"variant":"filter",candidates,availability:anyVisible?"installed":installed?"hidden-only":"not-installed",...rowItemWords(row,candidates[0]?ix.items[(_a2=ix.bySlug.get(candidates[0]))!=null?_a2:-1]:rowItems[0])}})}function rowItemWords(row,item){var _a,_b,_c,_d;const f=row.creates.filter;if(f)return{type:((_a=f.types)==null?void 0:_a[0])?lc(f.types[0]):null,rarity:f.rarity[0]?lc(f.rarity[0]):null,charges:null};const data=(_b=item==null?void 0:item.data)!=null?_b:{};const max=(_c=data.charges)==null?void 0:_c.max;return{type:lc(data.type)||null,rarity:lc(data.rarity)||null,charges:typeof max==="number"&&max>0?{max,...typeof((_d=data.charges)==null?void 0:_d.recharge)==="string"?{recharge:data.charges.recharge}:{}}:null}}function resolveCopyOption(note,param,ctx){var _a,_b,_c;const rows=(_a=note.options)!=null?_a:[];if(param===null||param==="")return{row:null,status:"needs-choice"};if(note.item_choice==="create"){const row=rows.find(r=>r.key===param);if(!row)return{row:null,status:"invalid"};const installed=rowInstalled(row,ctx.registry).sort(candidateOrder(ctx.edition));if(installed.length===0)return{row,status:"not-installed"};const own=row.creates.item?linkSlug(row.creates.item):void 0;const item=row.creates.item?((_b=installed.find(e=>e.slug===own))!=null?_b:installed[0]).slug:void 0;return{row,...item?{item}:{},status:row.min_level<=ctx.classLevel?"ok":"level"}}const slug=(_c=keptSlugFor(param))!=null?_c:param;const it=ctx.registry.getByTypeAndSlug("item",slug);if(!it)return{row:null,item:slug,status:"not-installed"};const matching=rows.filter(r=>rowMatches(r,it)).sort((a,b)=>a.min_level-b.min_level);if(matching.length===0)return{row:null,item:slug,status:"invalid"};return{row:matching[0],item:slug,status:matching[0].min_level<=ctx.classLevel?"ok":"level"}}var MUNDANE=new Set(["","none","mundane"]);var isMagic=data=>{const r=data==null?void 0:data.rarity;return typeof r==="string"&&!MUNDANE.has(r.trim().toLowerCase())};var plainText=item=>item.replace(/^\[\[/,"").replace(/\]\]$/,"").split("|").pop().split("/").pop();function scaledInfuseItem(infuse,classLevel){var _a,_b;let item={...(_a=infuse.item)!=null?_a:{}};const rows=[...(_b=infuse.scales_at)!=null?_b:[]].sort((a,b)=>a.level-b.level);for(const row of rows)if(row.level<=classLevel)item={...item,...row.item};return item}function wrapInfused(entry,note,classLevel,registry){var _a,_b,_c,_d,_e,_f,_g,_h,_i,_j,_k;const infuse=note.infuse;const item=scaledInfuseItem(infuse,classLevel);const resist=[...(_a=item.resist)!=null?_a:[],...((_b=infuse.choice)==null?void 0:_b.kind)==="damage-type"&&((_c=entry.infusion)==null?void 0:_c.choice)?[entry.infusion.choice]:[]];const overlay={...item.bonuses?{bonuses:item.bonuses}:{},resist,...item.charges?{charges:item.charges}:{},...item.action?{action:item.action}:{},...item.range?{range:item.range}:{},...infuse.attunement?{attunement:{required:true}}:{}};const base=resolveBaseItem(entry.item,registry);const data=(_d=base==null?void 0:base.data)!=null?_d:null;if(base&&isMagic(data)){const b=data;const bonuses={...(_e=b.bonuses)!=null?_e:{}};for(const[k,v]of Object.entries((_f=item.bonuses)!=null?_f:{}))if(typeof v==="number")bonuses[k]=(typeof bonuses[k]==="number"?bonuses[k]:0)+v;return{entity:{...b,bonuses,resist:[...new Set([...(_g=b.resist)!=null?_g:[],...resist])],attunement:{required:requiresAttunement(b)||!!infuse.attunement}},magicBase:true}}const rarity=(_h=infuse.rarity)!=null?_h:"unknown";if(!base){const text=plainText(entry.item);return{entity:{slug:`infused:${slugify(text)}`,name:text,type:"wondrous item",rarity,...overlay,description:""},magicBase:false}}const name=String((_i=data==null?void 0:data.name)!=null?_i:base.name),description=String((_j=data==null?void 0:data.description)!=null?_j:"");const slotted=base.entityType==="armor"||base.entityType==="weapon"?base:typeof(data==null?void 0:data.base_item)==="string"?resolveBaseItem(data.base_item,registry):null;if(slotted&&(slotted.entityType==="armor"||slotted.entityType==="weapon")){const type=slotted.entityType==="weapon"?"weapon":isShieldArmor(slotted.data)?"shield":"armor";return{entity:{slug:base.slug,name,type,rarity,base_item:`[[${slotted.slug}]]`,...overlay,description},magicBase:false}}return{entity:{slug:base.slug,name,type:String((_k=data==null?void 0:data.type)!=null?_k:"adventuring gear"),rarity,...overlay,description},magicBase:false}}function resolveEntryEntity(entry,index,registry,infusions){const view=!infusions?void 0:"views"in infusions?infusions.views.get(index):infusions.index===index?infusions:void 0;if(view)return{entity:view.entity,entityType:view.entityType};return resolveEntityForEntry(entry.item,registry)}function buildInfusionContext(character,resolved,registry){var _a,_b,_c,_d,_e;const equipment=(_a=character.equipment)!=null?_a:[];const pools=((_b=resolved.pools)!=null?_b:[]).filter(p=>!!p.active||p.selected.some(e=>e.itemBound));if(pools.length===0&&!equipment.some(e=>!!e.infusion))return void 0;const owners=new Map;for(const pool of pools)for(const entry of pool.selected)if(entry.itemBound)owners.set(normalizedPickKey(entry.key,entry.entity.repeatable===true),{pool,entry});const views=new Map,flags=[];const newest=new Map;equipment.forEach((e,i)=>{if(!e.infusion)return;const k=markerKey(e.infusion.by);const j=newest.get(k);if(j===void 0||equipment[j].infusion.seq<e.infusion.seq)newest.set(k,i)});equipment.forEach((e,i)=>{var _a2,_b2,_c2;const m=e.infusion;if(!m)return;const owner=owners.get(markerKey(m.by));const nullView=()=>{var _a3,_b3,_c3,_d2,_e2;return{index:i,kind:m.kind,entity:null,entityType:null,key:m.by,seq:m.seq,poolId:(_a3=owner==null?void 0:owner.pool.id)!=null?_a3:"",classIndex:(_b3=owner==null?void 0:owner.pool.classIndex)!=null?_b3:-1,noteSlug:(_c3=owner==null?void 0:owner.entry.slug)!=null?_c3:"",noteName:(_d2=owner==null?void 0:owner.entry.entity.name)!=null?_d2:"",sourceLabel:(_e2=owner==null?void 0:owner.entry.entity.name)!=null?_e2:""}};if(!owner){flags.push({index:i,reason:"orphan"});if(m.kind==="created")views.set(i,nullView());return}if(newest.get(markerKey(m.by))!==i){flags.push({index:i,reason:"duplicate"});if(m.kind==="created")views.set(i,nullView());return}if(((_a2=e.qty)!=null?_a2:1)>1)flags.push({index:i,reason:"stack"});const classLevel=(_c2=(_b2=resolved.classes[owner.pool.classIndex])==null?void 0:_b2.level)!=null?_c2:0;const base={index:i,kind:m.kind,key:m.by,seq:m.seq,poolId:owner.pool.id,classIndex:owner.pool.classIndex,noteSlug:owner.entry.slug,noteName:owner.entry.entity.name,sourceLabel:owner.entry.entity.name};if(m.kind==="created"){const own=resolveEntityForEntry(e.item,registry);const it=resolveBaseItem(e.item,registry);const opt=owner.entry.option;const fits=!!it&&!!(opt==null?void 0:opt.row)&&(opt.item===it.slug||rowMatches(opt.row,it));if(!fits)flags.push({index:i,reason:"mismatch"});views.set(i,{...base,entity:own.entity,entityType:own.entityType});return}if(!owner.entry.entity.infuse){flags.push({index:i,reason:"orphan"});return}const w=wrapInfused(e,owner.entry.entity,classLevel,registry);if(w.magicBase)flags.push({index:i,reason:"magic-base"});views.set(i,{...base,entity:w.entity,entityType:"item"})});const counters=new Map;for(const pool of pools){const words=poolActiveWords(pool);if(!words)continue;const rc=resolved.classes[pool.classIndex];const max=(_e=readTableColumn((_c=rc==null?void 0:rc.entity)==null?void 0:_c.table,(_d=rc==null?void 0:rc.level)!=null?_d:0,[words.column]))!=null?_e:0;const used=[...views.values()].filter(v=>v.poolId===pool.id&&v.entity!==null).length;counters.set(pool.id,{label:words.counterLabel,used,max,over:used>max})}return{views,counters,flags}}function entryCharges(entry,view,registry){return effectiveItemCharges(entry,registry,view)}function withEntryCharges(entry,view,current,registry){var _a,_b,_c,_d,_e,_f;const overlayMax=(view==null?void 0:view.kind)==="infused"?itemChargesMax(view.entity):void 0;if(overlayMax!==void 0&&entry.infusion)return{...entry,infusion:{...entry.infusion,charges:{current:Math.max(0,Math.min(current,overlayMax))}}};const max=(_e=(_d=(_b=(_a=entry.state)==null?void 0:_a.charges)==null?void 0:_b.max)!=null?_d:(_c=effectiveItemCharges(entry,registry,view))==null?void 0:_c.max)!=null?_e:Math.max(0,current);return{...entry,state:{...(_f=entry.state)!=null?_f:{},charges:{current:Math.max(0,Math.min(current,max)),max}}}}function isMarkedEntry(entry){return!!entry.infusion}function splitOne(equipment,index){var _a,_b;const src=equipment[index];if(!src||((_a=src.qty)!=null?_a:1)<=1)return[...equipment];const one={item:src.item,qty:1,...src.in!==void 0?{in:src.in}:{},...src.overrides?{overrides:src.overrides}:{}};return[...equipment.slice(0,index),{...src,qty:((_b=src.qty)!=null?_b:1)-1},one,...equipment.slice(index+1)]}var refuse=reason=>({ok:false,reason});function endInfusion(equipment,index,registry){const entry=equipment[index];if(!(entry==null?void 0:entry.infusion))return{equipment:[...equipment],ended:[]};const{kind,by}=entry.infusion;if(kind==="infused"){const{infusion:_m,...rest}=entry;const keep=requiresAttunement(resolveEntryEntity(rest,index,registry).entity);const next=keep?rest:(({attuned:_a,...r})=>r)(rest);return{equipment:equipment.map((e,i)=>i===index?next:e),ended:[{index,key:by,kind,item:entry.item}]}}const moved=equipment.map((e,i)=>{if(i===index||entry.id===void 0||e.in!==entry.id)return e;if(entry.in===void 0){const{in:_in,...r}=e;return r}return{...e,in:entry.in}});return{equipment:moved.filter((_,i)=>i!==index),ended:[{index:-1,key:by,kind,item:entry.item}]}}var pickKeyOf=e=>normalizedPickKey(e.key,e.entity.repeatable===true);var nextSeq=equipment=>equipment.reduce((m,e)=>{var _a,_b;return Math.max(m,(_b=(_a=e.infusion)==null?void 0:_a.seq)!=null?_b:0)},0)+1;function ownedPick(resolved,key){var _a,_b;const k=markerKey(key);for(const pool of(_a=resolved.pools)!=null?_a:[]){const entry=pool.selected.find(e=>e.itemBound&&pickKeyOf(e)===k);if(entry)return{pool,entry,stranded:strandedPicks(pool).includes(entry)||((_b=entry.option)==null?void 0:_b.status)==="level"}}return null}var wordsOf=(...texts)=>texts.map(lc).join(" ").split(/[^a-z]+/).filter(w=>w!=="");function shapeOf(found,text,registry){var _a,_b,_c;if(!found)return{kind:"gear",words:wordsOf(text)};const data=(_a=found.data)!=null?_a:{};const words=wordsOf((_b=data.name)!=null?_b:text,data.type);const slotted=found.entityType==="armor"||found.entityType==="weapon"?found:typeof data.base_item==="string"?resolveBaseItem(data.base_item,registry):null;if((slotted==null?void 0:slotted.entityType)==="armor"){const armor=slotted.data;return{kind:isShieldArmor(armor)?"shield":"armor",words,category:lc(armor.category)}}if((slotted==null?void 0:slotted.entityType)==="weapon"){const w=slotted.data;return{kind:"weapon",words,category:lc(w.category),properties:((_c=w.properties)!=null?_c:[]).filter(p=>typeof p==="string").map(lc)}}return{kind:"gear",words}}function admits(t,s){var _a,_b,_c,_d;if(t.kind!==s.kind)return false;if(((_a=t.category)==null?void 0:_a.length)&&!t.category.map(lc).includes(((_b=s.category)!=null?_b:"").split("-")[0]))return false;if(t.property&&!((_c=s.properties)!=null?_c:[]).includes(lc(t.property)))return false;if(((_d=t.name_any)==null?void 0:_d.length)&&!t.name_any.some(n=>{const w=wordsOf(n);return w.length>0&&w.every(x=>s.words.includes(x))}))return false;return true}function targetVerdict(entry,infuse,registry){const found=resolveBaseItem(entry.item,registry);if(!infuse.targets.some(t=>admits(t,shapeOf(found,plainText(entry.item),registry))))return"target-kind";return found&&isMagic(found.data)?"magic-base":"ok"}function newObjectEntry(name,infuse,registry,visible){const want=lc(name);const found=[];for(const type of["armor","weapon","item"]){for(const e of registry.search(name,type,Number.POSITIVE_INFINITY)){if(lc(e.name)===want&&!isMagic(e.data)&&visible(e)&&infuse.targets.some(t=>admits(t,shapeOf(e,e.name,registry))))found.push(e)}}const first=found.sort(candidateOrder(void 0))[0];return first?{item:`[[${first.slug}]]`,qty:1}:{item:name,qty:1}}function endBySeqs(equipment,seqs,registry){let eq=[...equipment];let slots=eq.map((_,i)=>i);const rows=[];for(const{seq,by}of seqs){const i=eq.findIndex(e=>{var _a;return((_a=e.infusion)==null?void 0:_a.seq)===seq&&e.infusion.by===by});if(i===-1)continue;const w=endInfusion(eq,i,registry);for(const row of w.ended)rows.push({row,slot:slots[i]});if(eq[i].infusion.kind==="created")slots=slots.filter((_,j)=>j!==i);eq=w.equipment}return{equipment:eq,ended:rows.map(({row,slot})=>row.kind==="infused"?{...row,index:slots.indexOf(slot)}:row)}}function displaced(equipment,resolved,pool,key){var _a;const k=markerKey(key);const out=equipment.filter(e=>!!e.infusion&&markerKey(e.infusion.by)===k).map(e=>({seq:e.infusion.seq,by:e.infusion.by}));const counter=(_a=resolved.infusions)==null?void 0:_a.counters.get(pool.id);if(!counter)return out;const live=[...resolved.infusions.views.values()].filter(v=>v.poolId===pool.id&&v.classIndex===pool.classIndex&&v.entity!==null&&markerKey(v.key)!==k).sort((a,b)=>a.seq-b.seq);let used=live.length;for(const v of live){if(used+1<=counter.max)break;out.push({seq:v.seq,by:v.key});used--}return out}function infuseEntry(character,resolved,registry,req){var _a,_b,_c,_d,_e,_f,_g;const owned=ownedPick(resolved,req.key);if(!owned)return refuse("not-owned");const infuse=owned.entry.entity.infuse;if(!infuse)return refuse("not-infusing");if(owned.stranded)return refuse("stranded");const wantsChoice=((_a=infuse.choice)==null?void 0:_a.kind)==="damage-type";const choice=lc(req.choice);if(wantsChoice&&choice==="")return refuse("choice-required");if(wantsChoice&&!isCanonicalDamageType(choice))return refuse("bad-choice");if(wantsChoice&&((_b=infuse.choice)==null?void 0:_b.options)&&!infuse.choice.options.some(o=>lc(o)===choice))return refuse("bad-choice");const equipment=(_c=character.equipment)!=null?_c:[];const charges=scaledInfuseItem(infuse,(_e=(_d=resolved.classes[owned.pool.classIndex])==null?void 0:_d.level)!=null?_e:0).charges;const marker={kind:"infused",by:owned.entry.key,seq:nextSeq(equipment),...wantsChoice?{choice}:{},...charges?{charges:{current:charges.max}}:{}};let placed;if(typeof req.target==="number"){const target=equipment[req.target];if(!target)return refuse("no-target");if(target.infusion)return refuse("marked");const verdict=targetVerdict(target,infuse,registry);if(verdict!=="ok")return refuse(verdict);const split=((_f=target.qty)!=null?_f:1)>1;placed=split?splitOne(equipment,req.target):[...equipment];const i=split?req.target+1:req.target;placed[i]={...placed[i],infusion:marker}}else{const name=req.target.newObject.trim();if(name==="")return refuse("no-target");placed=[...equipment,{...newObjectEntry(name,infuse,registry,(_g=req.isEntityVisible)!=null?_g:(()=>true)),infusion:marker}]}return{ok:true,...endBySeqs(placed,displaced(equipment,resolved,owned.pool,owned.entry.key),registry)}}function createEntry(character,resolved,registry,req){var _a,_b;const owned=ownedPick(resolved,req.key);if(!owned)return refuse("not-owned");const note=owned.entry.entity;if(!(note.repeatable===true&&!!((_a=note.options)==null?void 0:_a.some(r=>!!r.creates))))return refuse("not-creating");if(owned.stranded)return refuse("stranded");const opt=owned.entry.option;if(!(opt==null?void 0:opt.row)||opt.status!=="ok")return refuse("invalid-item");const it=registry.getByTypeAndSlug("item",linkSlug(req.item.trim()));if(!it||!(opt.item===it.slug||rowMatches(opt.row,it)))return refuse("invalid-item");const equipment=(_b=character.equipment)!=null?_b:[];const placed=[...equipment,{item:`[[${it.slug}]]`,qty:1,infusion:{kind:"created",by:owned.entry.key,seq:nextSeq(equipment)}}];return{ok:true,...endBySeqs(placed,displaced(equipment,resolved,owned.pool,owned.entry.key),registry)}}function markersWhere(equipment,pick){const out=[];equipment.forEach((e,index)=>{const m=e.infusion;if(m&&pick(m))out.push({index,key:m.by,kind:m.kind,item:e.item,seq:m.seq,by:m.by})});return out}var asRows=list=>list.map(({index,key,kind,item})=>({index,key,kind,item}));var storedKeys=v=>typeof v==="string"?[v]:Array.isArray(v)?v:[];function choiceEnds(character,resolved,req){var _a,_b,_c,_d,_e,_f;const pool=((_a=resolved.pools)!=null?_a:[]).find(p=>p.classIndex===req.classIndex&&p.id===req.choiceKey);if(!pool||!(pool.active||pool.selected.some(e=>e.itemBound)))return[];const choices=(_c=(_b=character.class[req.classIndex])==null?void 0:_b.choices)!=null?_c:{};const kept=new Set(req.next.map(markerKey));for(const lvl of Object.keys(choices))if(Number(lvl)!==req.level)for(const s of storedKeys((_d=choices[Number(lvl)])==null?void 0:_d[req.choiceKey]))kept.add(markerKey(s));const removed=new Set(storedKeys((_e=choices[req.level])==null?void 0:_e[req.choiceKey]).map(markerKey).filter(k=>!kept.has(k)));return markersWhere((_f=character.equipment)!=null?_f:[],m=>removed.has(markerKey(m.by)))}function infusionsEndedByChoice(character,resolved,_registry,req){return asRows(choiceEnds(character,resolved,req))}function reconcileChoiceEdit(character,resolved,registry,req){var _a;const list=choiceEnds(character,resolved,req);return list.length===0?null:endBySeqs((_a=character.equipment)!=null?_a:[],list,registry)}function classEnds(character,resolved,req){var _a,_b,_c,_d,_e;let pools=((_a=resolved.pools)!=null?_a:[]).filter(p=>p.classIndex===req.classIndex);if(!("remove"in req)){const old=(_c=(_b=resolved.classes[req.classIndex])==null?void 0:_b.subclass)!=null?_c:null;if(!old||req.subclass!==null&&bareEntitySlug(linkSlug(req.subclass.trim()))===bareEntitySlug(old.slug))return[];const ids=new Set(((_d=old.selection_pools)!=null?_d:[]).map(p=>p.id));pools=pools.filter(p=>ids.has(p.id))}const owned=new Set;for(const pool of pools)for(const e of pool.selected)if(e.itemBound)owned.add(pickKeyOf(e));return markersWhere((_e=character.equipment)!=null?_e:[],m=>owned.has(markerKey(m.by)))}function infusionsEndedByClassEdit(character,resolved,_registry,req){return asRows(classEnds(character,resolved,req))}function reconcileClassEdit(character,resolved,registry,req){var _a;const list=classEnds(character,resolved,req);return list.length===0?null:endBySeqs((_a=character.equipment)!=null?_a:[],list,registry)}function eligibleTargets(character,resolved,registry,key){var _a,_b;const infuse=(_a=ownedPick(resolved,key))==null?void 0:_a.entry.entity.infuse;if(!infuse)return[];const out=[];((_b=character.equipment)!=null?_b:[]).forEach((e,index)=>{var _a2;if(!e.infusion&&targetVerdict(e,infuse,registry)==="ok")out.push({index,stack:((_a2=e.qty)!=null?_a2:1)>1})});return out}var WEAPON_DEFAULT_ACTION_COST="action";var linkOf=item=>{var _a,_b;return(_b=(_a=item.match(/^\[\[(.+)\]\]$/))==null?void 0:_a[1])!=null?_b:null};var ruleOf=(entry,registry,view)=>resolveEntryEntity(entry,view?view.index:-1,registry,view!=null?view:null);function isWeaponLikeEntry(entry,registry,view){if(!registry)return false;const r=ruleOf(entry,registry,view);return defaultSlotForType(r.entityType,r.entity,registry)==="mainhand"}function itemsRowBranch(entry,registry,view){var _a,_b;const link=linkOf(entry.item);if(!link||!registry)return false;const t=view?view.entityType:(_b=(_a=registry.getBySlug(link))==null?void 0:_a.entityType)!=null?_b:null;return t!=="weapon"&&t!=="armor"&&!isWeaponLikeEntry(entry,registry,view)}function customizableOverrideKeys(entry,registry){const consumed=isConsumedOnUse(entry,registry);const keys=new Set(consumed?["name"]:["name","charges","recovery"]);if(!registry)return keys;const r=ruleOf(entry,registry);const slot=defaultSlotForType(r.entityType,r.entity,registry);const weaponLike=slot==="mainhand";const itemsRow=itemsRowBranch(entry,registry);if(weaponLike){keys.add("bonus");keys.add("damage_bonus");keys.add("extra_damage")}if(slot==="armor"||slot==="shield")keys.add("ac_bonus");if(weaponLike||itemsRow)keys.add("action");if(itemsRow)keys.add("range");const link=linkOf(entry.item);if(r.entityType==="item"&&!consumed&&!(link&&isReadOnceItem(link)))keys.add("resist");return keys}function defaultActionCost(entry,registry,view){var _a,_b,_c,_d,_e;if(isWeaponLikeEntry(entry,registry,view))return WEAPON_DEFAULT_ACTION_COST;const link=linkOf(entry.item);if(!link||!registry||!itemsRowBranch(entry,registry,view))return null;const withoutOverrides={...entry,overrides:void 0};const type=view?(_a=view.entity)==null?void 0:_a.type:(_c=(_b=registry.getBySlug(link))==null?void 0:_b.data)==null?void 0:_c.type;return(_e=(_d=resolveItemAction(link,withoutOverrides,type,{view,spellCost:scrollSpellCost(entry,registry)}))==null?void 0:_d.cost)!=null?_e:null}var SPELL_COST={action:"action",bonus:"bonus-action",reaction:"reaction"};function scrollSpellCost(entry,registry){var _a,_b,_c,_d,_e;const ref=(_a=entry.overrides)==null?void 0:_a.spell;if(!ref||!registry)return void 0;const castingTime=(_d=(_c=registry.getByTypeAndSlug("spell",(_b=linkOf(ref))!=null?_b:ref))==null?void 0:_c.data)==null?void 0:_d.casting_time;const kind=typeof castingTime==="string"?(_e=parseCastingTime(castingTime))==null?void 0:_e.kind:void 0;return kind?SPELL_COST[kind]:void 0}var chargesOf=e=>e==null?void 0:e.charges;function itemChargesMax(entity){const c=chargesOf(entity);if(typeof c==="number")return c>0?c:void 0;const m=c==null?void 0:c.max;return typeof m==="number"&&m>0?m:void 0}var RESET_OF=r=>{const s=String(r!=null?r:"").toLowerCase();return s.includes("dawn")?"dawn":s.includes("short")?"short":s.includes("long")?"long":"special"};function rechargeAmount(c){var _a,_b;const raw=[c.recharge_amount,c.dice].find(v=>typeof v==="string"&&v.trim()!=="");if(!raw)return"1";const bare=raw.trim().replace(/^`+|`+$/g,"");return((_b=(_a=parseInlineTag(bare))==null?void 0:_a.content)!=null?_b:bare).replace(/\s+/g,"")}var recoveryOf=(c,needRecharge)=>!c||typeof c==="number"||needRecharge&&(typeof c.recharge!=="string"||c.recharge.trim()==="")?void 0:{amount:rechargeAmount(c),reset:RESET_OF(c.recharge)};function effectiveItemRecovery(entry,registry,view){var _a,_b;if(isConsumedOnUse(entry,registry,view))return void 0;if(view&&view.entity===null)return void 0;if((view==null?void 0:view.kind)==="infused"&&itemChargesMax(view.entity)!==void 0)return recoveryOf(chargesOf(view.entity),false);if((_a=entry.state)==null?void 0:_a.recovery)return entry.state.recovery;const own=registry?recoveryOf(chargesOf(ruleOf(entry,registry,view).entity),true):void 0;if(own)return own;const link=linkOf(entry.item);return link?(_b=findItemAction(link))==null?void 0:_b.recovery:void 0}function isConsumedOnUse(entry,registry,view){var _a;const link=linkOf(entry.item);if(!link)return false;if((_a=findItemAction(link))==null?void 0:_a.consumed)return true;const entity=entityOf(entry,registry,view);return(entity==null?void 0:entity.type)==="potion"||isScrollEntity(entity)}function isScrollEntity(entity){if(!entity||typeof entity!=="object")return false;return entity.type==="scroll"||isCastableScroll(entity)}function isCastableScroll(entity){return!!entity&&typeof entity==="object"&&entity.scroll_level!=null}function entityOf(entry,registry,view){if(!registry||!linkOf(entry.item))return null;return ruleOf(entry,registry,view).entity}function effectiveItemCharges(entry,registry,view){var _a,_b,_c,_d,_e,_f;if(isConsumedOnUse(entry,registry,view))return void 0;if(view&&view.entity===null)return void 0;const infused=(view==null?void 0:view.kind)==="infused"?itemChargesMax(view.entity):void 0;if(infused!==void 0)return{current:Math.max(0,Math.min((_c=(_b=(_a=entry.infusion)==null?void 0:_a.charges)==null?void 0:_b.current)!=null?_c:infused,infused)),max:infused};const stored=(_d=entry.state)==null?void 0:_d.charges;if(stored)return stored;const own=registry?itemChargesMax(ruleOf(entry,registry,view).entity):void 0;if(own!==void 0)return{current:own,max:own};const link=linkOf(entry.item);const max=link?(_f=(_e=findItemAction(link))==null?void 0:_e.max_charges)!=null?_f:0:0;return max>0?{current:max,max}:void 0}function effectiveItemArmorClass(entry,registry,view){var _a;if(!registry)return null;const{entity}=ruleOf(entry,registry,view);const armor=effectiveArmor(entity,registry);if(!armor)return null;const shield=isShieldArmor(armor);const bonus=isItemEntity(entity)&&typeof((_a=entity.bonuses)==null?void 0:_a.ac)==="number"?entity.bonuses.ac:0;const terms=slotAcTerms(armor,entry);return{value:terms.armor+terms.override+bonus,shield,addDex:!shield&&armor.ac.add_dex===true}}export{WEAPON_DEFAULT_ACTION_COST,isWeaponLikeEntry,customizableOverrideKeys,defaultActionCost,scrollSpellCost,itemChargesMax,effectiveItemRecovery,isConsumedOnUse,isScrollEntity,isCastableScroll,effectiveItemCharges,effectiveItemArmorClass,poolCountLabel,poolActiveWords,parsePickKey,normalizedPickKey,markerKey,isItemBound,optionCandidates,resolveOptionRows,resolveCopyOption,scaledInfuseItem,resolveEntryEntity,buildInfusionContext,entryCharges,withEntryCharges,isMarkedEntry,splitOne,endInfusion,infuseEntry,createEntry,infusionsEndedByChoice,reconcileChoiceEdit,infusionsEndedByClassEdit,reconcileClassEdit,eligibleTargets,bindFeatureConsumers,levelPrereqMax,levelPrereqRefsMet,poolAnchorLevel,resolvePool,resolveAllPools,strandedPicks,heldPicks,withoutStrandedSites};
1
+ import{parseCastingTime}from"./chunk-CMIEZQL4.js";import{readTableColumn}from"./chunk-CSTAQQGX.js";import{derivePoolLayout}from"./chunk-O776WL7O.js";import{findItemAction,isReadOnceItem,resolveItemAction}from"./chunk-DVUXUIPV.js";import{requiresAttunement}from"./chunk-YGH7S5ZF.js";import{defaultSlotForType,effectiveArmor,isItemEntity,isShieldArmor,resolveEntityForEntry,slotAcTerms}from"./chunk-4IAMSRHD.js";import{warnOnce}from"./chunk-DZITM5AG.js";import{keptSlugFor,resolveBaseItem}from"./chunk-PZ4L2EEG.js";import{bucketOf,memoByRevision}from"./chunk-QMEKQTUT.js";import{bareEntitySlug,slugify,twinKey,wikilinkTailSlug}from"./chunk-63YJPWTM.js";import{parseInlineTag}from"./chunk-BREHZNTL.js";import{isCanonicalDamageType}from"./chunk-7FPQJDFD.js";function equivalentResourceIds(id,index){var _a,_b,_c;const out=[];const add=other=>{if(other!==id&&index.has(other)&&!out.includes(other))out.push(other)};for(const other of(_b=(_a=index.get(id))==null?void 0:_a.equivalentIds)!=null?_b:[])add(other);for(const res of index.values())if((_c=res.equivalentIds)==null?void 0:_c.includes(id))add(res.id);return out}function ownedByClass(res,rc){var _a,_b;const s=(_a=res==null?void 0:res.owner)==null?void 0:_a.source;if(!s)return false;if(s.kind==="class")return s.slug===((_b=rc.entity)==null?void 0:_b.slug);if(s.kind==="subclass")return!!rc.subclass&&s.slug===rc.subclass.slug;return false}function payingResourceId(id,index,owner){const candidates=[id,...equivalentResourceIds(id,index)].filter(c=>index.has(c));if(candidates.length===0)return void 0;if(owner){const own=candidates.find(c=>ownedByClass(index.get(c),owner));if(own)return own}return candidates[0]}function classOfSource(source,classes){var _a,_b;if(source.kind==="class")return(_a=classes.find(c=>{var _a2;return((_a2=c.entity)==null?void 0:_a2.slug)===source.slug}))!=null?_a:null;if(source.kind==="subclass")return(_b=classes.find(c=>{var _a2;return((_a2=c.subclass)==null?void 0:_a2.slug)===source.slug}))!=null?_b:null;return null}function bindFeatureConsumers(features,index,classes){return features.map(rf=>{const consumes=rf.feature.consumes;const id=consumes==null?void 0:consumes.resource;if(!consumes||typeof id!=="string"||id.length===0)return rf;const payer=payingResourceId(id,index,classOfSource(rf.source,classes));if(payer===void 0||payer===id)return rf;return{...rf,feature:{...rf.feature,consumes:{...consumes,resource:payer}}}})}var SORTED_OPTIONAL_FEATURES=new WeakMap;function sortedOptionalFeatures(registry){return memoByRevision(SORTED_OPTIONAL_FEATURES,registry,()=>bucketOf(registry,"optional-feature").slice().sort((a,b)=>a.name.localeCompare(b.name)||a.slug.localeCompare(b.slug)))}var SRD_OWNER_PREFIXES=new Set(["srd-5e","srd-2024"]);function levelPrereqMax(d){var _a;return((_a=d.prerequisites)!=null?_a:[]).filter(p=>p.kind==="level").reduce((m,p)=>Math.max(m,p.min),0)}function namedRefKey(name){return name?slugify(name.replace(/\s*\([^)]*\)\s*$/,"")):""}function levelPrereqRefsMet(d,rc){var _a,_b;for(const p of(_a=d.prerequisites)!=null?_a:[]){if(p.kind!=="level")continue;if(p.class&&namedRefKey(p.class.name)!==namedRefKey((_b=rc.entity)==null?void 0:_b.name))return false;if(p.subclass){const sub=rc.subclass;const own=[sub==null?void 0:sub.short_name,sub==null?void 0:sub.name].map(namedRefKey).filter(k=>k!=="");if(!own.includes(namedRefKey(p.subclass.name)))return false}}return true}function optionalFeaturePrereqKeys(d){var _a;return((_a=d.prerequisites)!=null?_a:[]).filter(p=>p.kind==="optionalfeature").map(p=>twinKey(wikilinkTailSlug(p.optionalfeature)))}function withOptionalFeaturePrereqsMet(offered,selected,grants){let open=offered;for(;;){const openSlugs=new Set(open.map(e=>e.slug));const held=new Set([...grants,...selected.filter(e=>openSlugs.has(e.slug))].map(e=>twinKey(e.slug)));const next=open.filter(e=>optionalFeaturePrereqKeys(e.entity).every(k=>held.has(k)));if(next.length===open.length)return next;open=next}}function poolAnchorLevel(entity,pool){let anchorLevel=1;let columnSeen=false;for(let l=1;l<=20;l++){const c=readTableColumn(entity.table,l,[pool.count.column]);if(c!=null)columnSeen=true;if(c!=null&&c>=1){anchorLevel=l;break}}return{anchorLevel,columnSeen}}function resolvePool(rc,classIndex,pool,registry,index,edition){var _a,_b,_c,_d,_e,_f,_g,_h,_i;const entity=rc.entity;const level=rc.level;const ownerBare=bareEntitySlug(entity.slug);const ownerPrefix=entity.slug.split("_")[0];const ownEdition=SRD_OWNER_PREFIXES.has(ownerPrefix)?entity.edition:void 0;const col=pool.count.column;const count=(_a=readTableColumn(entity.table,level,[col]))!=null?_a:0;const{anchorLevel,columnSeen}=poolAnchorLevel(entity,pool);if(!columnSeen){warnOnce(`pool-column:${pool.id}`,`Archivist: pool "${pool.id}" declares count column "${col}", which "${entity.slug}"'s class table carries at no level; the pool resolves count 0 at anchor level 1`)}const ft=pool.source.where.feature_type;const all=sortedOptionalFeatures(registry);const entryOf=(slug,entity2,compendium)=>({slug,entity:entity2,...compendium?{compendium}:{},key:slug,param:null,itemBound:isItemBound(entity2)});const byBare=new Map;const candidates=new Map;for(const e of all){const d=e.data;const entry=entryOf(e.slug,d,e.compendium);const bare=bareEntitySlug(e.slug);byBare.set(bare,entry);if(d.feature_type!==ft)continue;if(!((_b=d.available_to)!=null?_b:[]).some(l=>wikilinkTailSlug(l)===ownerBare))continue;if(levelPrereqMax(d)>level)continue;if(!levelPrereqRefsMet(d,rc))continue;if(ownEdition&&d.edition&&d.edition!==ownEdition)continue;const key=twinKey(e.slug);const group=candidates.get(key);if(group)group.push(entry);else candidates.set(key,[entry])}const collapsed=[];for(const group of candidates.values()){if(group.length===1){collapsed.push(group[0]);continue}const bare=bareEntitySlug(group[0].slug);const owned=group.find(e=>e.slug.split("_")[0]===ownerPrefix);if(!owned){warnOnce(`pool-collapse:${bare}`,`Archivist: pool "${pool.id}" holds ${group.length} cross-edition entries for "${bare}" and none shares the owner's compendium prefix "${ownerPrefix}"; keeping "${group[0].slug}"`)}collapsed.push(owned!=null?owned:group[0])}const grantDecls=[...(_d=(_c=rc.entity)==null?void 0:_c.pool_grants)!=null?_d:[],...(_f=(_e=rc.subclass)==null?void 0:_e.pool_grants)!=null?_f:[]];const grantsRaw=grantDecls.filter(g=>g.pool===pool.id).flatMap(g=>g.grants).filter(g=>g.at_level<=level).map(g=>byBare.get(wikilinkTailSlug(g.feature))).filter(e=>e!=null);const grantedBare=new Set;const grants=grantsRaw.filter(e=>{const key=bareEntitySlug(e.slug);if(grantedBare.has(key))return false;grantedBare.add(key);return true});const offered=collapsed.filter(e=>!grantedBare.has(bareEntitySlug(e.slug)));const bySlugAvailable=new Map(offered.map(e=>[e.slug,e]));const byTwinAvailable=new Map(offered.map(e=>[twinKey(e.slug),e]));const resolveStored=s=>{const exact=bySlugAvailable.get(s);if(exact)return exact;const survivor=byTwinAvailable.get(twinKey(s));if(survivor)return survivor;const full=registry.getByTypeAndSlug("optional-feature",s);if(full)return entryOf(full.slug,full.data,full.compendium);return byBare.get(bareEntitySlug(s))};const raw=(_g=rc.choices[anchorLevel])==null?void 0:_g[pool.id];const selectedSlugs=Array.isArray(raw)?raw:typeof raw==="string"?[raw]:[];const selected=[];const seenKeys=new Set;for(const s of selectedSlugs){const{slugPart,param}=parsePickKey(s);const entry=resolveStored(slugPart);if(!entry)continue;const repeatable=entry.entity.repeatable===true;if(!repeatable&&param!==null){warnOnce(`pick-param:${pool.id}:${s}`,`Archivist: pool "${pool.id}" pick "${s}" names a parameter, but "${entry.slug}" is not repeatable; the parameter is ignored`)}const nkey=repeatable?normalizedPickKey(s,true):twinKey(entry.slug);if(grantedBare.has(bareEntitySlug(entry.slug))||seenKeys.has(nkey))continue;seenKeys.add(nkey);selected.push({...entry,key:repeatable||param!==null?s:entry.slug,param:repeatable?param:null,...repeatable?{option:resolveCopyOption(entry.entity,param,{classLevel:level,registry,edition})}:{}})}const available=withOptionalFeaturePrereqsMet(offered,selected,grants);const members=[...available,...grants];const layout=derivePoolLayout(members);const votes=new Map;for(const e of members){const id=(_h=e.entity.consumes)==null?void 0:_h.resource;const payer=id?payingResourceId(id,index,rc):void 0;if(!payer)continue;votes.set(payer,((_i=votes.get(payer))!=null?_i:0)+1)}let resource;let bestN=0;for(const[id,n]of votes)if(n>bestN){resource=id;bestN=n}const bind=poolRebinder(rc,pool.id,resource,index);return{id:pool.id,label:pool.label,classIndex,count,anchorLevel,selected:selected.map(bind),available:available.map(bind),grants:grants.map(bind),...layout?{layout}:{},...resource?{resource}:{},...pool.count.label?{countLabel:pool.count.label}:{},...pool.active?{active:pool.active}:{},...pool.head_resource?{headResource:pool.head_resource}:{}}}function poolRebinder(rc,poolId,vote,index){const declared=declaredResourceIds(rc);const copies=new Map;return e=>{const consumes=e.entity.consumes;const id=consumes==null?void 0:consumes.resource;if(!consumes||typeof id!=="string"||id.length===0)return e;const payer=payingResourceId(id,index,rc);if(payer===id)return e;const target=payer!=null?payer:vote!==void 0&&!declared.has(id)?vote:void 0;if(target===void 0)return e;const done=copies.get(e.key);if(done)return done;if(payer===void 0){warnOnce(`pool-rebind:${poolId}:${id}`,`Archivist: pool "${poolId}" members consume "${id}", which this character does not own; bound to the pool's resource "${target}"`)}const copy={...e,entity:{...e.entity,consumes:{...consumes,resource:target}}};copies.set(e.key,copy);return copy}}function declaredResourceIds(rc){var _a;const out=new Set;const add=list=>{for(const r of list!=null?list:[])if(typeof(r==null?void 0:r.id)==="string")out.add(r.id)};for(const owner of[rc.entity,rc.subclass]){if(!owner)continue;add(owner.resources);for(const features of Object.values((_a=owner.features_by_level)!=null?_a:{}))for(const f of features!=null?features:[])add(f.resources)}return out}function resolveAllPools(resolved,registry,index){const out=[];resolved.classes.forEach((rc,classIndex)=>{var _a,_b,_c,_d;if(!rc.entity)return;const decls=[...(_a=rc.entity.selection_pools)!=null?_a:[],...(_c=(_b=rc.subclass)==null?void 0:_b.selection_pools)!=null?_c:[]];const seen=new Set;for(const pool of decls){if(seen.has(pool.id))continue;seen.add(pool.id);out.push(resolvePool(rc,classIndex,pool,registry,index,(_d=resolved.definition)==null?void 0:_d.edition))}});return out}function strandedPicks(pool){const inAvailable=new Set(pool.available.map(e=>e.slug));return pool.selected.filter(e=>!inAvailable.has(e.slug))}function heldPicks(pool){var _a;const selected=(_a=pool.selected)!=null?_a:[];if(!pool.available)return[...selected];const inAvailable=new Set(pool.available.map(e=>e.slug));return selected.filter(e=>inAvailable.has(e.slug))}function withoutStrandedSites(sites,classes,registry,edition){if(sites.length===0)return sites;const strandedKeys=new Map;const keysOf=(classIndex,poolId)=>{var _a,_b,_c;const at=`${classIndex}:${poolId}`;let keys=strandedKeys.get(at);if(keys)return keys;const rc=classes[classIndex];const decl=(rc==null?void 0:rc.entity)?[...(_a=rc.entity.selection_pools)!=null?_a:[],...(_c=(_b=rc.subclass)==null?void 0:_b.selection_pools)!=null?_c:[]].find(p=>p.id===poolId):void 0;keys=new Set(rc&&decl?strandedPicks(resolvePool(rc,classIndex,decl,registry,new Map,edition)).map(e=>twinKey(e.slug)):[]);strandedKeys.set(at,keys);return keys};return sites.filter(site=>!keysOf(site.classIndex,site.poolId).has(twinKey(site.memberSlug)))}function poolCountLabel(pool){var _a;return(_a=pool.countLabel)!=null?_a:"Known"}function poolActiveWords(pool){var _a,_b,_c;const a=pool.active;if(!a)return null;return{column:a.column,label:a.label,verb:a.verb,counterLabel:(_a=a.counter_label)!=null?_a:a.label,createLabel:(_b=a.create_label)!=null?_b:"Created",createVerb:(_c=a.create_verb)!=null?_c:"Create"}}function parsePickKey(stored){const i=stored.indexOf("#");return i===-1?{slugPart:stored,param:null}:{slugPart:stored.slice(0,i),param:stored.slice(i+1)}}function normalizedPickKey(stored,repeatable){const{slugPart,param}=parsePickKey(stored);return repeatable?`${bareEntitySlug(slugPart)}#${param!=null?param:""}`:bareEntitySlug(slugPart)}function markerKey(by){const{slugPart,param}=parsePickKey(by);return param===null?bareEntitySlug(slugPart):`${bareEntitySlug(slugPart)}#${param}`}function isItemBound(note){var _a;return!!note.infuse||note.repeatable===true&&!!((_a=note.options)==null?void 0:_a.some(r=>!!r.creates))}var SRD_BOOKS=new Set(["SRD 2024","SRD 5e"]);var lc=v=>String(v!=null?v:"").trim().toLowerCase();var linkSlug=link=>link.replace(/^\[\[/,"").replace(/\]\]$/,"").split("|")[0];var itemsOf=registry=>registry.search("","item",Number.POSITIVE_INFINITY);function matchesFilter(data,f){var _a;const type=lc(data.type);if(!f.rarity.map(lc).includes(lc(data.rarity)))return false;if(f.types&&!f.types.map(lc).includes(type))return false;if((_a=f.exclude_types)==null?void 0:_a.map(lc).includes(type))return false;return!(f.cursed===false&&data.cursed===true)}function rowMatches(row,it){const c=row.creates;if(c.item)return lc(it.name)===lc(row.name)||it.slug===linkSlug(c.item);if(c.variant)return c.variant.candidates.some(l=>bareEntitySlug(linkSlug(l))===bareEntitySlug(it.slug));return!!c.filter&&matchesFilter(it.data,c.filter)}function buildItemIndex(items){const lcType=[],lcRarity=[];const byLcName=new Map,bySlug=new Map,byBare=new Map;const push=(m,k,i)=>{const l=m.get(k);if(l)l.push(i);else m.set(k,[i])};items.forEach((it,i)=>{const data=it.data;lcType.push(lc(data.type));lcRarity.push(lc(data.rarity));push(byLcName,lc(it.name),i);if(!bySlug.has(it.slug))bySlug.set(it.slug,i);push(byBare,bareEntitySlug(it.slug),i)});return{items,lcType,lcRarity,byLcName,bySlug,byBare}}var ITEM_INDEX=new WeakMap;var itemIndexOf=registry=>memoByRevision(ITEM_INDEX,registry,()=>buildItemIndex(itemsOf(registry)));var inBucketOrder=(ix,hits)=>[...hits].sort((a,b)=>a-b).map(i=>ix.items[i]);function rowInstalledIn(row,ix){var _a,_b,_c;const c=row.creates;if(c.item){const hits=new Set((_a=ix.byLcName.get(lc(row.name)))!=null?_a:[]);const own=ix.bySlug.get(linkSlug(c.item));if(own!==void 0)hits.add(own);return inBucketOrder(ix,hits)}if(c.variant){const hits=new Set;for(const l of c.variant.candidates)for(const i of(_b=ix.byBare.get(bareEntitySlug(linkSlug(l))))!=null?_b:[])hits.add(i);return inBucketOrder(ix,hits)}const f=c.filter;if(!f)return[];const rarities=new Set(f.rarity.map(lc));const types=f.types?new Set(f.types.map(lc)):null;const excluded=new Set(((_c=f.exclude_types)!=null?_c:[]).map(lc));return ix.items.filter((it,i)=>rarities.has(ix.lcRarity[i])&&(!types||types.has(ix.lcType[i]))&&!excluded.has(ix.lcType[i])&&!(f.cursed===false&&it.data.cursed===true))}var rowInstalled=(row,registry)=>rowInstalledIn(row,itemIndexOf(registry));function candidateOrder(edition){return(a,b)=>{const ea=edition&&lc(a.data.edition)===edition?0:1;const eb=edition&&lc(b.data.edition)===edition?0:1;if(ea!==eb)return ea-eb;const sa=SRD_BOOKS.has(a.compendium)?0:1,sb=SRD_BOOKS.has(b.compendium)?0:1;if(sa!==sb)return sa-sb;return a.slug<b.slug?-1:a.slug>b.slug?1:0}}function optionCandidates(row,registry,opts={}){return candidatesFrom(rowInstalled(row,registry),registry,opts)}function candidatesFrom(installed,registry,opts){var _a,_b;const visible=(_a=opts.isEntityVisible)!=null?_a:(()=>true);const excluded=((_b=opts.exclude)!=null?_b:[]).map(s=>{var _a2;return registry.getByTypeAndSlug("item",(_a2=keptSlugFor(s))!=null?_a2:s)}).filter(e=>!!e);const exNames=new Set(excluded.map(e=>lc(e.name))),exBares=new Set(excluded.map(e=>bareEntitySlug(e.slug)));const seen=new Set,out=[];for(const e of installed.filter(visible).sort(candidateOrder(opts.edition))){const bare=bareEntitySlug(e.slug);if(seen.has(bare))continue;seen.add(bare);if(exNames.has(lc(e.name))||exBares.has(bare))continue;out.push(e.slug)}return out}function resolveOptionRows(note,registry,opts={}){var _a;const ix=itemIndexOf(registry);return((_a=note.options)!=null?_a:[]).map(row=>{var _a2;const rowItems=rowInstalledIn(row,ix);const candidates=candidatesFrom(rowItems,registry,opts);const anyVisible=candidates.length>0||candidatesFrom(rowItems,registry,{...opts,exclude:[]}).length>0;const installed=rowItems.length>0;return{key:row.key,name:row.name,minLevel:row.min_level,...row.attunement!==void 0?{attunement:row.attunement}:{},arm:row.creates.item?"item":row.creates.variant?"variant":"filter",candidates,availability:anyVisible?"installed":installed?"hidden-only":"not-installed",...rowItemWords(row,candidates[0]?ix.items[(_a2=ix.bySlug.get(candidates[0]))!=null?_a2:-1]:rowItems[0])}})}function rowItemWords(row,item){var _a,_b,_c,_d;const f=row.creates.filter;if(f)return{type:((_a=f.types)==null?void 0:_a[0])?lc(f.types[0]):null,rarity:f.rarity[0]?lc(f.rarity[0]):null,charges:null};const data=(_b=item==null?void 0:item.data)!=null?_b:{};const max=(_c=data.charges)==null?void 0:_c.max;return{type:lc(data.type)||null,rarity:lc(data.rarity)||null,charges:typeof max==="number"&&max>0?{max,...typeof((_d=data.charges)==null?void 0:_d.recharge)==="string"?{recharge:data.charges.recharge}:{}}:null}}function resolveCopyOption(note,param,ctx){var _a,_b,_c;const rows=(_a=note.options)!=null?_a:[];if(param===null||param==="")return{row:null,status:"needs-choice"};if(note.item_choice==="create"){const row=rows.find(r=>r.key===param);if(!row)return{row:null,status:"invalid"};const installed=rowInstalled(row,ctx.registry).sort(candidateOrder(ctx.edition));if(installed.length===0)return{row,status:"not-installed"};const own=row.creates.item?linkSlug(row.creates.item):void 0;const item=row.creates.item?((_b=installed.find(e=>e.slug===own))!=null?_b:installed[0]).slug:void 0;return{row,...item?{item}:{},status:row.min_level<=ctx.classLevel?"ok":"level"}}const slug=(_c=keptSlugFor(param))!=null?_c:param;const it=ctx.registry.getByTypeAndSlug("item",slug);if(!it)return{row:null,item:slug,status:"not-installed"};const matching=rows.filter(r=>rowMatches(r,it)).sort((a,b)=>a.min_level-b.min_level);if(matching.length===0)return{row:null,item:slug,status:"invalid"};return{row:matching[0],item:slug,status:matching[0].min_level<=ctx.classLevel?"ok":"level"}}var MUNDANE=new Set(["","none","mundane"]);var isMagic=data=>{const r=data==null?void 0:data.rarity;return typeof r==="string"&&!MUNDANE.has(r.trim().toLowerCase())};var plainText=item=>item.replace(/^\[\[/,"").replace(/\]\]$/,"").split("|").pop().split("/").pop();function scaledInfuseItem(infuse,classLevel){var _a,_b;let item={...(_a=infuse.item)!=null?_a:{}};const rows=[...(_b=infuse.scales_at)!=null?_b:[]].sort((a,b)=>a.level-b.level);for(const row of rows)if(row.level<=classLevel)item={...item,...row.item};return item}function wrapInfused(entry,note,classLevel,registry){var _a,_b,_c,_d,_e,_f,_g,_h,_i,_j,_k;const infuse=note.infuse;const item=scaledInfuseItem(infuse,classLevel);const resist=[...(_a=item.resist)!=null?_a:[],...((_b=infuse.choice)==null?void 0:_b.kind)==="damage-type"&&((_c=entry.infusion)==null?void 0:_c.choice)?[entry.infusion.choice]:[]];const overlay={...item.bonuses?{bonuses:item.bonuses}:{},resist,...item.charges?{charges:item.charges}:{},...item.action?{action:item.action}:{},...item.range?{range:item.range}:{},...infuse.attunement?{attunement:{required:true}}:{}};const base=resolveBaseItem(entry.item,registry);const data=(_d=base==null?void 0:base.data)!=null?_d:null;if(base&&isMagic(data)){const b=data;const bonuses={...(_e=b.bonuses)!=null?_e:{}};for(const[k,v]of Object.entries((_f=item.bonuses)!=null?_f:{}))if(typeof v==="number")bonuses[k]=(typeof bonuses[k]==="number"?bonuses[k]:0)+v;return{entity:{...b,bonuses,resist:[...new Set([...(_g=b.resist)!=null?_g:[],...resist])],attunement:{required:requiresAttunement(b)||!!infuse.attunement}},magicBase:true}}const rarity=(_h=infuse.rarity)!=null?_h:"unknown";if(!base){const text=plainText(entry.item);return{entity:{slug:`infused:${slugify(text)}`,name:text,type:"wondrous item",rarity,...overlay,description:""},magicBase:false}}const name=String((_i=data==null?void 0:data.name)!=null?_i:base.name),description=String((_j=data==null?void 0:data.description)!=null?_j:"");const slotted=base.entityType==="armor"||base.entityType==="weapon"?base:typeof(data==null?void 0:data.base_item)==="string"?resolveBaseItem(data.base_item,registry):null;if(slotted&&(slotted.entityType==="armor"||slotted.entityType==="weapon")){const type=slotted.entityType==="weapon"?"weapon":isShieldArmor(slotted.data)?"shield":"armor";return{entity:{slug:base.slug,name,type,rarity,base_item:`[[${slotted.slug}]]`,...overlay,description},magicBase:false}}return{entity:{slug:base.slug,name,type:String((_k=data==null?void 0:data.type)!=null?_k:"adventuring gear"),rarity,...overlay,description},magicBase:false}}function resolveEntryEntity(entry,index,registry,infusions){const view=!infusions?void 0:"views"in infusions?infusions.views.get(index):infusions.index===index?infusions:void 0;if(view)return{entity:view.entity,entityType:view.entityType};return resolveEntityForEntry(entry.item,registry)}function buildInfusionContext(character,resolved,registry){var _a,_b,_c,_d,_e;const equipment=(_a=character.equipment)!=null?_a:[];const pools=((_b=resolved.pools)!=null?_b:[]).filter(p=>!!p.active||p.selected.some(e=>e.itemBound));if(pools.length===0&&!equipment.some(e=>!!e.infusion))return void 0;const owners=new Map;for(const pool of pools)for(const entry of pool.selected)if(entry.itemBound)owners.set(normalizedPickKey(entry.key,entry.entity.repeatable===true),{pool,entry});const views=new Map,flags=[];const newest=new Map;equipment.forEach((e,i)=>{if(!e.infusion)return;const k=markerKey(e.infusion.by);const j=newest.get(k);if(j===void 0||equipment[j].infusion.seq<e.infusion.seq)newest.set(k,i)});equipment.forEach((e,i)=>{var _a2,_b2,_c2;const m=e.infusion;if(!m)return;const owner=owners.get(markerKey(m.by));const nullView=()=>{var _a3,_b3,_c3,_d2,_e2;return{index:i,kind:m.kind,entity:null,entityType:null,key:m.by,seq:m.seq,poolId:(_a3=owner==null?void 0:owner.pool.id)!=null?_a3:"",classIndex:(_b3=owner==null?void 0:owner.pool.classIndex)!=null?_b3:-1,noteSlug:(_c3=owner==null?void 0:owner.entry.slug)!=null?_c3:"",noteName:(_d2=owner==null?void 0:owner.entry.entity.name)!=null?_d2:"",sourceLabel:(_e2=owner==null?void 0:owner.entry.entity.name)!=null?_e2:""}};if(!owner){flags.push({index:i,reason:"orphan"});if(m.kind==="created")views.set(i,nullView());return}if(newest.get(markerKey(m.by))!==i){flags.push({index:i,reason:"duplicate"});if(m.kind==="created")views.set(i,nullView());return}if(((_a2=e.qty)!=null?_a2:1)>1)flags.push({index:i,reason:"stack"});const classLevel=(_c2=(_b2=resolved.classes[owner.pool.classIndex])==null?void 0:_b2.level)!=null?_c2:0;const base={index:i,kind:m.kind,key:m.by,seq:m.seq,poolId:owner.pool.id,classIndex:owner.pool.classIndex,noteSlug:owner.entry.slug,noteName:owner.entry.entity.name,sourceLabel:owner.entry.entity.name};if(m.kind==="created"){const own=resolveEntityForEntry(e.item,registry);const it=resolveBaseItem(e.item,registry);const opt=owner.entry.option;const fits=!!it&&!!(opt==null?void 0:opt.row)&&(opt.item===it.slug||rowMatches(opt.row,it));if(!fits)flags.push({index:i,reason:"mismatch"});views.set(i,{...base,entity:own.entity,entityType:own.entityType});return}if(!owner.entry.entity.infuse){flags.push({index:i,reason:"orphan"});return}const w=wrapInfused(e,owner.entry.entity,classLevel,registry);if(w.magicBase)flags.push({index:i,reason:"magic-base"});views.set(i,{...base,entity:w.entity,entityType:"item"})});const counters=new Map;for(const pool of pools){const words=poolActiveWords(pool);if(!words)continue;const rc=resolved.classes[pool.classIndex];const max=(_e=readTableColumn((_c=rc==null?void 0:rc.entity)==null?void 0:_c.table,(_d=rc==null?void 0:rc.level)!=null?_d:0,[words.column]))!=null?_e:0;const used=[...views.values()].filter(v=>v.poolId===pool.id&&v.entity!==null).length;counters.set(pool.id,{label:words.counterLabel,used,max,over:used>max})}return{views,counters,flags}}function entryCharges(entry,view,registry){return effectiveItemCharges(entry,registry,view)}function withEntryCharges(entry,view,current,registry){var _a,_b,_c,_d,_e,_f;const overlayMax=(view==null?void 0:view.kind)==="infused"?itemChargesMax(view.entity):void 0;if(overlayMax!==void 0&&entry.infusion)return{...entry,infusion:{...entry.infusion,charges:{current:Math.max(0,Math.min(current,overlayMax))}}};const max=(_e=(_d=(_b=(_a=entry.state)==null?void 0:_a.charges)==null?void 0:_b.max)!=null?_d:(_c=effectiveItemCharges(entry,registry,view))==null?void 0:_c.max)!=null?_e:Math.max(0,current);return{...entry,state:{...(_f=entry.state)!=null?_f:{},charges:{current:Math.max(0,Math.min(current,max)),max}}}}function isMarkedEntry(entry){return!!entry.infusion}function splitOne(equipment,index){var _a,_b;const src=equipment[index];if(!src||((_a=src.qty)!=null?_a:1)<=1)return[...equipment];const one={item:src.item,qty:1,...src.in!==void 0?{in:src.in}:{},...src.overrides?{overrides:src.overrides}:{}};return[...equipment.slice(0,index),{...src,qty:((_b=src.qty)!=null?_b:1)-1},one,...equipment.slice(index+1)]}var refuse=reason=>({ok:false,reason});function endInfusion(equipment,index,registry){const entry=equipment[index];if(!(entry==null?void 0:entry.infusion))return{equipment:[...equipment],ended:[]};const{kind,by}=entry.infusion;if(kind==="infused"){const{infusion:_m,...rest}=entry;const keep=requiresAttunement(resolveEntryEntity(rest,index,registry).entity);const next=keep?rest:(({attuned:_a,...r})=>r)(rest);return{equipment:equipment.map((e,i)=>i===index?next:e),ended:[{index,key:by,kind,item:entry.item}]}}const moved=equipment.map((e,i)=>{if(i===index||entry.id===void 0||e.in!==entry.id)return e;if(entry.in===void 0){const{in:_in,...r}=e;return r}return{...e,in:entry.in}});return{equipment:moved.filter((_,i)=>i!==index),ended:[{index:-1,key:by,kind,item:entry.item}]}}var pickKeyOf=e=>normalizedPickKey(e.key,e.entity.repeatable===true);var nextSeq=equipment=>equipment.reduce((m,e)=>{var _a,_b;return Math.max(m,(_b=(_a=e.infusion)==null?void 0:_a.seq)!=null?_b:0)},0)+1;function ownedPick(resolved,key){var _a,_b;const k=markerKey(key);for(const pool of(_a=resolved.pools)!=null?_a:[]){const entry=pool.selected.find(e=>e.itemBound&&pickKeyOf(e)===k);if(entry)return{pool,entry,stranded:strandedPicks(pool).includes(entry)||((_b=entry.option)==null?void 0:_b.status)==="level"}}return null}var wordsOf=(...texts)=>texts.map(lc).join(" ").split(/[^a-z]+/).filter(w=>w!=="");function shapeOf(found,text,registry){var _a,_b,_c;if(!found)return{kind:"gear",words:wordsOf(text)};const data=(_a=found.data)!=null?_a:{};const words=wordsOf((_b=data.name)!=null?_b:text,data.type);const slotted=found.entityType==="armor"||found.entityType==="weapon"?found:typeof data.base_item==="string"?resolveBaseItem(data.base_item,registry):null;if((slotted==null?void 0:slotted.entityType)==="armor"){const armor=slotted.data;return{kind:isShieldArmor(armor)?"shield":"armor",words,category:lc(armor.category)}}if((slotted==null?void 0:slotted.entityType)==="weapon"){const w=slotted.data;return{kind:"weapon",words,category:lc(w.category),properties:((_c=w.properties)!=null?_c:[]).filter(p=>typeof p==="string").map(lc)}}return{kind:"gear",words}}function admits(t,s){var _a,_b,_c,_d;if(t.kind!==s.kind)return false;if(((_a=t.category)==null?void 0:_a.length)&&!t.category.map(lc).includes(((_b=s.category)!=null?_b:"").split("-")[0]))return false;if(t.property&&!((_c=s.properties)!=null?_c:[]).includes(lc(t.property)))return false;if(((_d=t.name_any)==null?void 0:_d.length)&&!t.name_any.some(n=>{const w=wordsOf(n);return w.length>0&&w.every(x=>s.words.includes(x))}))return false;return true}function targetVerdict(entry,infuse,registry){const found=resolveBaseItem(entry.item,registry);if(!infuse.targets.some(t=>admits(t,shapeOf(found,plainText(entry.item),registry))))return"target-kind";return found&&isMagic(found.data)?"magic-base":"ok"}function newObjectEntry(name,infuse,registry,visible){const want=lc(name);const found=[];for(const type of["armor","weapon","item"]){for(const e of registry.search(name,type,Number.POSITIVE_INFINITY)){if(lc(e.name)===want&&!isMagic(e.data)&&visible(e)&&infuse.targets.some(t=>admits(t,shapeOf(e,e.name,registry))))found.push(e)}}const first=found.sort(candidateOrder(void 0))[0];return first?{item:`[[${first.slug}]]`,qty:1}:{item:name,qty:1}}function endBySeqs(equipment,seqs,registry){let eq=[...equipment];let slots=eq.map((_,i)=>i);const rows=[];for(const{seq,by}of seqs){const i=eq.findIndex(e=>{var _a;return((_a=e.infusion)==null?void 0:_a.seq)===seq&&e.infusion.by===by});if(i===-1)continue;const w=endInfusion(eq,i,registry);for(const row of w.ended)rows.push({row,slot:slots[i]});if(eq[i].infusion.kind==="created")slots=slots.filter((_,j)=>j!==i);eq=w.equipment}return{equipment:eq,ended:rows.map(({row,slot})=>row.kind==="infused"?{...row,index:slots.indexOf(slot)}:row)}}function displaced(equipment,resolved,pool,key){var _a;const k=markerKey(key);const out=equipment.filter(e=>!!e.infusion&&markerKey(e.infusion.by)===k).map(e=>({seq:e.infusion.seq,by:e.infusion.by}));const counter=(_a=resolved.infusions)==null?void 0:_a.counters.get(pool.id);if(!counter)return out;const live=[...resolved.infusions.views.values()].filter(v=>v.poolId===pool.id&&v.classIndex===pool.classIndex&&v.entity!==null&&markerKey(v.key)!==k).sort((a,b)=>a.seq-b.seq);let used=live.length;for(const v of live){if(used+1<=counter.max)break;out.push({seq:v.seq,by:v.key});used--}return out}function infuseEntry(character,resolved,registry,req){var _a,_b,_c,_d,_e,_f,_g;const owned=ownedPick(resolved,req.key);if(!owned)return refuse("not-owned");const infuse=owned.entry.entity.infuse;if(!infuse)return refuse("not-infusing");if(owned.stranded)return refuse("stranded");const wantsChoice=((_a=infuse.choice)==null?void 0:_a.kind)==="damage-type";const choice=lc(req.choice);if(wantsChoice&&choice==="")return refuse("choice-required");if(wantsChoice&&!isCanonicalDamageType(choice))return refuse("bad-choice");if(wantsChoice&&((_b=infuse.choice)==null?void 0:_b.options)&&!infuse.choice.options.some(o=>lc(o)===choice))return refuse("bad-choice");const equipment=(_c=character.equipment)!=null?_c:[];const charges=scaledInfuseItem(infuse,(_e=(_d=resolved.classes[owned.pool.classIndex])==null?void 0:_d.level)!=null?_e:0).charges;const marker={kind:"infused",by:owned.entry.key,seq:nextSeq(equipment),...wantsChoice?{choice}:{},...charges?{charges:{current:charges.max}}:{}};let placed;if(typeof req.target==="number"){const target=equipment[req.target];if(!target)return refuse("no-target");if(target.infusion)return refuse("marked");const verdict=targetVerdict(target,infuse,registry);if(verdict!=="ok")return refuse(verdict);const split=((_f=target.qty)!=null?_f:1)>1;placed=split?splitOne(equipment,req.target):[...equipment];const i=split?req.target+1:req.target;placed[i]={...placed[i],infusion:marker}}else{const name=req.target.newObject.trim();if(name==="")return refuse("no-target");placed=[...equipment,{...newObjectEntry(name,infuse,registry,(_g=req.isEntityVisible)!=null?_g:(()=>true)),infusion:marker}]}return{ok:true,...endBySeqs(placed,displaced(equipment,resolved,owned.pool,owned.entry.key),registry)}}function createEntry(character,resolved,registry,req){var _a,_b;const owned=ownedPick(resolved,req.key);if(!owned)return refuse("not-owned");const note=owned.entry.entity;if(!(note.repeatable===true&&!!((_a=note.options)==null?void 0:_a.some(r=>!!r.creates))))return refuse("not-creating");if(owned.stranded)return refuse("stranded");const opt=owned.entry.option;if(!(opt==null?void 0:opt.row)||opt.status!=="ok")return refuse("invalid-item");const it=registry.getByTypeAndSlug("item",linkSlug(req.item.trim()));if(!it||!(opt.item===it.slug||rowMatches(opt.row,it)))return refuse("invalid-item");const equipment=(_b=character.equipment)!=null?_b:[];const placed=[...equipment,{item:`[[${it.slug}]]`,qty:1,infusion:{kind:"created",by:owned.entry.key,seq:nextSeq(equipment)}}];return{ok:true,...endBySeqs(placed,displaced(equipment,resolved,owned.pool,owned.entry.key),registry)}}function markersWhere(equipment,pick){const out=[];equipment.forEach((e,index)=>{const m=e.infusion;if(m&&pick(m))out.push({index,key:m.by,kind:m.kind,item:e.item,seq:m.seq,by:m.by})});return out}var asRows=list=>list.map(({index,key,kind,item})=>({index,key,kind,item}));var storedKeys=v=>typeof v==="string"?[v]:Array.isArray(v)?v:[];function choiceEnds(character,resolved,req){var _a,_b,_c,_d,_e,_f;const pool=((_a=resolved.pools)!=null?_a:[]).find(p=>p.classIndex===req.classIndex&&p.id===req.choiceKey);if(!pool||!(pool.active||pool.selected.some(e=>e.itemBound)))return[];const choices=(_c=(_b=character.class[req.classIndex])==null?void 0:_b.choices)!=null?_c:{};const kept=new Set(req.next.map(markerKey));for(const lvl of Object.keys(choices))if(Number(lvl)!==req.level)for(const s of storedKeys((_d=choices[Number(lvl)])==null?void 0:_d[req.choiceKey]))kept.add(markerKey(s));const removed=new Set(storedKeys((_e=choices[req.level])==null?void 0:_e[req.choiceKey]).map(markerKey).filter(k=>!kept.has(k)));return markersWhere((_f=character.equipment)!=null?_f:[],m=>removed.has(markerKey(m.by)))}function infusionsEndedByChoice(character,resolved,_registry,req){return asRows(choiceEnds(character,resolved,req))}function reconcileChoiceEdit(character,resolved,registry,req){var _a;const list=choiceEnds(character,resolved,req);return list.length===0?null:endBySeqs((_a=character.equipment)!=null?_a:[],list,registry)}function classEnds(character,resolved,req){var _a,_b,_c,_d,_e;let pools=((_a=resolved.pools)!=null?_a:[]).filter(p=>p.classIndex===req.classIndex);if(!("remove"in req)){const old=(_c=(_b=resolved.classes[req.classIndex])==null?void 0:_b.subclass)!=null?_c:null;if(!old||req.subclass!==null&&bareEntitySlug(linkSlug(req.subclass.trim()))===bareEntitySlug(old.slug))return[];const ids=new Set(((_d=old.selection_pools)!=null?_d:[]).map(p=>p.id));pools=pools.filter(p=>ids.has(p.id))}const owned=new Set;for(const pool of pools)for(const e of pool.selected)if(e.itemBound)owned.add(pickKeyOf(e));return markersWhere((_e=character.equipment)!=null?_e:[],m=>owned.has(markerKey(m.by)))}function infusionsEndedByClassEdit(character,resolved,_registry,req){return asRows(classEnds(character,resolved,req))}function reconcileClassEdit(character,resolved,registry,req){var _a;const list=classEnds(character,resolved,req);return list.length===0?null:endBySeqs((_a=character.equipment)!=null?_a:[],list,registry)}function eligibleTargets(character,resolved,registry,key){var _a,_b;const infuse=(_a=ownedPick(resolved,key))==null?void 0:_a.entry.entity.infuse;if(!infuse)return[];const out=[];((_b=character.equipment)!=null?_b:[]).forEach((e,index)=>{var _a2;if(!e.infusion&&targetVerdict(e,infuse,registry)==="ok")out.push({index,stack:((_a2=e.qty)!=null?_a2:1)>1})});return out}var WEAPON_DEFAULT_ACTION_COST="action";var linkOf=item=>{var _a,_b;return(_b=(_a=item.match(/^\[\[(.+)\]\]$/))==null?void 0:_a[1])!=null?_b:null};var ruleOf=(entry,registry,view)=>resolveEntryEntity(entry,view?view.index:-1,registry,view!=null?view:null);function isWeaponLikeEntry(entry,registry,view){if(!registry)return false;const r=ruleOf(entry,registry,view);return defaultSlotForType(r.entityType,r.entity,registry)==="mainhand"}function itemsRowBranch(entry,registry,view){var _a,_b;const link=linkOf(entry.item);if(!link||!registry)return false;const t=view?view.entityType:(_b=(_a=registry.getBySlug(link))==null?void 0:_a.entityType)!=null?_b:null;return t!=="weapon"&&t!=="armor"&&!isWeaponLikeEntry(entry,registry,view)}function customizableOverrideKeys(entry,registry){const consumed=isConsumedOnUse(entry,registry);const keys=new Set(consumed?["name"]:["name","charges","recovery"]);if(!registry)return keys;const r=ruleOf(entry,registry);const slot=defaultSlotForType(r.entityType,r.entity,registry);const weaponLike=slot==="mainhand";const itemsRow=itemsRowBranch(entry,registry);if(weaponLike){keys.add("bonus");keys.add("damage_bonus");keys.add("extra_damage")}if(slot==="armor"||slot==="shield")keys.add("ac_bonus");if(weaponLike||itemsRow)keys.add("action");if(itemsRow)keys.add("range");const link=linkOf(entry.item);if(r.entityType==="item"&&!consumed&&!(link&&isReadOnceItem(link)))keys.add("resist");return keys}function defaultActionCost(entry,registry,view){var _a,_b,_c,_d,_e;if(isWeaponLikeEntry(entry,registry,view))return WEAPON_DEFAULT_ACTION_COST;const link=linkOf(entry.item);if(!link||!registry||!itemsRowBranch(entry,registry,view))return null;const withoutOverrides={...entry,overrides:void 0};const type=view?(_a=view.entity)==null?void 0:_a.type:(_c=(_b=registry.getBySlug(link))==null?void 0:_b.data)==null?void 0:_c.type;return(_e=(_d=resolveItemAction(link,withoutOverrides,type,{view,spellCost:scrollSpellCost(entry,registry)}))==null?void 0:_d.cost)!=null?_e:null}var SPELL_COST={action:"action",bonus:"bonus-action",reaction:"reaction"};function scrollSpellCost(entry,registry){var _a,_b,_c,_d,_e;const ref=(_a=entry.overrides)==null?void 0:_a.spell;if(!ref||!registry)return void 0;const castingTime=(_d=(_c=registry.getByTypeAndSlug("spell",(_b=linkOf(ref))!=null?_b:ref))==null?void 0:_c.data)==null?void 0:_d.casting_time;const kind=typeof castingTime==="string"?(_e=parseCastingTime(castingTime))==null?void 0:_e.kind:void 0;return kind?SPELL_COST[kind]:void 0}var chargesOf=e=>e==null?void 0:e.charges;function itemChargesMax(entity){const c=chargesOf(entity);if(typeof c==="number")return c>0?c:void 0;const m=c==null?void 0:c.max;return typeof m==="number"&&m>0?m:void 0}var RESET_OF=r=>{const s=String(r!=null?r:"").toLowerCase();return s.includes("dawn")?"dawn":s.includes("short")?"short":s.includes("long")?"long":"special"};function rechargeAmount(c){var _a,_b;const raw=[c.recharge_amount,c.dice].find(v=>typeof v==="string"&&v.trim()!=="");if(!raw)return"1";const bare=raw.trim().replace(/^`+|`+$/g,"");return((_b=(_a=parseInlineTag(bare))==null?void 0:_a.content)!=null?_b:bare).replace(/\s+/g,"")}var recoveryOf=(c,needRecharge)=>!c||typeof c==="number"||needRecharge&&(typeof c.recharge!=="string"||c.recharge.trim()==="")?void 0:{amount:rechargeAmount(c),reset:RESET_OF(c.recharge)};function effectiveItemRecovery(entry,registry,view){var _a,_b;if(isConsumedOnUse(entry,registry,view))return void 0;if(view&&view.entity===null)return void 0;if((view==null?void 0:view.kind)==="infused"&&itemChargesMax(view.entity)!==void 0)return recoveryOf(chargesOf(view.entity),false);if((_a=entry.state)==null?void 0:_a.recovery)return entry.state.recovery;const own=registry?recoveryOf(chargesOf(ruleOf(entry,registry,view).entity),true):void 0;if(own)return own;const link=linkOf(entry.item);return link?(_b=findItemAction(link))==null?void 0:_b.recovery:void 0}function isConsumedOnUse(entry,registry,view){var _a;const link=linkOf(entry.item);if(!link)return false;if((_a=findItemAction(link))==null?void 0:_a.consumed)return true;const entity=entityOf(entry,registry,view);return(entity==null?void 0:entity.type)==="potion"||isScrollEntity(entity)}function isScrollEntity(entity){if(!entity||typeof entity!=="object")return false;return entity.type==="scroll"||isCastableScroll(entity)}function isCastableScroll(entity){return settableSpellLevel(entity)!==null&&!storesSpell(entity)}function settableSpellLevel(entity){if(!entity||typeof entity!=="object")return null;const level=entity.scroll_level;return typeof level==="number"?level:null}function storesSpell(entity){if(settableSpellLevel(entity)===null)return false;const e=entity;if(e.type==="scroll")return false;return itemChargesMax(entity)!==void 0||typeof e.spell_charge_cost==="number"}function storedSpellNumbers(entity){if(!storesSpell(entity))return null;const e=entity;const text=[e.description,...Array.isArray(e.entries)?e.entries:[]].filter(t=>typeof t==="string").join("\n");const fromText=re=>{const m=re.exec(text);return m?parseInt(m[1],10):void 0};const saveDC=typeof e.spell_save_dc==="number"?e.spell_save_dc:fromText(/\bsav(?:e|ing throw) DC (?:is|of) (\d+)/i);const attackBonus=typeof e.spell_attack_bonus==="number"?e.spell_attack_bonus:fromText(/\battack bonus (?:is|of) \+?(-?\d+)/i);if(saveDC===void 0&&attackBonus===void 0)return null;return{...saveDC!==void 0?{saveDC}:{},...attackBonus!==void 0?{attackBonus}:{}}}function itemSpellUse(entry,registry,view){const entity=entityOf(entry,registry,view);if(settableSpellLevel(entity)===null)return null;if(isConsumedOnUse(entry,registry,view))return{kind:"consume"};const declared=entity.spell_charge_cost;const cost=typeof declared==="number"&&Number.isInteger(declared)&&declared>=0?declared:1;const charges=effectiveItemCharges(entry,registry,view);if(cost===0||!charges)return{kind:"at-will"};return{kind:"charges",cost,charges:{current:charges.current,max:charges.max}}}function entityOf(entry,registry,view){if(!registry||!linkOf(entry.item))return null;return ruleOf(entry,registry,view).entity}function effectiveItemCharges(entry,registry,view){var _a,_b,_c,_d,_e,_f;if(isConsumedOnUse(entry,registry,view))return void 0;if(view&&view.entity===null)return void 0;const infused=(view==null?void 0:view.kind)==="infused"?itemChargesMax(view.entity):void 0;if(infused!==void 0)return{current:Math.max(0,Math.min((_c=(_b=(_a=entry.infusion)==null?void 0:_a.charges)==null?void 0:_b.current)!=null?_c:infused,infused)),max:infused};const stored=(_d=entry.state)==null?void 0:_d.charges;if(stored)return stored;const own=registry?itemChargesMax(ruleOf(entry,registry,view).entity):void 0;if(own!==void 0)return{current:own,max:own};const link=linkOf(entry.item);const max=link?(_f=(_e=findItemAction(link))==null?void 0:_e.max_charges)!=null?_f:0:0;return max>0?{current:max,max}:void 0}function effectiveItemArmorClass(entry,registry,view){var _a;if(!registry)return null;const{entity}=ruleOf(entry,registry,view);const armor=effectiveArmor(entity,registry);if(!armor)return null;const shield=isShieldArmor(armor);const bonus=isItemEntity(entity)&&typeof((_a=entity.bonuses)==null?void 0:_a.ac)==="number"?entity.bonuses.ac:0;const terms=slotAcTerms(armor,entry);return{value:terms.armor+terms.override+bonus,shield,addDex:!shield&&armor.ac.add_dex===true}}export{WEAPON_DEFAULT_ACTION_COST,isWeaponLikeEntry,customizableOverrideKeys,defaultActionCost,scrollSpellCost,itemChargesMax,effectiveItemRecovery,isConsumedOnUse,isScrollEntity,isCastableScroll,settableSpellLevel,storesSpell,storedSpellNumbers,itemSpellUse,effectiveItemCharges,effectiveItemArmorClass,poolCountLabel,poolActiveWords,parsePickKey,normalizedPickKey,markerKey,isItemBound,optionCandidates,resolveOptionRows,resolveCopyOption,scaledInfuseItem,resolveEntryEntity,buildInfusionContext,entryCharges,withEntryCharges,isMarkedEntry,splitOne,endInfusion,infuseEntry,createEntry,infusionsEndedByChoice,reconcileChoiceEdit,infusionsEndedByClassEdit,reconcileClassEdit,eligibleTargets,bindFeatureConsumers,levelPrereqMax,levelPrereqRefsMet,poolAnchorLevel,resolvePool,resolveAllPools,strandedPicks,heldPicks,withoutStrandedSites};
@@ -1 +1 @@
1
- import{parseSubclass}from"./chunk-TLXFGGWH.js";import yaml from"js-yaml";var subclassCodec={parse(doc){return parseSubclass(doc.body)},serialize(entity){return yaml.dump(entity,{lineWidth:-1,sortKeys:false})}};export{subclassCodec};
1
+ import{parseSubclass}from"./chunk-ETDMOGFO.js";import yaml from"js-yaml";var subclassCodec={parse(doc){return parseSubclass(doc.body)},serialize(entity){return yaml.dump(entity,{lineWidth:-1,sortKeys:false})}};export{subclassCodec};
@@ -1 +1 @@
1
- import{optionalFeatureEntitySchema}from"./chunk-I4O2FIDT.js";import{parseYaml}from"@archivist-gg/core";function parseOptionalFeature(source){const raw=parseYaml(source,["name","slug","feature_type"]);if(!raw.success)return raw;const result=optionalFeatureEntitySchema.safeParse({edition:"2014",...raw.data});if(!result.success){return{success:false,error:`optional-feature schema validation failed: ${result.error.message}`}}return{success:true,data:result.data}}export{parseOptionalFeature};
1
+ import{optionalFeatureEntitySchema}from"./chunk-NYPH7RQN.js";import{parseYaml}from"@archivist-gg/core";function parseOptionalFeature(source){const raw=parseYaml(source,["name","slug","feature_type"]);if(!raw.success)return raw;const result=optionalFeatureEntitySchema.safeParse({edition:"2014",...raw.data});if(!result.success){return{success:false,error:`optional-feature schema validation failed: ${result.error.message}`}}return{success:true,data:result.data}}export{parseOptionalFeature};
@@ -1 +1 @@
1
- import{backgroundEntitySchema}from"./chunk-N3RYJ7RE.js";import{parseYaml}from"@archivist-gg/core";function parseBackground(source){const raw=parseYaml(source,["name","slug"]);if(!raw.success)return raw;const result=backgroundEntitySchema.safeParse({edition:"2014",...raw.data});if(!result.success){return{success:false,error:`background schema validation failed: ${result.error.message}`}}return{success:true,data:result.data}}export{parseBackground};
1
+ import{backgroundEntitySchema}from"./chunk-L2DXF7YS.js";import{parseYaml}from"@archivist-gg/core";function parseBackground(source){const raw=parseYaml(source,["name","slug"]);if(!raw.success)return raw;const result=backgroundEntitySchema.safeParse({edition:"2014",...raw.data});if(!result.success){return{success:false,error:`background schema validation failed: ${result.error.message}`}}return{success:true,data:result.data}}export{parseBackground};