From 8431be0509cbb43247ef77794c42816bf83ecd10 Mon Sep 17 00:00:00 2001 From: Russell Larkin Date: Tue, 11 Jun 2024 13:54:09 +0100 Subject: [PATCH] #95, #97, Include sourcemap - #95: Make buildActions and buildActivations public. - #97: Fix 'lablel' error. - Include sourcemap. --- .github/workflows/main.yml | 2 +- rollup.config.js | 3 +- scripts/action-handler.js | 68 +++++++++++++---------- scripts/token-action-hud-dnd5e.min.js | 3 +- scripts/token-action-hud-dnd5e.min.js.map | 1 + 5 files changed, 44 insertions(+), 33 deletions(-) create mode 100644 scripts/token-action-hud-dnd5e.min.js.map diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 299be83..4e4e016 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -38,7 +38,7 @@ jobs: # Create a "module.zip" archive containing all the module's required files. # If you have other directories or files that will need to be added to # your packaged module, add them here. - - run: zip -r ./module.zip module.json readme.md LICENSE icons/ languages/ scripts/token-action-hud-dnd5e.min.js styles/ + - run: zip -r ./module.zip module.json readme.md LICENSE icons/ languages/ scripts/token-action-hud-dnd5e.min.js* styles/ # Update the GitHub release with the manifest and module archive files. - name: Update Release with Files diff --git a/rollup.config.js b/rollup.config.js index 8f2ba38..5cb49ef 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -13,7 +13,8 @@ export default [ }, output: { format: 'esm', - file: 'scripts/token-action-hud-dnd5e.min.js' + file: 'scripts/token-action-hud-dnd5e.min.js', + sourcemap: true }, plugins: [ terser({ keep_classnames: true, keep_fnames: true }), diff --git a/scripts/action-handler.js b/scripts/action-handler.js index 70030e8..3e75841 100644 --- a/scripts/action-handler.js +++ b/scripts/action-handler.js @@ -252,12 +252,13 @@ Hooks.once('tokenActionHudCoreApiReady', async (coreModule) => { /** * Build activations - * @param {array} items The items - * @param {object} groupData The group data - * @param {string} actionType The action type + * @public + * @param {object} data groupData, actionData, actionType */ - async #buildActivations (items, groupData, actionType = 'item') { - // Create map of items according to activation type + async buildActivations (data) { + const { groupData, actionData, actionType = 'item' } = data + + // Create map of items according to activation type const activationItems = new Map() // Create activation type mappings @@ -274,7 +275,7 @@ Hooks.once('tokenActionHudCoreApiReady', async (coreModule) => { } // Loop through items - for (const [key, value] of items) { + for (const [key, value] of actionData) { const activationType = value.system?.activation?.type const activationTypeOther = (Object.keys(activationTypeMappings).includes(activationType)) ? activationType : 'other' const groupId = activationTypeMappings[activationTypeOther] @@ -304,8 +305,10 @@ Hooks.once('tokenActionHudCoreApiReady', async (coreModule) => { this.addGroupInfo(groupDataClone) } + const actionData = activationItems.get(activationGroupId) + // Build actions - await this.#buildActions(activationItems.get(activationGroupId), groupDataClone, actionType) + await this.buildActions({ groupData: groupDataClone, actionData, actionType }) } } @@ -568,9 +571,9 @@ Hooks.once('tokenActionHudCoreApiReady', async (coreModule) => { await Promise.all([ // Build passive effects - this.#buildActions(passiveEffects, { id: 'passive-effects', type: 'system' }, actionType), + this.buildActions({ groupData: { id: 'passive-effects', type: 'system' }, actionData: passiveEffects, actionType }), // Build temporary effects - this.#buildActions(temporaryEffects, { id: 'temporary-effects', type: 'system' }, actionType) + this.buildActions({ groupData: { id: 'temporary-effects', type: 'system' }, actionData: temporaryEffects, actionType }) ]) } @@ -707,13 +710,14 @@ Hooks.once('tokenActionHudCoreApiReady', async (coreModule) => { type: 'system' } - const features = featuresMap.get(groupId) + const actionData = featuresMap.get(groupId) + const data = { groupData, actionData, actionType } // Build actions - await this.#buildActions(features, groupData, actionType) + await this.buildActions(data) // Build activations - if (groupNameMappings[groupId]) await this.#buildActivations(features, groupData, actionType) + if (groupNameMappings[groupId]) await this.buildActivations(data) } } @@ -798,14 +802,15 @@ Hooks.once('tokenActionHudCoreApiReady', async (coreModule) => { type: 'system' } - const inventory = inventoryMap.get(groupId) + const actionData = inventoryMap.get(groupId) + const data = { groupData, actionData } // Build actions - await this.#buildActions(inventory, groupData) + await this.buildActions(data) // Build activations if (this.activationgroupIds) { - await this.#buildActivations(inventory, groupData) + await this.buildActivations(data) } } } @@ -1059,13 +1064,14 @@ Hooks.once('tokenActionHudCoreApiReady', async (coreModule) => { // Add spell slot info to group this.addGroupInfo(groupData) - const spells = spellsMap.get(groupId) + const actionData = spellsMap.get(groupId) + const data = { groupData, actionData, actionType } // Build actions - await this.#buildActions(spells, groupData, actionType) + await this.buildActions(data) // Build activations - if (this.activationgroupIds) { await this.#buildActivations(spells, groupData, actionType) } + if (this.activationgroupIds) { await this.buildActivations(data) } } } @@ -1122,21 +1128,22 @@ Hooks.once('tokenActionHudCoreApiReady', async (coreModule) => { /** * Build actions - * @private - * @param {object} items - * @param {object} groupData - * @param {string} actionType + * @public + * @param {object} data actionData, groupData, actionType + * @param {object} options */ - async #buildActions (items, groupData, actionType = 'item') { - // Exit if there are no items - if (items.size === 0) return + async buildActions (data, options) { + const { actionData, groupData, actionType } = data + + // Exit if there is no action data + if (actionData.size === 0) return // Exit if there is no groupId const groupId = (typeof groupData === 'string' ? groupData : groupData?.id) if (!groupId) return // Get actions - const actions = await Promise.all([...items].map(async item => await this.#getAction(actionType, item[1]))) + const actions = await Promise.all([...actionData].map(async item => await this.#getAction(actionType, item[1]))) // Add actions to action list this.addActions(actions, groupData) @@ -1147,15 +1154,16 @@ Hooks.once('tokenActionHudCoreApiReady', async (coreModule) => { * @private * @param {string} actionType * @param {object} entity + * @param {object} options * @returns {object} */ - async #getAction (actionType, entity) { + async #getAction (actionType = 'item', entity) { const id = entity.id ?? entity._id let name = entity?.name ?? entity?.label if ( entity?.system?.recharge && - !entity?.system?.recharge?.charged && - entity?.system?.recharge?.value + !entity?.system?.recharge?.charged && + entity?.system?.recharge?.value ) { name += ` (${coreModule.api.Utils.i18n('DND5E.Recharge')})` } @@ -1361,7 +1369,7 @@ Hooks.once('tokenActionHudCoreApiReady', async (coreModule) => { if (uses?.per && (consumeName || uses?.prompt) && (uses.value > 0 || uses.max > 0)) { const of = coreModule.api.Utils.i18n('DND5E.of') const per = uses.per === 'charges' ? '' : ` ${coreModule.api.Utils.i18n('DND5E.per')}` - const period = CONFIG.DND5E.limitedUsePeriods[uses.per].label + const period = CONFIG.DND5E.limitedUsePeriods[uses.per]?.label ?? uses.per const amount = consumeAmount !== undefined ? consumeAmount : uses.amount const text = `${amount > 1 ? `${amount} ${of} ` : ''}${uses.value ?? '0'}${uses.max > 0 ? `/${uses.max}` : ''}` const title = `${text}${per} ${period}${consumeName ? ` (${of} ${consumeName})` : ''}` diff --git a/scripts/token-action-hud-dnd5e.min.js b/scripts/token-action-hud-dnd5e.min.js index b450ce1..52a296d 100644 --- a/scripts/token-action-hud-dnd5e.min.js +++ b/scripts/token-action-hud-dnd5e.min.js @@ -1 +1,2 @@ -const e={ID:"token-action-hud-dnd5e"},t={ID:"token-action-hud-core"},s="1.5",i={ability:"DND5E.Ability",check:"tokenActionHud.dnd5e.check",condition:"tokenActionHud.dnd5e.condition",counter:"tokenActionHud.dnd5e.counter",effect:"DND5E.Effect",exhaustion:"DND5E.Exhaustion",feature:"ITEM.TypeFeat",item:"tokenActionHud.dnd5e.item",save:"DND5E.ActionSave",skill:"tokenActionHud.dnd5e.skill",spell:"ITEM.TypeSpell",utility:"DND5E.ActionUtil"},n={bonus:"fas fa-plus",crew:"fas fa-users",day:"fas fa-hourglass-end",hour:"fas fa-hourglass-half",lair:"fas fa-home",minute:"fas fa-hourglass-start",legendary:"fas fas fa-dragon",reaction:"fas fa-bolt",special:"fas fa-star"},a="systems/dnd5e/icons/svg/statuses/concentrating.svg",l={blind:{uuid:"Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.0b8N4FymGGfbZGpJ"},blinded:{uuid:"Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.0b8N4FymGGfbZGpJ"},"Convenient Effect: Blinded":{uuid:"Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.0b8N4FymGGfbZGpJ"},charmed:{uuid:"Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.zZaEBrKkr66OWJvD"},"Convenient Effect: Charmed":{uuid:"Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.zZaEBrKkr66OWJvD"},deaf:{uuid:"Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.6G8JSjhn701cBITY"},deafened:{uuid:"Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.6G8JSjhn701cBITY"},"Convenient Effect: Deafened":{uuid:"Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.6G8JSjhn701cBITY"},fear:{uuid:"Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.oreoyaFKnvZCrgij"},"Convenient Effect: Frightened":{uuid:"Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.oreoyaFKnvZCrgij"},frightened:{uuid:"Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.oreoyaFKnvZCrgij"},grappled:{uuid:"Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.gYDAhd02ryUmtwZn"},"Convenient Effect: Grappled":{uuid:"Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.gYDAhd02ryUmtwZn"},incapacitated:{uuid:"Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.TpkZgLfxCmSndmpb"},"Convenient Effect: Incapacitated":{uuid:"Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.TpkZgLfxCmSndmpb"},invisible:{uuid:"Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.3UU5GCTVeRDbZy9u"},"Convenient Effect: Invisible":{uuid:"Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.3UU5GCTVeRDbZy9u"},paralysis:{uuid:"Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.xnSV5hLJIMaTABXP"},paralyzed:{uuid:"Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.xnSV5hLJIMaTABXP"},"Convenient Effect: Paralyzed":{uuid:"Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.xnSV5hLJIMaTABXP"},petrified:{uuid:"Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.xaNDaW6NwQTgHSmi"},"Convenient Effect: Petrified":{uuid:"Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.xaNDaW6NwQTgHSmi"},poison:{uuid:"Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.lq3TRI6ZlED8ABMx"},poisoned:{uuid:"Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.lq3TRI6ZlED8ABMx"},"Convenient Effect: Poisoned":{uuid:"Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.lq3TRI6ZlED8ABMx"},prone:{uuid:"Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.y0TkcdyoZlOTmAFT"},"Convenient Effect: Prone":{uuid:"Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.y0TkcdyoZlOTmAFT"},restrain:{uuid:"Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.cSVcyZyNe2iG1fIc"},restrained:{uuid:"Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.cSVcyZyNe2iG1fIc"},"Convenient Effect: Restrained":{uuid:"Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.cSVcyZyNe2iG1fIc"},stun:{uuid:"Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.ZyZMUwA2rboh4ObS"},stunned:{uuid:"Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.ZyZMUwA2rboh4ObS"},"Convenient Effect: Stunned":{uuid:"Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.ZyZMUwA2rboh4ObS"},unconscious:{uuid:"Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.UWw13ISmMxDzmwbd"},"Convenient Effect: Unconscious":{uuid:"Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.UWw13ISmMxDzmwbd"},exhaustion:{uuid:"Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.cspWveykstnu3Zcv"},"Convenient Effect: Exhaustion 1":{uuid:"Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.cspWveykstnu3Zcv"},"Convenient Effect: Exhaustion 2":{uuid:"Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.cspWveykstnu3Zcv"},"Convenient Effect: Exhaustion 3":{uuid:"Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.cspWveykstnu3Zcv"},"Convenient Effect: Exhaustion 4":{uuid:"Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.cspWveykstnu3Zcv"},"Convenient Effect: Exhaustion 5":{uuid:"Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.cspWveykstnu3Zcv"}},o={_1stLevelSpells:{id:"1st-level-spells",name:"tokenActionHud.dnd5e.1stLevelSpells",type:"system"},_2ndLevelSpells:{id:"2nd-level-spells",name:"tokenActionHud.dnd5e.2ndLevelSpells",type:"system"},_3rdLevelSpells:{id:"3rd-level-spells",name:"tokenActionHud.dnd5e.3rdLevelSpells",type:"system"},_4thLevelSpells:{id:"4th-level-spells",name:"tokenActionHud.dnd5e.4thLevelSpells",type:"system"},_5thLevelSpells:{id:"5th-level-spells",name:"tokenActionHud.dnd5e.5thLevelSpells",type:"system"},_6thLevelSpells:{id:"6th-level-spells",name:"tokenActionHud.dnd5e.6thLevelSpells",type:"system"},_7thLevelSpells:{id:"7th-level-spells",name:"tokenActionHud.dnd5e.7thLevelSpells",type:"system"},_8thLevelSpells:{id:"8th-level-spells",name:"tokenActionHud.dnd5e.8thLevelSpells",type:"system"},_9thLevelSpells:{id:"9th-level-spells",name:"tokenActionHud.dnd5e.9thLevelSpells",type:"system"},abilities:{id:"abilities",name:"tokenActionHud.dnd5e.abilities",type:"system"},actions:{id:"actions",name:"DND5E.ActionPl",type:"system"},activeFeatures:{id:"active-features",name:"tokenActionHud.dnd5e.activeFeatures",type:"system"},artificerInfusions:{id:"artificer-infusions",name:"tokenActionHud.dnd5e.artificerInfusions",type:"system"},atWillSpells:{id:"at-will-spells",name:"tokenActionHud.dnd5e.atWillSpells",type:"system"},backgroundFeatures:{id:"background-features",name:"tokenActionHud.dnd5e.backgroundFeatures",type:"system"},bonusActions:{id:"bonus-actions",name:"tokenActionHud.dnd5e.bonusActions",type:"system"},cantrips:{id:"cantrips",name:"tokenActionHud.dnd5e.cantrips",type:"system"},channelDivinity:{id:"channel-divinity",name:"tokenActionHud.dnd5e.channelDivinity",type:"system"},checks:{id:"checks",name:"tokenActionHud.dnd5e.checks",type:"system"},classFeatures:{id:"class-features",name:"tokenActionHud.dnd5e.classFeatures",type:"system"},combat:{id:"combat",name:"tokenActionHud.combat",type:"system"},conditions:{id:"conditions",name:"tokenActionHud.dnd5e.conditions",type:"system"},consumables:{id:"consumables",name:"ITEM.TypeConsumablePl",type:"system"},containers:{id:"containers",name:"ITEM.TypeContainerPl",type:"system"},counters:{id:"counters",name:"tokenActionHud.dnd5e.counters",type:"system"},crewActions:{id:"crew-actions",name:"tokenActionHud.dnd5e.crewActions",type:"system"},defensiveTactics:{id:"defensive-tactics",name:"tokenActionHud.dnd5e.defensiveTactics",type:"system"},eldritchInvocations:{id:"eldritch-invocations",name:"tokenActionHud.dnd5e.eldritchInvocations",type:"system"},elementalDisciplines:{id:"elemental-disciplines",name:"tokenActionHud.dnd5e.elementalDisciplines",type:"system"},equipment:{id:"equipment",name:"ITEM.TypeEquipmentPl",type:"system"},equipped:{id:"equipped",name:"DND5E.Equipped",type:"system"},exhaustion:{id:"exhaustion",name:"DND5E.Exhaustion",type:"system"},feats:{id:"feats",name:"tokenActionHud.dnd5e.feats",type:"system"},fightingStyles:{id:"fighting-styles",name:"tokenActionHud.dnd5e.fightingStyles",type:"system"},huntersPrey:{id:"hunters-prey",name:"tokenActionHud.dnd5e.huntersPrey",type:"system"},innateSpells:{id:"innate-spells",name:"tokenActionHud.dnd5e.innateSpells",type:"system"},kiAbilities:{id:"ki-abilities",name:"tokenActionHud.dnd5e.kiAbilities",type:"system"},lairActions:{id:"lair-actions",name:"tokenActionHud.dnd5e.lairActions",type:"system"},legendaryActions:{id:"legendary-actions",name:"tokenActionHud.dnd5e.legendaryActions",type:"system"},loot:{id:"loot",name:"ITEM.TypeLootPl",type:"system"},maneuvers:{id:"maneuvers",name:"tokenActionHud.dnd5e.maneuvers",type:"system"},metamagicOptions:{id:"metamagic-options",name:"tokenActionHud.dnd5e.metamagicOptions",type:"system"},monsterFeatures:{id:"monster-features",name:"tokenActionHud.dnd5e.monsterFeatures",type:"system"},multiattacks:{id:"multiattacks",name:"tokenActionHud.dnd5e.multiattacks",type:"system"},otherActions:{id:"other-actions",name:"tokenActionHud.dnd5e.otherActions",type:"system"},pactBoons:{id:"pact-boons",name:"tokenActionHud.dnd5e.pactBoons",type:"system"},pactSpells:{id:"pact-spells",name:"tokenActionHud.dnd5e.pactSpells",type:"system"},passiveEffects:{id:"passive-effects",name:"DND5E.EffectPassive",type:"system"},passiveFeatures:{id:"passive-features",name:"tokenActionHud.dnd5e.passiveFeatures",type:"system"},psionicPowers:{id:"psionic-powers",name:"tokenActionHud.dnd5e.psionicPowers",type:"system"},raceFeatures:{id:"race-features",name:"tokenActionHud.dnd5e.raceFeatures",type:"system"},reactions:{id:"reactions",name:"DND5E.ReactionPl",type:"system"},rests:{id:"rests",name:"tokenActionHud.dnd5e.rests",type:"system"},runes:{id:"runes",name:"tokenActionHud.dnd5e.runes",type:"system"},saves:{id:"saves",name:"DND5E.ClassSaves",type:"system"},skills:{id:"skills",name:"tokenActionHud.dnd5e.skills",type:"system"},superiorHuntersDefense:{id:"superior-hunters-defense",name:"tokenActionHud.dnd5e.superiorHuntersDefense",type:"system"},temporaryEffects:{id:"temporary-effects",name:"DND5E.EffectTemporary",type:"system"},token:{id:"token",name:"tokenActionHud.token",type:"system"},tools:{id:"tools",name:"ITEM.TypeToolPl",type:"system"},unequipped:{id:"unequipped",name:"DND5E.Unequipped",type:"system"},utility:{id:"utility",name:"tokenActionHud.utility",type:"system"},weapons:{id:"weapons",name:"ITEM.TypeWeaponPl",type:"system"}},r="fas fa-sun",d={.5:"fas fa-adjust",1:"fas fa-check",2:"fas fa-check-double"},c={common:"tokenActionHud.dnd5e.common",uncommon:"tokenActionHud.dnd5e.uncommon",rare:"tokenActionHud.dnd5e.rare",veryRare:"tokenActionHud.dnd5e.veryRare",legendary:"tokenActionHud.dnd5e.legendary",artifact:"tokenActionHud.dnd5e.artifact"},p="fas fa-circle-r",u={ada:"DND5E.WeaponPropertiesAda",amm:"DND5E.WeaponPropertiesAmm",fin:"DND5E.WeaponPropertiesFin",fir:"DND5E.WeaponPropertiesFir",foc:"DND5E.WeaponPropertiesFoc",hvy:"DND5E.WeaponPropertiesHvy",lgt:"DND5E.WeaponPropertiesLgt",lod:"DND5E.WeaponPropertiesLod",mgc:"DND5E.WeaponPropertiesMgc",rch:"DND5E.WeaponPropertiesRch",rel:"DND5E.WeaponPropertiesRel",ret:"DND5E.WeaponPropertiesRet",sil:"DND5E.WeaponPropertiesSil",spc:"DND5E.WeaponPropertiesSpc",thr:"DND5E.WeaponPropertiesThr",two:"DND5E.WeaponPropertiesTwo",ver:"DND5E.WeaponPropertiesVer"};let m=null;Hooks.once("tokenActionHudCoreApiReady",(async e=>{const t=o;Object.values(t).forEach((t=>{t.name=e.api.Utils.i18n(t.name),t.listName=`Group: ${e.api.Utils.i18n(t.name)}`}));const s=Object.values(t);m={layout:[{nestId:"inventory",id:"inventory",name:e.api.Utils.i18n("DND5E.Inventory"),groups:[{...t.weapons,nestId:"inventory_weapons"},{...t.equipment,nestId:"inventory_equipment"},{...t.consumables,nestId:"inventory_consumables"},{...t.tools,nestId:"inventory_tools"},{...t.containers,nestId:"inventory_containers"},{...t.loot,nestId:"inventory_loot"}]},{nestId:"features",id:"features",name:e.api.Utils.i18n("DND5E.Features"),groups:[{...t.activeFeatures,nestId:"features_active-features"},{...t.passiveFeatures,nestId:"features_passive-features"}]},{nestId:"spells",id:"spells",name:e.api.Utils.i18n("ITEM.TypeSpellPl"),groups:[{...t.atWillSpells,nestId:"spells_at-will-spells"},{...t.innateSpells,nestId:"spells_innate-spells"},{...t.pactSpells,nestId:"spells_pact-spells"},{...t.cantrips,nestId:"spells_cantrips"},{...t._1stLevelSpells,nestId:"spells_1st-level-spells"},{...t._2ndLevelSpells,nestId:"spells_2nd-level-spells"},{...t._3rdLevelSpells,nestId:"spells_3rd-level-spells"},{...t._4thLevelSpells,nestId:"spells_4th-level-spells"},{...t._5thLevelSpells,nestId:"spells_5th-level-spells"},{...t._6thLevelSpells,nestId:"spells_6th-level-spells"},{...t._7thLevelSpells,nestId:"spells_7th-level-spells"},{...t._8thLevelSpells,nestId:"spells_8th-level-spells"},{...t._9thLevelSpells,nestId:"spells_9th-level-spells"}]},{nestId:"attributes",id:"attributes",name:e.api.Utils.i18n("DND5E.Attributes"),groups:[{...t.abilities,nestId:"attributes_abilities"},{...t.skills,nestId:"attributes_skills"}]},{nestId:"effects",id:"effects",name:e.api.Utils.i18n("DND5E.Effects"),groups:[{...t.temporaryEffects,nestId:"effects_temporary-effects"},{...t.passiveEffects,nestId:"effects_passive-effects"},{...t.conditions,nestId:"effects_conditions"}]},{nestId:"utility",id:"utility",name:e.api.Utils.i18n("tokenActionHud.utility"),groups:[{...t.combat,nestId:"utility_combat"},{...t.token,nestId:"utility_token"},{...t.rests,nestId:"utility_rests"},{...t.utility,nestId:"utility_utility"}]}],groups:s}}));let y=null;Hooks.once("tokenActionHudCoreApiReady",(async t=>{y=class Utils{static getSetting(s,i=null){let n=i??null;try{n=game.settings.get(e.ID,s)}catch{t.api.Logger.debug(`Setting '${s}' not found`)}return n}static async setSetting(s,i){try{i=await game.settings.set(e.ID,s,i),t.api.Logger.debug(`Setting '${s}' set to '${i}'`)}catch{t.api.Logger.debug(`Setting '${s}' not found`)}}}}));let h=null;Hooks.once("tokenActionHudCoreApiReady",(async e=>{h=class ActionHandler extends e.api.ActionHandler{actors=null;tokens=null;actorType=null;items=null;abbreviateSkills=null;displaySpellInfo=null;showItemsWithoutActivationCosts=null;showUnchargedItems=null;showUnequippedItems=null;showUnpreparedSpells=null;activationgroupIds=null;featuregroupIds=null;inventorygroupIds=null;spellgroupIds=null;featureActions=null;inventoryActions=null;spellActions=null;systemVersion=game.dnd5e.version;async buildSystemActions(t){if(this.actors=this.actor?[this.actor]:this.#e(),this.tokens=this.token?[this.token]:this.#t(),this.actorType=this.actor?.type,this.actor){let t=this.actor.items;t=this.#s(t),t=e.api.Utils.sortItemsByName(t),this.items=t}this.abbreviateSkills=y.getSetting("abbreviateSkills"),this.displaySpellInfo=y.getSetting("displaySpellInfo"),this.showItemsWithoutActivationCosts=y.getSetting("showItemsWithoutActivationCosts"),this.showUnchargedItems=y.getSetting("showUnchargedItems"),this.showUnequippedItems=y.getSetting("showUnequippedItems"),"npc"!==this.actorType||this.showUnequippedItems||(this.showUnequippedItems=y.getSetting("showUnequippedItemsNpcs")),this.showUnpreparedSpells=y.getSetting("showUnpreparedSpells"),this.activationgroupIds=["actions","bonus-actions","crew-actions","lair-actions","legendary-actions","reactions","other-actions"],this.featuregroupIds=["active-features","passive-features","background-features","class-features","feats","monster-features","race-features","artificer-infusions","channel-divinity","defensive-tactics","eldritch-invocations","elemental-disciplines","fighting-styles","hunters-prey","ki-abilities","maneuvers","metamagic-options","multiattacks","pact-boons","psionic-powers","runes","superior-hunters-defense"],this.spellgroupIds=["cantrips","1st-level-spells","2nd-level-spells","3rd-level-spells","4th-level-spells","5th-level-spells","6th-level-spells","7th-level-spells","8th-level-spells","9th-level-spells","at-will-spells","innate-spells","pact-spells"],"character"===this.actorType||"npc"===this.actorType?(this.inventorygroupIds=["equipped","consumables","containers","equipment","loot","tools","weapons","unequipped"],await this.#i()):"vehicle"===this.actorType?(this.inventorygroupIds=["consumables","equipment","tools","weapons"],await this.#n()):this.actor||await this.#a()}async#i(){await Promise.all([this.#l(),this.#o(),this.#r(),this.#d(),this.#c()]),this.#p("ability","abilities"),this.#p("check","checks"),this.#p("save","saves"),this.#u(),this.#m(),this.#y(),this.#h(),this.#f(),this.#g()}async#n(){await Promise.all([this.#l(),this.#o(),this.#r(),this.#d()]),this.#p("ability","abilities"),this.#p("check","checks"),this.#p("save","saves"),this.#u(),this.#g()}async#a(){this.#p("ability","abilities"),this.#p("check","checks"),this.#p("save","saves"),this.#u(),await this.#l(),this.#h(),this.#f(),this.#g()}#p(t,s){const n=this.actor?this.actor.system.abilities:CONFIG.DND5E.abilities;if(0===n.length)return;const a=Object.entries(n).filter((e=>0!==n[e[0]].value)).map((([a,l])=>{const o=`${t}-${a}`,r=a.charAt(0).toUpperCase()+a.slice(1),d=this.systemVersion>="2.2"?CONFIG.DND5E.abilities[a].label:CONFIG.DND5E.abilities[a],c=this.abbreviateSkills?r:d,p=`${`${e.api.Utils.i18n(i[t])}: `??""}${d}`,u=[t,a].join(this.delimiter),m="checks"!==s?this.#v(n[a].proficient):"",y="saves"!==s?l?.mod:"saves"===s?l?.save:"";return{id:o,name:c,encodedValue:u,icon1:m,info1:this.actor?{text:e.api.Utils.getModifier(y)}:null,info2:this.actor&&"abilities"===s?{text:`(${e.api.Utils.getModifier(l?.save)})`}:null,listName:p}})),l={id:s,type:"system"};this.addActions(a,l)}async#b(e,t,s="item"){const i=new Map,n={action:"actions",bonus:"bonus-actions",crew:"crew-actions",lair:"lair-actions",legendary:"legendary-actions",reaction:"reactions",reactiondamage:"reactions",reactionmanual:"reactions",other:"other-actions"};for(const[t,s]of e){const e=s.system?.activation?.type,a=n[Object.keys(n).includes(e)?e:"other"];i.has(a)||i.set(a,new Map),i.get(a).set(t,s)}for(const e of this.activationgroupIds){if(!i.has(e))continue;const n={...t,id:`${e}+${t.id}`,type:"system-derived"};["equipped","unequipped"].includes(t.id)&&(n.defaultSelected=!1);const a={id:e,type:"system"};await this.addGroup(n,a),"spell"===s&&this.addGroupInfo(n),await this.#k(i.get(e),n,s)}}#u(){const t="utility",s={initiative:{id:"initiative",name:e.api.Utils.i18n("tokenActionHud.dnd5e.rollInitiative")},endTurn:{id:"endTurn",name:e.api.Utils.i18n("tokenActionHud.endTurn")}};game.combat?.current?.tokenId!==this.token?.id&&delete s.endTurn;const n=Object.entries(s).map((s=>{const n=s[1].id,a=s[1].name,l=`${`${e.api.Utils.i18n(i[t])}: `??""}${a}`,o=[t,n].join(this.delimiter),r={};let d="";if("initiative"===s[0]&&game.combat){const t=e.api.Utils.getControlledTokens()?.map((e=>e.id)),s=game.combat.combatants.filter((e=>t.includes(e.tokenId)));if(1===s.length){const e=s[0].initiative;r.class="tah-spotlight",r.text=e}d=`toggle${s.length>0&&s.every((e=>e?.initiative))?" active":""}`}return{id:n,name:a,encodedValue:o,info1:r,cssClass:d,listName:l}}));this.addActions(n,{id:"combat",type:"system"})}async#l(){if(0===this.tokens?.length)return;const t="condition",s=CONFIG.statusEffects.filter((e=>""!==e.id));if(0===s.length)return;const n=await Promise.all(s.map((async s=>{const n=s.id,a=e.api.Utils.i18n(s.label)??s.name,l=`${`${e.api.Utils.i18n(i[t])}: `??""}${a}`,o=[t,n].join(this.delimiter),r=`toggle${this.actors.every((e=>game.version.startsWith("11")?e.effects.some((e=>e.statuses.some((e=>e===n))&&!e?.disabled)):e.effects.some((e=>e.flags?.core?.statusId===n&&!e?.disabled))))?" active":""}`,d=e.api.Utils.getImage(s),c=await this.#A(n,a),p=await this.#I(c);return{id:n,name:a,encodedValue:o,img:d,cssClass:r,listName:l,tooltip:p}})));this.addActions(n,{id:"conditions",type:"system"})}async#m(){if("character"!==this.actorType)return;const t="counter";let s=[];if(e.api.Utils.isModuleActive("dnd5e-custom-counters")){if("character"!==this.actorType)return;s=Object.entries(game.settings.get("dnd5e-custom-counters","characterCounters")).filter((([e,t])=>t.visible)).map((([e,t])=>(t.key=e,t)))}else s=[{name:e.api.Utils.i18n("DND5E.DeathSave"),type:"successFailure",system:!0,visible:!0,key:"death-saves"},{name:e.api.Utils.i18n("DND5E.Exhaustion"),type:"number",system:!0,visible:!0,key:"exhaustion"},{name:e.api.Utils.i18n("DND5E.Inspiration"),type:"checkbox",system:!0,visible:!0,key:"inspiration"}];const n=s.map((s=>{const n=s.key,a=s.name,l=`${`${e.api.Utils.i18n(i[t])}: `??""}${a}`,o=s.system?n:encodeURIComponent(`${n}>${s.type}`),r=[t,o].join(this.delimiter);let d="",c="",p="",u="";if(s.system)switch(n){case"exhaustion":d=this.actor.system.attributes.exhaustion>0?" active":"",c=`toggle${d}`,p=e.api.Utils.getImage("modules/token-action-hud-dnd5e/icons/exhaustion.svg"),u={text:this.actor.system.attributes.exhaustion};break;case"death-saves":p=e.api.Utils.getImage("modules/token-action-hud-dnd5e/icons/death-saves.svg"),u={text:`${this.actor.system.attributes.death.success}/${this.actor.system.attributes.death.failure}`};break;case"inspiration":d=this.actor.system.attributes.inspiration?" active":"",c=`toggle${d}`,p=e.api.Utils.getImage("modules/token-action-hud-dnd5e/icons/inspiration.svg")}else{const e=this.actor.getFlag("dnd5e-custom-counters",n);switch(s.type){case"checkbox":d=e?" active":"",c=`toggle${d}`;break;case"number":d=e>0?" active":"",c=`toggle${d}`,u={text:e};break;case"successFailure":u={text:`${e?.success??0}/${e?.failure??0}`}}}return{id:n,name:a,listName:l,encodedValue:r,cssClass:c,img:p,info1:u}}));this.addActions(n,{id:"counters",type:"system"})}async#o(){const e="effect",t=new Map;for(const e of this.actor.allApplicableEffects())t.set(e.id,e);if(0===t.size)return;const s=new Map,i=new Map;for(const[e,n]of t.entries()){if(n.isSuppressed||!1===n.parent?.system?.identified&&!game.user.isGM)continue;n.isTemporary?i.set(e,n):s.set(e,n)}await Promise.all([this.#k(s,{id:"passive-effects",type:"system"},e),this.#k(i,{id:"temporary-effects",type:"system"},e)])}#y(){if(0===this.actors.length)return;if(!this.actors.every((e=>"character"===e.type)))return;const t="exhaustion",s="exhaustion",n=e.api.Utils.i18n("DND5E.Exhaustion"),a=`${`${e.api.Utils.i18n(i[t])}: `??""}${n}`,l=[t,s].join(this.delimiter),o=e.api.Utils.getImage("modules/token-action-hud-dnd5e/icons/exhaustion.svg"),r={text:this.actor.system.attributes.exhaustion};let d="";d=`toggle${this.actor.system.attributes.exhaustion>0?" active":""}`;const c=[{cssClass:d,id:s,name:n,encodedValue:l,img:o,info1:r,listName:a}];this.addActions(c,{id:"exhaustion",type:"system"})}async#r(){const t="feature",s=new Map;for(const[e,t]of this.items){"feat"===t.type&&s.set(e,t)}if(0===s.size)return;const i=new Map,n=[{type:"background",groupId:"background-features"},{type:"class",groupId:"class-features"},{type:"monster",groupId:"monster-features"},{type:"race",groupId:"race-features"},{type:"feats",groupId:"feats"}],a=[{type:"artificerInfusion",groupId:"artificer-infusions"},{type:"channelDivinity",groupId:"channel-divinity"},{type:"defensiveTactic",groupId:"defensive-tactics"},{type:"eldritchInvocation",groupId:"eldritch-invocations"},{type:"elementalDiscipline",groupId:"elemental-disciplines"},{type:"fightingStyle",groupId:"fighting-styles"},{type:"huntersPrey",groupId:"hunters-prey"},{type:"ki",groupId:"ki-abilities"},{type:"maneuver",groupId:"maneuvers"},{type:"metamagic",groupId:"metamagic-options"},{type:"multiattack",groupId:"multiattacks"},{type:"pact",groupId:"pact-boons"},{type:"psionicPower",groupId:"psionic-powers"},{type:"rune",groupId:"runes"},{type:"superiorHuntersDefense",groupId:"superior-hunters-defense"}];for(const[e,t]of s){const s=t.system.activation?.type,l=t.system.type.value,o=t.system.type?.subtype;s&&(i.has("active-features")||i.set("active-features",new Map),i.get("active-features").set(e,t)),s&&""!==s||(i.has("passive-features")||i.set("passive-features",new Map),i.get("passive-features").set(e,t));for(const s of n){const n=s.groupId;s.type===l&&(i.has(n)||i.set(n,new Map),i.get(n).set(e,t))}for(const s of a){const n=s.groupId;o&&s.type===o&&(i.has(n)||i.set(n,new Map),i.get(n).set(e,t))}}const l={"active-features":e.api.Utils.i18n("tokenActionHud.dnd5e.activeFeatures"),"passive-features":e.api.Utils.i18n("tokenActionHud.dnd5e.passiveFeatures")};for(const e of this.featuregroupIds){if(!i.has(e))continue;const s={id:e,name:l[e]??"",type:"system"},n=i.get(e);await this.#k(n,s,t),l[e]&&await this.#b(n,s,t)}}async#d(){if(0===this.items.size)return;const t=new Map;for(const[e,s]of this.items){const i=s.system.equipped,n=s.system?.quantity>0,a=this.#E(s),l=this.#w(s),o=this.#D(s),r=s.type;n&&a&&(i&&(t.has("equipped")||t.set("equipped",new Map),t.get("equipped").set(e,s)),i||(t.has("unequipped")||t.set("unequipped",new Map),t.get("unequipped").set(e,s)),l&&"consumable"===r&&(t.has("consumables")||t.set("consumables",new Map),t.get("consumables").set(e,s)),o&&("container"===r&&(t.has("containers")||t.set("containers",new Map),t.get("containers").set(e,s)),"equipment"===r&&(t.has("equipment")||t.set("equipment",new Map),t.get("equipment").set(e,s)),"loot"===r&&(t.has("loot")||t.set("loot",new Map),t.get("loot").set(e,s)),"tool"===r&&(t.has("tools")||t.set("tools",new Map),t.get("tools").set(e,s)),"weapon"===r&&(t.has("weapons")||t.set("weapons",new Map),t.get("weapons").set(e,s))))}const s={equipped:e.api.Utils.i18n("DND5E.Equipped"),unequipped:e.api.Utils.i18n("DND5E.Unequipped"),consumables:e.api.Utils.i18n("ITEM.TypeConsumablePl"),containers:e.api.Utils.i18n("ITEM.TypeContainerPl"),equipment:e.api.Utils.i18n("ITEM.TypeEquipmentPl"),loot:e.api.Utils.i18n("ITEM.TypeLootPl"),tools:e.api.Utils.i18n("ITEM.TypeToolPl"),weapons:e.api.Utils.i18n("ITEM.TypeWeaponPl")};for(const e of this.inventorygroupIds){if(!t.has(e))continue;const i={id:e,name:s[e],type:"system"},n=t.get(e);await this.#k(n,i),this.activationgroupIds&&await this.#b(n,i)}}#h(){if(0===this.actors.length)return;if(!this.actors.every((e=>"character"===e.type)))return;const t="utility",s={shortRest:{name:e.api.Utils.i18n("DND5E.ShortRest")},longRest:{name:e.api.Utils.i18n("DND5E.LongRest")}},n=Object.entries(s).map((s=>{const n=s[0],a=s[1].name,l=`${`${e.api.Utils.i18n(i[t])}: `??""}${a}`,o=[t,n].join(this.delimiter);return{id:n,name:a,encodedValue:o,listName:l}}));this.addActions(n,{id:"rests",type:"system"})}#f(){const t="skill",s=this.actor?this.actor.system.skills:CONFIG.DND5E.skills;if(0===s.length)return;const n=Object.entries(s).map((n=>{try{const a=n[0],l=a.charAt(0).toUpperCase()+a.slice(1),o=this.abbreviateSkills?l:CONFIG.DND5E.skills[a].label,r=`${`${e.api.Utils.i18n(i[t])}: `??""}${CONFIG.DND5E.skills[a].label}`,d=[t,a].join(this.delimiter),c=this.#v(s[a].value),p=s[a].total;return{id:a,name:o,encodedValue:d,icon1:c,info1:this.actor?{text:p||0===p?`${p>=0?"+":""}${p}`:""}:"",listName:r}}catch(t){return e.api.Logger.error(n),null}})).filter((e=>!!e));this.addActions(n,{id:"skills",type:"system"})}async#c(){const t="spell",s=new Map;for(const[e,t]of this.items){if("spell"===t.type){const i=this.#w(t),n=this.#S(t);if(i&&n){switch(t.system.preparation.mode){case"atwill":s.has("at-will-spells")||s.set("at-will-spells",new Map),s.get("at-will-spells").set(e,t);break;case"innate":s.has("innate-spells")||s.set("innate-spells",new Map),s.get("innate-spells").set(e,t);break;case"pact":s.has("pact-spells")||s.set("pact-spells",new Map),s.get("pact-spells").set(e,t);break;default:switch(t.system.level){case 0:s.has("cantrips")||s.set("cantrips",new Map),s.get("cantrips").set(e,t);break;case 1:s.has("1st-level-spells")||s.set("1st-level-spells",new Map),s.get("1st-level-spells").set(e,t);break;case 2:s.has("2nd-level-spells")||s.set("2nd-level-spells",new Map),s.get("2nd-level-spells").set(e,t);break;case 3:s.has("3rd-level-spells")||s.set("3rd-level-spells",new Map),s.get("3rd-level-spells").set(e,t);break;case 4:s.has("4th-level-spells")||s.set("4th-level-spells",new Map),s.get("4th-level-spells").set(e,t);break;case 5:s.has("5th-level-spells")||s.set("5th-level-spells",new Map),s.get("5th-level-spells").set(e,t);break;case 6:s.has("6th-level-spells")||s.set("6th-level-spells",new Map),s.get("6th-level-spells").set(e,t);break;case 7:s.has("7th-level-spells")||s.set("7th-level-spells",new Map),s.get("7th-level-spells").set(e,t);break;case 8:s.has("8th-level-spells")||s.set("8th-level-spells",new Map),s.get("8th-level-spells").set(e,t);break;case 9:s.has("9th-level-spells")||s.set("9th-level-spells",new Map),s.get("9th-level-spells").set(e,t)}}}}}const i=Object.entries(this.actor.system.spells).reverse();let n=null;const a=[];let l=this.showUnchargedItems,o=this.showUnchargedItems;for(const[e,t]of i){const s=t.value>0,i=t.max>0,r=t.level>0;"pact"===e&&(!o&&s&&i&&r&&(o=!0),r||(o=!1),t.slotAvailable=o,n=[e,t]),e.startsWith("spell")&&"spell0"!==e?(!l&&s&&i&&(l=!0),t.slotAvailable=l,a.push([e,t])):s&&(t.slotsAvailable=!0,a.push(e,t))}if(n[1].slotAvailable){const e=a.findIndex((e=>e[0]==="spell"+n[1].level));a[e][1].slotsAvailable=!0}const r={"1st-level-spells":{spellMode:1,name:e.api.Utils.i18n("tokenActionHud.dnd5e.1stLevelSpells")},"2nd-level-spells":{spellMode:2,name:e.api.Utils.i18n("tokenActionHud.dnd5e.2ndLevelSpells")},"3rd-level-spells":{spellMode:3,name:e.api.Utils.i18n("tokenActionHud.dnd5e.3rdLevelSpells")},"4th-level-spells":{spellMode:4,name:e.api.Utils.i18n("tokenActionHud.dnd5e.4thLevelSpells")},"5th-level-spells":{spellMode:5,name:e.api.Utils.i18n("tokenActionHud.dnd5e.5thLevelSpells")},"6th-level-spells":{spellMode:6,name:e.api.Utils.i18n("tokenActionHud.dnd5e.6thLevelSpells")},"7th-level-spells":{spellMode:7,name:e.api.Utils.i18n("tokenActionHud.dnd5e.7thLevelSpells")},"8th-level-spells":{spellMode:8,name:e.api.Utils.i18n("tokenActionHud.dnd5e.8thLevelSpells")},"9th-level-spells":{spellMode:9,name:e.api.Utils.i18n("tokenActionHud.dnd5e.9thLevelSpells")},"at-will-spells":{spellMode:"atwill",name:e.api.Utils.i18n("tokenActionHud.dnd5e.atWillSpells")},cantrips:{spellMode:0,name:e.api.Utils.i18n("tokenActionHud.dnd5e.cantrips")},"innate-spells":{spellMode:"innate",name:e.api.Utils.i18n("tokenActionHud.dnd5e.innateSpells")},"pact-spells":{spellMode:"pact",name:e.api.Utils.i18n("tokenActionHud.dnd5e.pactSpells")}},d=["1","2","3","4","5","6","7","8","9","pact"];for(const e of this.spellgroupIds){const i=r[e].spellMode,l=r[e].name;if(!s.has(e))continue;const o="pact"===i?n[1]:a.find((e=>e[0]===`spell${i}`))?.[1],c=o?.value,p=o?.max,u=o?.slotAvailable;if(!u&&d.includes(i))continue;const m={};m.info1={class:"tah-spotlight",text:p>=0?`${c}/${p}`:""};const y={id:e,name:l,type:"system",info:m};this.addGroupInfo(y);const h=s.get(e);await this.#k(h,y,t),this.activationgroupIds&&await this.#b(h,y,t)}}#g(){if(0===this.actors.length)return;if(!this.actors.every((e=>"character"===e.type)))return;const t="utility",s={deathSave:{name:e.api.Utils.i18n("DND5E.DeathSave")},inspiration:{name:e.api.Utils.i18n("DND5E.Inspiration")}};(!this.actor||this.actor.system.attributes.hp.value>0)&&delete s.deathSave;const n=Object.entries(s).map((s=>{const n=s[0],a=s[1].name,l=`${`${e.api.Utils.i18n(i[t])}: `??""}${a}`,o=[t,n].join(this.delimiter);let r="";if("inspiration"===s[0]){r=`toggle${this.actors.every((e=>e.system.attributes?.inspiration))?" active":""}`}return{id:n,name:a,encodedValue:o,cssClass:r,listName:l}}));this.addActions(n,{id:"utility",type:"system"})}async#k(e,t,s="item"){if(0===e.size)return;if(!("string"==typeof t?t:t?.id))return;const i=await Promise.all([...e].map((async e=>await this.#C(s,e[1]))));this.addActions(i,t)}async#C(t,s){const n=s.id??s._id;let a=s?.name??s?.label;s?.system?.recharge&&!s?.system?.recharge?.charged&&s?.system?.recharge?.value&&(a+=` (${e.api.Utils.i18n("DND5E.Recharge")})`);const l=`${`${e.api.Utils.i18n(i[t])}: `??""}${a}`;let o="";if(Object.hasOwn(s,"disabled")){o=`toggle${s.disabled?"":" active"}`}const r=[t,n].join(this.delimiter),d=e.api.Utils.getImage(s),c=this.#U(s?.system?.activation?.type),p=this.#H(s),u=this.#T(s),m=this.#$(s),y=m?.info1,h=m?.info2,f=m?.info3,g=await this.#N(s);return{id:n,name:a,encodedValue:r,cssClass:o,img:d,icon1:c,icon2:p,icon3:u,info1:y,info2:h,info3:f,listName:l,tooltip:await this.#I(g)}}#E(e){if(this.showItemsWithoutActivationCosts)return!0;const t=Object.keys(CONFIG.DND5E.abilityActivationTypes).filter((e=>"none"!==e)),s=e.system.activation,i=s?.type;return!!(s&&t.includes(i)||"tool"===e.type)}#D(e){const t=e.type;if(this.showUnequippedItems&&!["consumable","spell","feat"].includes(t))return!0;return!(!e.system.equipped||"consumable"===t)}#w(e){if(this.showUnchargedItems)return!0;return!!e.system.uses}#S(e){if("character"!==this.actorType&&this.showUnequippedItems)return!0;const t=e.system.preparation.prepared;if(this.showUnpreparedSpells)return!0;const s=e.system.level,i=Object.keys(CONFIG.DND5E.spellPreparationModes).filter((e=>"prepared"!==e)),n=e.system.preparation.mode;return!(0!==s&&!i.includes(n)&&!t)}#$(e){return{info1:"spell"===e.type?this.#P(e):this.#M(e),info2:this.#J(e),info3:this.#x(e)}}#P(t){if(!this.displaySpellInfo)return null;const s={text:""},i=[],n=t.system?.properties;return[["vocal","DND5E.ComponentVerbal"],["somatic","DND5E.ComponentSomatic"],["material","DND5E.ComponentMaterial"]].forEach((t=>{n?.has(t[0])&&(i.push(e.api.Utils.i18n(t[1])),s.text+=e.api.Utils.i18n(`${t[1]}Abbr`))})),n?.has("ritual")&&(i.push(`[${e.api.Utils.i18n("DND5E.Ritual")}]`),s.text+=` [${e.api.Utils.i18n("DND5E.RitualAbbr")}]`),s.title=i.join(", "),s}#e(){const t=["character","npc"],s=e.api.Utils.getControlledTokens()?.filter((e=>e.actor)).map((e=>e.actor));return s.every((e=>t.includes(e.type)))?s:[]}#t(){const t=["character","npc"],s=e.api.Utils.getControlledTokens(),i=s?.filter((e=>e.actor)).map((e=>e.actor));return i.every((e=>t.includes(e.type)))?s:[]}#M(t){const s=t?.system?.quantity??0;return{text:s>1?s:"",title:`${e.api.Utils.i18n("DND5E.Quantity")}: ${s}`}}#J(t,s,i){const n=t?.system?.uses;if(n?.per&&(n.value>0||n.max>0)){const t=e.api.Utils.i18n("DND5E.of"),a=e.api.Utils.i18n("DND5E.per"),l=CONFIG.DND5E.limitedUsePeriods[`${n.per}`].label,o=void 0!==i?i:n.amount,r=`${o>1?`${o} ${t} `:""}${n.value??"0"}${n.max>0?`/${n.max}`:""}`;return{text:r,title:`${n.amount>1?`/${n.max}`:""}${r} ${a} ${l}${s?` (${t} ${s})`:""}`}}return{}}#x(t){const s=t?.system?.consume?.target,i=t?.system?.consume?.type,n=t?.system?.consume?.amount;if(!s||s===t.id)return{};if("attribute"===i){const e=s.substr(0,s.lastIndexOf(".")),t=foundry.utils.getProperty(this.actor.system,e);if(t){const e=`${t.value??"0"}${t.max?`/${t.max}`:""}`;return{text:e,title:`${e} ${t.label??""}`}}}else{const t=this.items.get(s);if("charges"===i)return this.#J(t,t.name,n);if(t?.system?.quantity){const s=`${n>1?`${n} ${e.api.Utils.i18n("DND5E.of")} `:""}${t.system.quantity}`;return{text:s,title:`${s} ${t.name}`}}}return{}}#s(e){if(y.getSetting("showSlowActions"))return e;const t=["minute","hour","day"],s=new Map;for(const[i,n]of e.entries()){const e=n.system?.activation?.type;t.includes(e)||s.set(i,n)}return s}#v(e){const t=CONFIG.DND5E.proficiencyLevels[e]??"",s=d[e];if(s)return``}#U(e){const t=CONFIG.DND5E.abilityActivationTypes[e]??"",s=n[e];if(s)return``}#T(t){if("spell"!==t?.type||!this.displaySpellInfo||!t.system?.properties?.has("concentration"))return null;return``}#H(t){if("spell"!==t?.type||!this.showUnpreparedSpells)return null;const s=t.system.level,i=t.system.preparation.mode,n=t.system.preparation.prepared,a=n?"fas fa-sun":"fas fa-sun tah-icon-disabled",l="always"===i?e.api.Utils.i18n("DND5E.SpellPrepAlways"):n?e.api.Utils.i18n("DND5E.SpellPrepared"):e.api.Utils.i18n("DND5E.SpellUnprepared");return"prepared"!==i&&"always"!==i||0===s?null:``}async#N(e){if("none"===this.tooltipsSetting)return"";const t=e?.name??"";if("nameOnly"===this.tooltipsSetting)return t;const s=!1===e.system?.identified,i="string"==typeof e?.system?.description?e?.system?.description:(s?e?.system?.unidentified?.description:e?.system?.description?.value)??"";let n,a,l,o;return s||(n=e?.modifiers??null,a=[...e.system?.chatProperties??[],...e.system?.equippableItemCardProperties??[],...e.system?.activatedEffectCardProperties??[]].filter((e=>e)),l=s?null:e?.rarity??null,o="weapon"===e?.type?this.#Q(e?.system?.properties):null),{name:t,description:i,modifiers:n,properties:a,rarity:l,traits:o}}async#A(e,t){if("none"===this.tooltipsSetting)return"";if("nameOnly"===this.tooltipsSetting)return t;return{name:t,description:(l[e]&&l[e]?.uuid?await fromUuid(l[e].uuid):null)?.text?.content??""}}async#I(t){if("none"===this.tooltipsSetting)return"";if("string"==typeof t)return t;const s=e.api.Utils.i18n(t.name);if("nameOnly"===this.tooltipsSetting)return s;const i=`

${s}

`,n=t?.descriptionLocalised??await TextEditor.enrichHTML(e.api.Utils.i18n(t?.description??""),{async:!0}),a=t?.rarity?`${e.api.Utils.i18n(c[t.rarity])}`:"",l=t?.properties?`
${t.properties.map((t=>`${e.api.Utils.i18n(t)}`)).join("")}
`:"",o=t?.traits?t.traits.map((t=>`${e.api.Utils.i18n(t.label??t)}`)).join(""):"",r=t?.traits2?t.traits2.map((t=>`${e.api.Utils.i18n(t.label??t)}`)).join(""):"",d=t?.traitsAlt?t.traitsAlt.map((t=>`${e.api.Utils.i18n(t.label)}`)).join(""):"",p=t?.modifiers?`
${t.modifiers.filter((e=>e.enabled)).map((t=>`${e.api.Utils.i18n(t.label)} ${`${t.modifier>=0?"+":""}${t.modifier??""}`}`)).join("")}
`:"",u=[a,o,r,d].join(""),m=u?`
${u}
`:"";return n||m||p?`
${i}${m||p?`
${m}${p}
`:""}${n}${l}
`:s}#Q(t){return t?Object.entries(t).filter((([e,t])=>t&&u[e])).map((([t,s])=>e.api.Utils.i18n(u[t]))):null}}}));let f=null;Hooks.once("tokenActionHudCoreApiReady",(async e=>{f=class MagicItemActionHandlerExtender extends e.api.ActionHandlerExtender{constructor(e){super(),this.actionHandler=e,this.actor=null}async extendActionHandler(){if(this.actor=this.actionHandler.actor,!this.actor)return;const t=await MagicItems.actor(this.actor.id);if(!t)return;const s=t.items??[];if(0===s.length)return;const i={id:"magic-items",type:"system"};s.forEach((t=>{if(t.attuned&&!this._isItemAttuned(t))return;if(t.equipped&&!this._isItemEquipped(t))return;const s={id:`magic-items_${t.id}`,name:t.name,type:"system-derived",info1:`${t.uses}/${t.charges}`};this.actionHandler.addGroup(s,i);const n=t.ownedEntries.map((s=>{const i=s.item,n=i.id;return{id:n,name:i.name,encodedValue:["magicItem",`${t.id}>${n}`].join("|"),img:e.api.Utils.getImage(i),info1:i.consumption,info2:i.baseLevel?`${e.api.Utils.i18n("DND5E.AbbreviationLevel")} ${i.baseLevel}`:"",selected:!0}}));this.actionHandler.addActions(n,s)}))}_isItemEquipped(e){return e.item.system.equipped}_isItemAttuned(e){return e.item.system.attunment!==(CONFIG.DND5E.attunementTypes?.REQUIRED??1)}}}));let g=null;Hooks.once("tokenActionHudCoreApiReady",(async e=>{g=class RollHandler extends e.api.RollHandler{async handleActionClick(t,s){const[i,n]=s.split("|");if(this.actor)await this.#j(t,i,this.actor,this.token,n);else for(const s of e.api.Utils.getControlledTokens()){const e=s.actor;await this.#j(t,i,e,s,n)}}async#j(e,t,s,i,n){switch(t){case"ability":this.#B(e,s,n);break;case"check":this.#q(e,s,n);break;case"save":this.#F(e,s,n);break;case"condition":if(!i)return;await this.#_(e,s,i,n);break;case"counter":await this.#L(e,s,n);break;case"effect":await this.#O(e,s,n);break;case"exhaustion":await this.#R(e,s);break;case"feature":case"item":case"spell":case"weapon":this.isRenderItem()?this.renderItem(s,n):this.#W(e,s,n);break;case"magicItem":await this.#G(s,n);break;case"skill":this.#Z(e,s,n);break;case"utility":await this.#z(e,s,i,n)}}async#L(e,t,s){switch(s){case"death-saves":this.#V(e,t);break;case"exhaustion":await this.#R(e,t);break;case"inspiration":await this.#K(t);break;default:await this.#Y(e,t,s)}}async#R(e,t){const s=this.isRightClick(e),i=t.system.attributes.exhaustion,n=s?i-1:i+1;n>=0&&t.update({"system.attributes.exhaustion":n})}async#K(e){const t=!e.system.attributes.inspiration;e.update({"system.attributes.inspiration":t})}async#Y(t,s,i){if(!e.api.Utils.isModuleActive("dnd5e-custom-counters"))return;const[n,a]=decodeURIComponent(i).split(">"),l=this.isRightClick(t),o=this.isCtrl(t);let r=s.getFlag("dnd5e-custom-counters",n);switch(a){case"checkbox":await s.setFlag("dnd5e-custom-counters",n,!r);break;case"number":r=r??0,l?r>0&&await s.setFlag("dnd5e-custom-counters",n,r-1):await s.setFlag("dnd5e-custom-counters",n,r+1);break;case"successFailure":r=r??{},r.success=r?.success??0,r.failure=r?.failure??0,l?o?r?.failure>0&&await s.setFlag("dnd5e-custom-counters",`${n}.failure`,r.failure-1):r?.success>0&&await s.setFlag("dnd5e-custom-counters",`${n}.success`,r.success-1):o?await s.setFlag("dnd5e-custom-counters",`${n}.failure`,r.failure+1):await s.setFlag("dnd5e-custom-counters",`${n}.success`,r.success+1)}}#B(e,t,s){t&&t.system?.abilities&&t.rollAbility(s,{event:e})}#F(e,t,s){t&&t.system?.abilities&&t.rollAbilitySave(s,{event:e})}#q(e,t,s){t&&t.system?.abilities&&t.rollAbilityTest(s,{event:e})}#V(e,t){t.rollDeathSave({event:e})}async#G(e,t){const s=t.split(">"),i=s[0],n=s[1];(await MagicItems.actor(e.id)).roll(i,n),Hooks.callAll("forceUpdateTokenActionHud")}#Z(e,t,s){t&&t.system?.skills&&t.rollSkill(s,{event:e})}#W(t,s,i){const n=e.api.Utils.getItem(s,i);if(!this.#X(n))return n.use({event:t});n.rollRecharge()}#X(e){return e.system.recharge&&!e.system.recharge.charged&&e.system.recharge.value}async#z(e,t,s,i){switch(i){case"deathSave":this.#V(e,t);break;case"endTurn":if(!s)break;game.combat?.current?.tokenId===s.id&&await(game.combat?.nextTurn());break;case"initiative":await this.#ee(t);break;case"inspiration":await this.#K(t);break;case"longRest":t.longRest();break;case"shortRest":t.shortRest()}Hooks.callAll("forceUpdateTokenActionHud")}async#ee(e){e&&(await e.rollInitiative({createCombatants:!0}),Hooks.callAll("forceUpdateTokenActionHud"))}async#_(e,t,s,i){if(!s)return;const n=this.isRightClick(e),a=CONFIG.statusEffects.find((e=>e.id===i)),l=a?.flags?Object.hasOwn(a.flags,"dfreds-convenient-effects")?a.flags["dfreds-convenient-effects"].isConvenient:null:i.startsWith("Convenient Effect");if(game.dfreds&&l)n?await game.dfreds.effectInterface.toggleEffect(a.name??a.label,{overlay:!0}):await game.dfreds.effectInterface.toggleEffect(a.name??a.label);else{const e=this.#te(i);if(!e)return;const a=this.#se(t,i);a?.disabled&&await a.delete(),n?await s.toggleEffect(e,{overlay:!0}):await s.toggleEffect(e)}Hooks.callAll("forceUpdateTokenActionHud")}#te(e){return CONFIG.statusEffects.find((t=>t.id===e))}#se(e,t){return game.version.startsWith("11")?e.effects.find((e=>e.statuses.every((e=>e===t)))):e.effects.find((e=>e.flags?.core?.statusId===t))}async#O(e,t,s){let i=("find"in t.effects.entries?t.effects.entries:t.effects).find((e=>e.id===s)),n=!0;if(!i){n=!1;for(const e of t.allApplicableEffects())e.id===s&&(i=e)}if(!i)return;this.isRightClick(e)&&n?await i.delete():await i.update({disabled:!i.disabled}),Hooks.callAll("forceUpdateTokenActionHud")}async handleActionHover(t,s){const[i,n]=s.split("|");if(!["feature","item","spell","weapon","magicItem"].includes(i))return;const a=e.api.Utils.getItem(this.actor,n);switch(t.type){case"mouseenter":case"mouseover":Hooks.call("tokenActionHudSystemActionHoverOn",t,a);break;case"mouseleave":case"mouseout":Hooks.call("tokenActionHudSystemActionHoverOff",t,a)}}}}));class RollHandlerObsidian extends g{_rollAbilityTest(e,t){OBSIDIAN.Items.roll(super.actor,{roll:"abl",abl:t})}_rollAbilitySave(e,t){OBSIDIAN.Items.roll(super.actor,{roll:"save",save:t})}_rollSkill(e,t){OBSIDIAN.Items.roll(super.actor,{roll:"skl",skl:t})}_useItem(e,t){OBSIDIAN.Items.roll(super.actor,{roll:"item",id:t})}}function register(t){game.settings.register(e.ID,"abbreviateSkills",{name:game.i18n.localize("tokenActionHud.dnd5e.settings.abbreviateSkills.name"),hint:game.i18n.localize("tokenActionHud.dnd5e.settings.abbreviateSkills.hint"),scope:"client",config:!0,type:Boolean,default:!1,onChange:e=>{t(e)}}),game.settings.register(e.ID,"showSlowActions",{name:game.i18n.localize("tokenActionHud.dnd5e.settings.showSlowActions.name"),hint:game.i18n.localize("tokenActionHud.dnd5e.settings.showSlowActions.hint"),scope:"client",config:!0,type:Boolean,default:!0,onChange:e=>{t(e)}}),game.settings.register(e.ID,"displaySpellInfo",{name:game.i18n.localize("tokenActionHud.dnd5e.settings.displaySpellInfo.name"),hint:game.i18n.localize("tokenActionHud.dnd5e.settings.displaySpellInfo.hint"),scope:"client",config:!0,type:Boolean,default:!0,onChange:e=>{t(e)}}),game.settings.register(e.ID,"showUnchargedItems",{name:game.i18n.localize("tokenActionHud.dnd5e.settings.showUnchargedItems.name"),hint:game.i18n.localize("tokenActionHud.dnd5e.settings.showUnchargedItems.hint"),scope:"client",config:!0,type:Boolean,default:!1,onChange:e=>{t(e)}}),game.settings.register(e.ID,"showUnequippedItems",{name:game.i18n.localize("tokenActionHud.dnd5e.settings.showUnequippedItems.name"),hint:game.i18n.localize("tokenActionHud.dnd5e.settings.showUnequippedItems.hint"),scope:"client",config:!0,type:Boolean,default:!1,onChange:e=>{t(e)}}),game.settings.register(e.ID,"showUnequippedItemsNpcs",{name:game.i18n.localize("tokenActionHud.dnd5e.settings.showUnequippedItemsNpcs.name"),hint:game.i18n.localize("tokenActionHud.dnd5e.settings.showUnequippedItemsNpcs.hint"),scope:"client",config:!0,type:Boolean,default:!0,onChange:e=>{t(e)}}),game.settings.register(e.ID,"showUnpreparedSpells",{name:game.i18n.localize("tokenActionHud.dnd5e.settings.showUnpreparedSpells.name"),hint:game.i18n.localize("tokenActionHud.dnd5e.settings.showUnpreparedSpells.hint"),scope:"client",config:!0,type:Boolean,default:!1,onChange:e=>{t(e)}}),game.settings.register(e.ID,"showItemsWithoutActivationCosts",{name:game.i18n.localize("tokenActionHud.dnd5e.settings.showItemsWithoutActivationCosts.name"),hint:game.i18n.localize("tokenActionHud.dnd5e.settings.showItemsWithoutActivationCosts.hint"),scope:"client",config:!0,type:Boolean,default:!1,onChange:e=>{t(e)}})}let v=null;Hooks.once("tokenActionHudCoreApiReady",(async e=>{v=class SystemManager extends e.api.SystemManager{getActionHandler(){const t=new h;return(e.api.Utils.isModuleActive("magic-items-2")||e.api.Utils.isModuleActive("magicitems"))&&t.addActionHandlerExtender(new f(t)),t}getAvailableRollHandlers(){let t="Core D&D5e";e.api.Utils.isModuleActive("midi-qol")&&(t+=` [supports ${e.api.Utils.getModuleTitle("midi-qol")}]`);const s={core:t};return e.api.SystemManager.addHandler(s,"obsidian"),s}getRollHandler(e){let t;if("obsidian"===e)t=new RollHandlerObsidian;else t=new g;return t}registerSettings(e){register(e)}async registerDefaults(){const t=m;if(game.modules.get("magicitems")?.active||game.modules.get("magic-items-2")?.active){const s=e.api.Utils.i18n("tokenActionHud.dnd5e.magicItems");t.groups.push({id:"magic-items",name:s,listName:`Group: ${s}`,type:"system"}),t.groups.sort(((e,t)=>e.id.localeCompare(t.id)))}return t}}})),Hooks.on("tokenActionHudCoreApiReady",(async()=>{const t=game.modules.get(e.ID);t.api={requiredCoreModuleVersion:"1.5",SystemManager:v},Hooks.call("tokenActionHudSystemReady",t)}));export{i as ACTION_TYPE,n as ACTIVATION_TYPE_ICON,h as ActionHandler,a as CONCENTRATION_ICON,l as CONDITION,t as CORE_MODULE,m as DEFAULTS,o as GROUP,e as MODULE,f as MagicItemActionHandlerExtender,r as PREPARED_ICON,d as PROFICIENCY_LEVEL_ICON,c as RARITY,s as REQUIRED_CORE_MODULE_VERSION,p as RITUAL_ICON,g as RollHandler,RollHandlerObsidian,v as SystemManager,y as Utils,u as WEAPON_PROPERTY,register}; +const e={ID:"token-action-hud-dnd5e"},t={ID:"token-action-hud-core"},s="1.5",i={ability:"DND5E.Ability",check:"tokenActionHud.dnd5e.check",condition:"tokenActionHud.dnd5e.condition",counter:"tokenActionHud.dnd5e.counter",effect:"DND5E.Effect",exhaustion:"DND5E.Exhaustion",feature:"ITEM.TypeFeat",item:"tokenActionHud.dnd5e.item",save:"DND5E.ActionSave",skill:"tokenActionHud.dnd5e.skill",spell:"ITEM.TypeSpell",utility:"DND5E.ActionUtil"},n={bonus:"fas fa-plus",crew:"fas fa-users",day:"fas fa-hourglass-end",hour:"fas fa-hourglass-half",lair:"fas fa-home",minute:"fas fa-hourglass-start",legendary:"fas fas fa-dragon",reaction:"fas fa-bolt",special:"fas fa-star"},a="systems/dnd5e/icons/svg/statuses/concentrating.svg",l={blind:{uuid:"Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.0b8N4FymGGfbZGpJ"},blinded:{uuid:"Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.0b8N4FymGGfbZGpJ"},"Convenient Effect: Blinded":{uuid:"Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.0b8N4FymGGfbZGpJ"},charmed:{uuid:"Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.zZaEBrKkr66OWJvD"},"Convenient Effect: Charmed":{uuid:"Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.zZaEBrKkr66OWJvD"},deaf:{uuid:"Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.6G8JSjhn701cBITY"},deafened:{uuid:"Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.6G8JSjhn701cBITY"},"Convenient Effect: Deafened":{uuid:"Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.6G8JSjhn701cBITY"},fear:{uuid:"Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.oreoyaFKnvZCrgij"},"Convenient Effect: Frightened":{uuid:"Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.oreoyaFKnvZCrgij"},frightened:{uuid:"Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.oreoyaFKnvZCrgij"},grappled:{uuid:"Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.gYDAhd02ryUmtwZn"},"Convenient Effect: Grappled":{uuid:"Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.gYDAhd02ryUmtwZn"},incapacitated:{uuid:"Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.TpkZgLfxCmSndmpb"},"Convenient Effect: Incapacitated":{uuid:"Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.TpkZgLfxCmSndmpb"},invisible:{uuid:"Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.3UU5GCTVeRDbZy9u"},"Convenient Effect: Invisible":{uuid:"Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.3UU5GCTVeRDbZy9u"},paralysis:{uuid:"Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.xnSV5hLJIMaTABXP"},paralyzed:{uuid:"Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.xnSV5hLJIMaTABXP"},"Convenient Effect: Paralyzed":{uuid:"Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.xnSV5hLJIMaTABXP"},petrified:{uuid:"Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.xaNDaW6NwQTgHSmi"},"Convenient Effect: Petrified":{uuid:"Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.xaNDaW6NwQTgHSmi"},poison:{uuid:"Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.lq3TRI6ZlED8ABMx"},poisoned:{uuid:"Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.lq3TRI6ZlED8ABMx"},"Convenient Effect: Poisoned":{uuid:"Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.lq3TRI6ZlED8ABMx"},prone:{uuid:"Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.y0TkcdyoZlOTmAFT"},"Convenient Effect: Prone":{uuid:"Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.y0TkcdyoZlOTmAFT"},restrain:{uuid:"Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.cSVcyZyNe2iG1fIc"},restrained:{uuid:"Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.cSVcyZyNe2iG1fIc"},"Convenient Effect: Restrained":{uuid:"Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.cSVcyZyNe2iG1fIc"},stun:{uuid:"Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.ZyZMUwA2rboh4ObS"},stunned:{uuid:"Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.ZyZMUwA2rboh4ObS"},"Convenient Effect: Stunned":{uuid:"Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.ZyZMUwA2rboh4ObS"},unconscious:{uuid:"Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.UWw13ISmMxDzmwbd"},"Convenient Effect: Unconscious":{uuid:"Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.UWw13ISmMxDzmwbd"},exhaustion:{uuid:"Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.cspWveykstnu3Zcv"},"Convenient Effect: Exhaustion 1":{uuid:"Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.cspWveykstnu3Zcv"},"Convenient Effect: Exhaustion 2":{uuid:"Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.cspWveykstnu3Zcv"},"Convenient Effect: Exhaustion 3":{uuid:"Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.cspWveykstnu3Zcv"},"Convenient Effect: Exhaustion 4":{uuid:"Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.cspWveykstnu3Zcv"},"Convenient Effect: Exhaustion 5":{uuid:"Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.cspWveykstnu3Zcv"}},o={_1stLevelSpells:{id:"1st-level-spells",name:"tokenActionHud.dnd5e.1stLevelSpells",type:"system"},_2ndLevelSpells:{id:"2nd-level-spells",name:"tokenActionHud.dnd5e.2ndLevelSpells",type:"system"},_3rdLevelSpells:{id:"3rd-level-spells",name:"tokenActionHud.dnd5e.3rdLevelSpells",type:"system"},_4thLevelSpells:{id:"4th-level-spells",name:"tokenActionHud.dnd5e.4thLevelSpells",type:"system"},_5thLevelSpells:{id:"5th-level-spells",name:"tokenActionHud.dnd5e.5thLevelSpells",type:"system"},_6thLevelSpells:{id:"6th-level-spells",name:"tokenActionHud.dnd5e.6thLevelSpells",type:"system"},_7thLevelSpells:{id:"7th-level-spells",name:"tokenActionHud.dnd5e.7thLevelSpells",type:"system"},_8thLevelSpells:{id:"8th-level-spells",name:"tokenActionHud.dnd5e.8thLevelSpells",type:"system"},_9thLevelSpells:{id:"9th-level-spells",name:"tokenActionHud.dnd5e.9thLevelSpells",type:"system"},abilities:{id:"abilities",name:"tokenActionHud.dnd5e.abilities",type:"system"},actions:{id:"actions",name:"DND5E.ActionPl",type:"system"},activeFeatures:{id:"active-features",name:"tokenActionHud.dnd5e.activeFeatures",type:"system"},artificerInfusions:{id:"artificer-infusions",name:"tokenActionHud.dnd5e.artificerInfusions",type:"system"},atWillSpells:{id:"at-will-spells",name:"tokenActionHud.dnd5e.atWillSpells",type:"system"},backgroundFeatures:{id:"background-features",name:"tokenActionHud.dnd5e.backgroundFeatures",type:"system"},bonusActions:{id:"bonus-actions",name:"tokenActionHud.dnd5e.bonusActions",type:"system"},cantrips:{id:"cantrips",name:"tokenActionHud.dnd5e.cantrips",type:"system"},channelDivinity:{id:"channel-divinity",name:"tokenActionHud.dnd5e.channelDivinity",type:"system"},checks:{id:"checks",name:"tokenActionHud.dnd5e.checks",type:"system"},classFeatures:{id:"class-features",name:"tokenActionHud.dnd5e.classFeatures",type:"system"},combat:{id:"combat",name:"tokenActionHud.combat",type:"system"},conditions:{id:"conditions",name:"tokenActionHud.dnd5e.conditions",type:"system"},consumables:{id:"consumables",name:"ITEM.TypeConsumablePl",type:"system"},containers:{id:"containers",name:"ITEM.TypeContainerPl",type:"system"},counters:{id:"counters",name:"tokenActionHud.dnd5e.counters",type:"system"},crewActions:{id:"crew-actions",name:"tokenActionHud.dnd5e.crewActions",type:"system"},defensiveTactics:{id:"defensive-tactics",name:"tokenActionHud.dnd5e.defensiveTactics",type:"system"},eldritchInvocations:{id:"eldritch-invocations",name:"tokenActionHud.dnd5e.eldritchInvocations",type:"system"},elementalDisciplines:{id:"elemental-disciplines",name:"tokenActionHud.dnd5e.elementalDisciplines",type:"system"},equipment:{id:"equipment",name:"ITEM.TypeEquipmentPl",type:"system"},equipped:{id:"equipped",name:"DND5E.Equipped",type:"system"},exhaustion:{id:"exhaustion",name:"DND5E.Exhaustion",type:"system"},feats:{id:"feats",name:"tokenActionHud.dnd5e.feats",type:"system"},fightingStyles:{id:"fighting-styles",name:"tokenActionHud.dnd5e.fightingStyles",type:"system"},huntersPrey:{id:"hunters-prey",name:"tokenActionHud.dnd5e.huntersPrey",type:"system"},innateSpells:{id:"innate-spells",name:"tokenActionHud.dnd5e.innateSpells",type:"system"},kiAbilities:{id:"ki-abilities",name:"tokenActionHud.dnd5e.kiAbilities",type:"system"},lairActions:{id:"lair-actions",name:"tokenActionHud.dnd5e.lairActions",type:"system"},legendaryActions:{id:"legendary-actions",name:"tokenActionHud.dnd5e.legendaryActions",type:"system"},loot:{id:"loot",name:"ITEM.TypeLootPl",type:"system"},maneuvers:{id:"maneuvers",name:"tokenActionHud.dnd5e.maneuvers",type:"system"},metamagicOptions:{id:"metamagic-options",name:"tokenActionHud.dnd5e.metamagicOptions",type:"system"},monsterFeatures:{id:"monster-features",name:"tokenActionHud.dnd5e.monsterFeatures",type:"system"},multiattacks:{id:"multiattacks",name:"tokenActionHud.dnd5e.multiattacks",type:"system"},otherActions:{id:"other-actions",name:"tokenActionHud.dnd5e.otherActions",type:"system"},pactBoons:{id:"pact-boons",name:"tokenActionHud.dnd5e.pactBoons",type:"system"},pactSpells:{id:"pact-spells",name:"tokenActionHud.dnd5e.pactSpells",type:"system"},passiveEffects:{id:"passive-effects",name:"DND5E.EffectPassive",type:"system"},passiveFeatures:{id:"passive-features",name:"tokenActionHud.dnd5e.passiveFeatures",type:"system"},psionicPowers:{id:"psionic-powers",name:"tokenActionHud.dnd5e.psionicPowers",type:"system"},raceFeatures:{id:"race-features",name:"tokenActionHud.dnd5e.raceFeatures",type:"system"},reactions:{id:"reactions",name:"DND5E.ReactionPl",type:"system"},rests:{id:"rests",name:"tokenActionHud.dnd5e.rests",type:"system"},runes:{id:"runes",name:"tokenActionHud.dnd5e.runes",type:"system"},saves:{id:"saves",name:"DND5E.ClassSaves",type:"system"},skills:{id:"skills",name:"tokenActionHud.dnd5e.skills",type:"system"},superiorHuntersDefense:{id:"superior-hunters-defense",name:"tokenActionHud.dnd5e.superiorHuntersDefense",type:"system"},temporaryEffects:{id:"temporary-effects",name:"DND5E.EffectTemporary",type:"system"},token:{id:"token",name:"tokenActionHud.token",type:"system"},tools:{id:"tools",name:"ITEM.TypeToolPl",type:"system"},unequipped:{id:"unequipped",name:"DND5E.Unequipped",type:"system"},utility:{id:"utility",name:"tokenActionHud.utility",type:"system"},weapons:{id:"weapons",name:"ITEM.TypeWeaponPl",type:"system"}},r="fas fa-sun",d={.5:"fas fa-adjust",1:"fas fa-check",2:"fas fa-check-double"},c={common:"tokenActionHud.dnd5e.common",uncommon:"tokenActionHud.dnd5e.uncommon",rare:"tokenActionHud.dnd5e.rare",veryRare:"tokenActionHud.dnd5e.veryRare",legendary:"tokenActionHud.dnd5e.legendary",artifact:"tokenActionHud.dnd5e.artifact"},p="fas fa-circle-r",u={ada:"DND5E.WeaponPropertiesAda",amm:"DND5E.WeaponPropertiesAmm",fin:"DND5E.WeaponPropertiesFin",fir:"DND5E.WeaponPropertiesFir",foc:"DND5E.WeaponPropertiesFoc",hvy:"DND5E.WeaponPropertiesHvy",lgt:"DND5E.WeaponPropertiesLgt",lod:"DND5E.WeaponPropertiesLod",mgc:"DND5E.WeaponPropertiesMgc",rch:"DND5E.WeaponPropertiesRch",rel:"DND5E.WeaponPropertiesRel",ret:"DND5E.WeaponPropertiesRet",sil:"DND5E.WeaponPropertiesSil",spc:"DND5E.WeaponPropertiesSpc",thr:"DND5E.WeaponPropertiesThr",two:"DND5E.WeaponPropertiesTwo",ver:"DND5E.WeaponPropertiesVer"};let m=null;Hooks.once("tokenActionHudCoreApiReady",(async t=>{m=class Utils{static getSetting(s,i=null){let n=i??null;try{n=game.settings.get(e.ID,s)}catch{t.api.Logger.debug(`Setting '${s}' not found`)}return n}static async setSetting(s,i){try{i=await game.settings.set(e.ID,s,i),t.api.Logger.debug(`Setting '${s}' set to '${i}'`)}catch{t.api.Logger.debug(`Setting '${s}' not found`)}}}}));let y=null;Hooks.once("tokenActionHudCoreApiReady",(async e=>{y=class ActionHandler extends e.api.ActionHandler{actors=null;tokens=null;actorType=null;items=null;abbreviateSkills=null;displaySpellInfo=null;showItemsWithoutActivationCosts=null;showUnchargedItems=null;showUnequippedItems=null;showUnpreparedSpells=null;activationgroupIds=null;featuregroupIds=null;inventorygroupIds=null;spellgroupIds=null;featureActions=null;inventoryActions=null;spellActions=null;systemVersion=game.dnd5e.version;async buildSystemActions(t){if(this.actors=this.actor?[this.actor]:this.#e(),this.tokens=this.token?[this.token]:this.#t(),this.actorType=this.actor?.type,this.actor){let t=this.actor.items;t=this.#s(t),t=e.api.Utils.sortItemsByName(t),this.items=t}this.abbreviateSkills=m.getSetting("abbreviateSkills"),this.displaySpellInfo=m.getSetting("displaySpellInfo"),this.showItemsWithoutActivationCosts=m.getSetting("showItemsWithoutActivationCosts"),this.showUnchargedItems=m.getSetting("showUnchargedItems"),this.showUnequippedItems=m.getSetting("showUnequippedItems"),"npc"!==this.actorType||this.showUnequippedItems||(this.showUnequippedItems=m.getSetting("showUnequippedItemsNpcs")),this.showUnpreparedSpells=m.getSetting("showUnpreparedSpells"),this.activationgroupIds=["actions","bonus-actions","crew-actions","lair-actions","legendary-actions","reactions","other-actions"],this.featuregroupIds=["active-features","passive-features","background-features","class-features","feats","monster-features","race-features","artificer-infusions","channel-divinity","defensive-tactics","eldritch-invocations","elemental-disciplines","fighting-styles","hunters-prey","ki-abilities","maneuvers","metamagic-options","multiattacks","pact-boons","psionic-powers","runes","superior-hunters-defense"],this.spellgroupIds=["cantrips","1st-level-spells","2nd-level-spells","3rd-level-spells","4th-level-spells","5th-level-spells","6th-level-spells","7th-level-spells","8th-level-spells","9th-level-spells","at-will-spells","innate-spells","pact-spells"],"character"===this.actorType||"npc"===this.actorType?(this.inventorygroupIds=["equipped","consumables","containers","equipment","loot","tools","weapons","unequipped"],await this.#i()):"vehicle"===this.actorType?(this.inventorygroupIds=["consumables","equipment","tools","weapons"],await this.#n()):this.actor||await this.#a()}async#i(){await Promise.all([this.#l(),this.#o(),this.#r(),this.#d(),this.#c()]),this.#p("ability","abilities"),this.#p("check","checks"),this.#p("save","saves"),this.#u(),this.#m(),this.#y(),this.#h(),this.#g(),this.#f()}async#n(){await Promise.all([this.#l(),this.#o(),this.#r(),this.#d()]),this.#p("ability","abilities"),this.#p("check","checks"),this.#p("save","saves"),this.#u(),this.#f()}async#a(){this.#p("ability","abilities"),this.#p("check","checks"),this.#p("save","saves"),this.#u(),await this.#l(),this.#h(),this.#g(),this.#f()}#p(t,s){const n=this.actor?this.actor.system.abilities:CONFIG.DND5E.abilities;if(0===n.length)return;const a=Object.entries(n).filter((e=>0!==n[e[0]].value)).map((([a,l])=>{const o=`${t}-${a}`,r=a.charAt(0).toUpperCase()+a.slice(1),d=this.systemVersion>="2.2"?CONFIG.DND5E.abilities[a].label:CONFIG.DND5E.abilities[a],c=this.abbreviateSkills?r:d,p=`${`${e.api.Utils.i18n(i[t])}: `??""}${d}`,u=[t,a].join(this.delimiter),m="checks"!==s?this.#v(n[a].proficient):"",y="saves"!==s?l?.mod:"saves"===s?l?.save:"";return{id:o,name:c,encodedValue:u,icon1:m,info1:this.actor?{text:e.api.Utils.getModifier(y)}:null,info2:this.actor&&"abilities"===s?{text:`(${e.api.Utils.getModifier(l?.save)})`}:null,listName:p}})),l={id:s,type:"system"};this.addActions(a,l)}async buildActivations(e){const{groupData:t,actionData:s,actionType:i="item"}=e,n=new Map,a={action:"actions",bonus:"bonus-actions",crew:"crew-actions",lair:"lair-actions",legendary:"legendary-actions",reaction:"reactions",reactiondamage:"reactions",reactionmanual:"reactions",other:"other-actions"};for(const[e,t]of s){const s=t.system?.activation?.type,i=a[Object.keys(a).includes(s)?s:"other"];n.has(i)||n.set(i,new Map),n.get(i).set(e,t)}for(const e of this.activationgroupIds){if(!n.has(e))continue;const s={...t,id:`${e}+${t.id}`,type:"system-derived"};["equipped","unequipped"].includes(t.id)&&(s.defaultSelected=!1);const a={id:e,type:"system"};await this.addGroup(s,a),"spell"===i&&this.addGroupInfo(s);const l=n.get(e);await this.buildActions({groupData:s,actionData:l,actionType:i})}}#u(){const t="utility",s={initiative:{id:"initiative",name:e.api.Utils.i18n("tokenActionHud.dnd5e.rollInitiative")},endTurn:{id:"endTurn",name:e.api.Utils.i18n("tokenActionHud.endTurn")}};game.combat?.current?.tokenId!==this.token?.id&&delete s.endTurn;const n=Object.entries(s).map((s=>{const n=s[1].id,a=s[1].name,l=`${`${e.api.Utils.i18n(i[t])}: `??""}${a}`,o=[t,n].join(this.delimiter),r={};let d="";if("initiative"===s[0]&&game.combat){const t=e.api.Utils.getControlledTokens()?.map((e=>e.id)),s=game.combat.combatants.filter((e=>t.includes(e.tokenId)));if(1===s.length){const e=s[0].initiative;r.class="tah-spotlight",r.text=e}d=`toggle${s.length>0&&s.every((e=>e?.initiative))?" active":""}`}return{id:n,name:a,encodedValue:o,info1:r,cssClass:d,listName:l}}));this.addActions(n,{id:"combat",type:"system"})}async#l(){if(0===this.tokens?.length)return;const t="condition",s=CONFIG.statusEffects.filter((e=>""!==e.id));if(0===s.length)return;const n=await Promise.all(s.map((async s=>{const n=s.id,a=e.api.Utils.i18n(s.label)??s.name,l=`${`${e.api.Utils.i18n(i[t])}: `??""}${a}`,o=[t,n].join(this.delimiter),r=`toggle${this.actors.every((e=>game.version.startsWith("11")?e.effects.some((e=>e.statuses.some((e=>e===n))&&!e?.disabled)):e.effects.some((e=>e.flags?.core?.statusId===n&&!e?.disabled))))?" active":""}`,d=e.api.Utils.getImage(s),c=await this.#b(n,a),p=await this.#k(c);return{id:n,name:a,encodedValue:o,img:d,cssClass:r,listName:l,tooltip:p}})));this.addActions(n,{id:"conditions",type:"system"})}async#m(){if("character"!==this.actorType)return;const t="counter";let s=[];if(e.api.Utils.isModuleActive("dnd5e-custom-counters")){if("character"!==this.actorType)return;s=Object.entries(game.settings.get("dnd5e-custom-counters","characterCounters")).filter((([e,t])=>t.visible)).map((([e,t])=>(t.key=e,t)))}else s=[{name:e.api.Utils.i18n("DND5E.DeathSave"),type:"successFailure",system:!0,visible:!0,key:"death-saves"},{name:e.api.Utils.i18n("DND5E.Exhaustion"),type:"number",system:!0,visible:!0,key:"exhaustion"},{name:e.api.Utils.i18n("DND5E.Inspiration"),type:"checkbox",system:!0,visible:!0,key:"inspiration"}];const n=s.map((s=>{const n=s.key,a=s.name,l=`${`${e.api.Utils.i18n(i[t])}: `??""}${a}`,o=s.system?n:encodeURIComponent(`${n}>${s.type}`),r=[t,o].join(this.delimiter);let d="",c="",p="",u="";if(s.system)switch(n){case"exhaustion":d=this.actor.system.attributes.exhaustion>0?" active":"",c=`toggle${d}`,p=e.api.Utils.getImage("modules/token-action-hud-dnd5e/icons/exhaustion.svg"),u={text:this.actor.system.attributes.exhaustion};break;case"death-saves":p=e.api.Utils.getImage("modules/token-action-hud-dnd5e/icons/death-saves.svg"),u={text:`${this.actor.system.attributes.death.success}/${this.actor.system.attributes.death.failure}`};break;case"inspiration":d=this.actor.system.attributes.inspiration?" active":"",c=`toggle${d}`,p=e.api.Utils.getImage("modules/token-action-hud-dnd5e/icons/inspiration.svg")}else{const e=this.actor.getFlag("dnd5e-custom-counters",n);switch(s.type){case"checkbox":d=e?" active":"",c=`toggle${d}`;break;case"number":d=e>0?" active":"",c=`toggle${d}`,u={text:e};break;case"successFailure":u={text:`${e?.success??0}/${e?.failure??0}`}}}return{id:n,name:a,listName:l,encodedValue:r,cssClass:c,img:p,info1:u}}));this.addActions(n,{id:"counters",type:"system"})}async#o(){const e="effect",t=new Map;for(const e of this.actor.allApplicableEffects())t.set(e.id,e);if(0===t.size)return;const s=new Map,i=new Map;for(const[e,n]of t.entries()){if(n.isSuppressed||!1===n.parent?.system?.identified&&!game.user.isGM)continue;n.isTemporary?i.set(e,n):s.set(e,n)}await Promise.all([this.buildActions({groupData:{id:"passive-effects",type:"system"},actionData:s,actionType:e}),this.buildActions({groupData:{id:"temporary-effects",type:"system"},actionData:i,actionType:e})])}#y(){if(0===this.actors.length)return;if(!this.actors.every((e=>"character"===e.type)))return;const t="exhaustion",s="exhaustion",n=e.api.Utils.i18n("DND5E.Exhaustion"),a=`${`${e.api.Utils.i18n(i[t])}: `??""}${n}`,l=[t,s].join(this.delimiter),o=e.api.Utils.getImage("modules/token-action-hud-dnd5e/icons/exhaustion.svg"),r={text:this.actor.system.attributes.exhaustion};let d="";d=`toggle${this.actor.system.attributes.exhaustion>0?" active":""}`;const c=[{cssClass:d,id:s,name:n,encodedValue:l,img:o,info1:r,listName:a}];this.addActions(c,{id:"exhaustion",type:"system"})}async#r(){const t=new Map;for(const[e,s]of this.items){"feat"===s.type&&t.set(e,s)}if(0===t.size)return;const s=new Map,i=[{type:"background",groupId:"background-features"},{type:"class",groupId:"class-features"},{type:"monster",groupId:"monster-features"},{type:"race",groupId:"race-features"},{type:"feats",groupId:"feats"}],n=[{type:"artificerInfusion",groupId:"artificer-infusions"},{type:"channelDivinity",groupId:"channel-divinity"},{type:"defensiveTactic",groupId:"defensive-tactics"},{type:"eldritchInvocation",groupId:"eldritch-invocations"},{type:"elementalDiscipline",groupId:"elemental-disciplines"},{type:"fightingStyle",groupId:"fighting-styles"},{type:"huntersPrey",groupId:"hunters-prey"},{type:"ki",groupId:"ki-abilities"},{type:"maneuver",groupId:"maneuvers"},{type:"metamagic",groupId:"metamagic-options"},{type:"multiattack",groupId:"multiattacks"},{type:"pact",groupId:"pact-boons"},{type:"psionicPower",groupId:"psionic-powers"},{type:"rune",groupId:"runes"},{type:"superiorHuntersDefense",groupId:"superior-hunters-defense"}];for(const[e,a]of t){const t=a.system.activation?.type,l=a.system.type.value,o=a.system.type?.subtype;t&&(s.has("active-features")||s.set("active-features",new Map),s.get("active-features").set(e,a)),t&&""!==t||(s.has("passive-features")||s.set("passive-features",new Map),s.get("passive-features").set(e,a));for(const t of i){const i=t.groupId;t.type===l&&(s.has(i)||s.set(i,new Map),s.get(i).set(e,a))}for(const t of n){const i=t.groupId;o&&t.type===o&&(s.has(i)||s.set(i,new Map),s.get(i).set(e,a))}}const a={"active-features":e.api.Utils.i18n("tokenActionHud.dnd5e.activeFeatures"),"passive-features":e.api.Utils.i18n("tokenActionHud.dnd5e.passiveFeatures")};for(const e of this.featuregroupIds){if(!s.has(e))continue;const t={groupData:{id:e,name:a[e]??"",type:"system"},actionData:s.get(e),actionType:"feature"};await this.buildActions(t),a[e]&&await this.buildActivations(t)}}async#d(){if(0===this.items.size)return;const t=new Map;for(const[e,s]of this.items){const i=s.system.equipped,n=s.system?.quantity>0,a=this.#A(s),l=this.#I(s),o=this.#D(s),r=s.type;n&&a&&(i&&(t.has("equipped")||t.set("equipped",new Map),t.get("equipped").set(e,s)),i||(t.has("unequipped")||t.set("unequipped",new Map),t.get("unequipped").set(e,s)),l&&"consumable"===r&&(t.has("consumables")||t.set("consumables",new Map),t.get("consumables").set(e,s)),o&&("container"===r&&(t.has("containers")||t.set("containers",new Map),t.get("containers").set(e,s)),"equipment"===r&&(t.has("equipment")||t.set("equipment",new Map),t.get("equipment").set(e,s)),"loot"===r&&(t.has("loot")||t.set("loot",new Map),t.get("loot").set(e,s)),"tool"===r&&(t.has("tools")||t.set("tools",new Map),t.get("tools").set(e,s)),"weapon"===r&&(t.has("weapons")||t.set("weapons",new Map),t.get("weapons").set(e,s))))}const s={equipped:e.api.Utils.i18n("DND5E.Equipped"),unequipped:e.api.Utils.i18n("DND5E.Unequipped"),consumables:e.api.Utils.i18n("ITEM.TypeConsumablePl"),containers:e.api.Utils.i18n("ITEM.TypeContainerPl"),equipment:e.api.Utils.i18n("ITEM.TypeEquipmentPl"),loot:e.api.Utils.i18n("ITEM.TypeLootPl"),tools:e.api.Utils.i18n("ITEM.TypeToolPl"),weapons:e.api.Utils.i18n("ITEM.TypeWeaponPl")};for(const e of this.inventorygroupIds){if(!t.has(e))continue;const i={groupData:{id:e,name:s[e],type:"system"},actionData:t.get(e)};await this.buildActions(i),this.activationgroupIds&&await this.buildActivations(i)}}#h(){if(0===this.actors.length)return;if(!this.actors.every((e=>"character"===e.type)))return;const t="utility",s={shortRest:{name:e.api.Utils.i18n("DND5E.ShortRest")},longRest:{name:e.api.Utils.i18n("DND5E.LongRest")}},n=Object.entries(s).map((s=>{const n=s[0],a=s[1].name,l=`${`${e.api.Utils.i18n(i[t])}: `??""}${a}`,o=[t,n].join(this.delimiter);return{id:n,name:a,encodedValue:o,listName:l}}));this.addActions(n,{id:"rests",type:"system"})}#g(){const t="skill",s=this.actor?this.actor.system.skills:CONFIG.DND5E.skills;if(0===s.length)return;const n=Object.entries(s).map((n=>{try{const a=n[0],l=a.charAt(0).toUpperCase()+a.slice(1),o=this.abbreviateSkills?l:CONFIG.DND5E.skills[a].label,r=`${`${e.api.Utils.i18n(i[t])}: `??""}${CONFIG.DND5E.skills[a].label}`,d=[t,a].join(this.delimiter),c=this.#v(s[a].value),p=s[a].total;return{id:a,name:o,encodedValue:d,icon1:c,info1:this.actor?{text:p||0===p?`${p>=0?"+":""}${p}`:""}:"",listName:r}}catch(t){return e.api.Logger.error(n),null}})).filter((e=>!!e));this.addActions(n,{id:"skills",type:"system"})}async#c(){const t=new Map;for(const[e,s]of this.items){if("spell"===s.type){const i=this.#I(s),n=this.#E(s);if(i&&n){switch(s.system.preparation.mode){case"atwill":t.has("at-will-spells")||t.set("at-will-spells",new Map),t.get("at-will-spells").set(e,s);break;case"innate":t.has("innate-spells")||t.set("innate-spells",new Map),t.get("innate-spells").set(e,s);break;case"pact":t.has("pact-spells")||t.set("pact-spells",new Map),t.get("pact-spells").set(e,s);break;default:switch(s.system.level){case 0:t.has("cantrips")||t.set("cantrips",new Map),t.get("cantrips").set(e,s);break;case 1:t.has("1st-level-spells")||t.set("1st-level-spells",new Map),t.get("1st-level-spells").set(e,s);break;case 2:t.has("2nd-level-spells")||t.set("2nd-level-spells",new Map),t.get("2nd-level-spells").set(e,s);break;case 3:t.has("3rd-level-spells")||t.set("3rd-level-spells",new Map),t.get("3rd-level-spells").set(e,s);break;case 4:t.has("4th-level-spells")||t.set("4th-level-spells",new Map),t.get("4th-level-spells").set(e,s);break;case 5:t.has("5th-level-spells")||t.set("5th-level-spells",new Map),t.get("5th-level-spells").set(e,s);break;case 6:t.has("6th-level-spells")||t.set("6th-level-spells",new Map),t.get("6th-level-spells").set(e,s);break;case 7:t.has("7th-level-spells")||t.set("7th-level-spells",new Map),t.get("7th-level-spells").set(e,s);break;case 8:t.has("8th-level-spells")||t.set("8th-level-spells",new Map),t.get("8th-level-spells").set(e,s);break;case 9:t.has("9th-level-spells")||t.set("9th-level-spells",new Map),t.get("9th-level-spells").set(e,s)}}}}}const s=Object.entries(this.actor.system.spells).reverse();let i=null;const n=[];let a=this.showUnchargedItems,l=this.showUnchargedItems;for(const[e,t]of s){const s=t.value>0,o=t.max>0,r=t.level>0;"pact"===e&&(!l&&s&&o&&r&&(l=!0),r||(l=!1),t.slotAvailable=l,i=[e,t]),e.startsWith("spell")&&"spell0"!==e?(!a&&s&&o&&(a=!0),t.slotAvailable=a,n.push([e,t])):s&&(t.slotsAvailable=!0,n.push(e,t))}if(i[1].slotAvailable){const e=n.findIndex((e=>e[0]==="spell"+i[1].level));n[e][1].slotsAvailable=!0}const o={"1st-level-spells":{spellMode:1,name:e.api.Utils.i18n("tokenActionHud.dnd5e.1stLevelSpells")},"2nd-level-spells":{spellMode:2,name:e.api.Utils.i18n("tokenActionHud.dnd5e.2ndLevelSpells")},"3rd-level-spells":{spellMode:3,name:e.api.Utils.i18n("tokenActionHud.dnd5e.3rdLevelSpells")},"4th-level-spells":{spellMode:4,name:e.api.Utils.i18n("tokenActionHud.dnd5e.4thLevelSpells")},"5th-level-spells":{spellMode:5,name:e.api.Utils.i18n("tokenActionHud.dnd5e.5thLevelSpells")},"6th-level-spells":{spellMode:6,name:e.api.Utils.i18n("tokenActionHud.dnd5e.6thLevelSpells")},"7th-level-spells":{spellMode:7,name:e.api.Utils.i18n("tokenActionHud.dnd5e.7thLevelSpells")},"8th-level-spells":{spellMode:8,name:e.api.Utils.i18n("tokenActionHud.dnd5e.8thLevelSpells")},"9th-level-spells":{spellMode:9,name:e.api.Utils.i18n("tokenActionHud.dnd5e.9thLevelSpells")},"at-will-spells":{spellMode:"atwill",name:e.api.Utils.i18n("tokenActionHud.dnd5e.atWillSpells")},cantrips:{spellMode:0,name:e.api.Utils.i18n("tokenActionHud.dnd5e.cantrips")},"innate-spells":{spellMode:"innate",name:e.api.Utils.i18n("tokenActionHud.dnd5e.innateSpells")},"pact-spells":{spellMode:"pact",name:e.api.Utils.i18n("tokenActionHud.dnd5e.pactSpells")}},r=["1","2","3","4","5","6","7","8","9","pact"];for(const e of this.spellgroupIds){const s=o[e].spellMode,a=o[e].name;if(!t.has(e))continue;const l="pact"===s?i[1]:n.find((e=>e[0]===`spell${s}`))?.[1],d=l?.value,c=l?.max,p=l?.slotAvailable;if(!p&&r.includes(s))continue;const u={};u.info1={class:"tah-spotlight",text:c>=0?`${d}/${c}`:""};const m={id:e,name:a,type:"system",info:u};this.addGroupInfo(m);const y={groupData:m,actionData:t.get(e),actionType:"spell"};await this.buildActions(y),this.activationgroupIds&&await this.buildActivations(y)}}#f(){if(0===this.actors.length)return;if(!this.actors.every((e=>"character"===e.type)))return;const t="utility",s={deathSave:{name:e.api.Utils.i18n("DND5E.DeathSave")},inspiration:{name:e.api.Utils.i18n("DND5E.Inspiration")}};(!this.actor||this.actor.system.attributes.hp.value>0)&&delete s.deathSave;const n=Object.entries(s).map((s=>{const n=s[0],a=s[1].name,l=`${`${e.api.Utils.i18n(i[t])}: `??""}${a}`,o=[t,n].join(this.delimiter);let r="";if("inspiration"===s[0]){r=`toggle${this.actors.every((e=>e.system.attributes?.inspiration))?" active":""}`}return{id:n,name:a,encodedValue:o,cssClass:r,listName:l}}));this.addActions(n,{id:"utility",type:"system"})}async buildActions(e,t){const{actionData:s,groupData:i,actionType:n}=e;if(0===s.size)return;if(!("string"==typeof i?i:i?.id))return;const a=await Promise.all([...s].map((async e=>await this.#w(n,e[1]))));this.addActions(a,i)}async#w(t="item",s){const n=s.id??s._id;let a=s?.name??s?.label;s?.system?.recharge&&!s?.system?.recharge?.charged&&s?.system?.recharge?.value&&(a+=` (${e.api.Utils.i18n("DND5E.Recharge")})`);const l=`${`${e.api.Utils.i18n(i[t])}: `??""}${a}`;let o="";if(Object.hasOwn(s,"disabled")){o=`toggle${s.disabled?"":" active"}`}const r=[t,n].join(this.delimiter),d=e.api.Utils.getImage(s),c=this.#S(s?.system?.activation?.type),p=this.#C(s),u=this.#U(s),m=this.#T(s),y=m?.info1,h=m?.info2,g=m?.info3,f=await this.#H(s);return{id:n,name:a,encodedValue:r,cssClass:o,img:d,icon1:c,icon2:p,icon3:u,info1:y,info2:h,info3:g,listName:l,tooltip:await this.#k(f)}}#A(e){if(this.showItemsWithoutActivationCosts)return!0;const t=Object.keys(CONFIG.DND5E.abilityActivationTypes).filter((e=>"none"!==e)),s=e.system.activation,i=s?.type;return!!(s&&t.includes(i)||"tool"===e.type)}#D(e){const t=e.type;if(this.showUnequippedItems&&!["consumable","spell","feat"].includes(t))return!0;return!(!e.system.equipped||"consumable"===t)}#I(e){if(this.showUnchargedItems)return!0;return!!e.system.uses}#E(e){if("character"!==this.actorType&&this.showUnequippedItems)return!0;const t=e.system.preparation.prepared;if(this.showUnpreparedSpells)return!0;const s=e.system.level,i=Object.keys(CONFIG.DND5E.spellPreparationModes).filter((e=>"prepared"!==e)),n=e.system.preparation.mode;return!(0!==s&&!i.includes(n)&&!t)}#T(e){return{info1:"spell"===e.type?this.#$(e):this.#N(e),info2:this.#P(e),info3:this.#M(e)}}#$(t){if(!this.displaySpellInfo)return null;const s={text:""},i=[],n=t.system?.properties;return[["vocal","DND5E.ComponentVerbal"],["somatic","DND5E.ComponentSomatic"],["material","DND5E.ComponentMaterial"]].forEach((t=>{n?.has(t[0])&&(i.push(e.api.Utils.i18n(t[1])),s.text+=e.api.Utils.i18n(`${t[1]}Abbr`))})),n?.has("ritual")&&(i.push(`[${e.api.Utils.i18n("DND5E.Ritual")}]`),s.text+=` [${e.api.Utils.i18n("DND5E.RitualAbbr")}]`),s.title=i.join(", "),s}#e(){const t=["character","npc"],s=e.api.Utils.getControlledTokens()?.filter((e=>e.actor)).map((e=>e.actor));return s.every((e=>t.includes(e.type)))?s:[]}#t(){const t=["character","npc"],s=e.api.Utils.getControlledTokens(),i=s?.filter((e=>e.actor)).map((e=>e.actor));return i.every((e=>t.includes(e.type)))?s:[]}#N(t){const s=t?.system?.quantity??0;return{text:s>1?s:"",title:`${e.api.Utils.i18n("DND5E.Quantity")}: ${s}`}}#P(t,s,i){const n=t?.system?.uses;if(n?.per&&(s||n?.prompt)&&(n.value>0||n.max>0)){const t=e.api.Utils.i18n("DND5E.of"),a="charges"===n.per?"":` ${e.api.Utils.i18n("DND5E.per")}`,l=CONFIG.DND5E.limitedUsePeriods[n.per]?.label??n.per,o=void 0!==i?i:n.amount,r=`${o>1?`${o} ${t} `:""}${n.value??"0"}${n.max>0?`/${n.max}`:""}`;return{text:r,title:`${r}${a} ${l}${s?` (${t} ${s})`:""}`}}return{}}#M(t){const s=t?.system?.consume?.target,i=t?.system?.consume?.type,n=t?.system?.consume?.amount;if(!s||!i||s===t.id)return{};if("attribute"===i){const e=s.substr(0,s.lastIndexOf(".")),t=foundry.utils.getProperty(this.actor.system,e);if(t){const e=`${t.value??"0"}${t.max?`/${t.max}`:""}`;return{text:e,title:`${e} ${t.label??""}`}}}else{const t=this.items.get(s);if("charges"===i)return this.#P(t,t.name,n);if(t?.system?.quantity){const s=`${n>1?`${n} ${e.api.Utils.i18n("DND5E.of")} `:""}${t.system.quantity}`;return{text:s,title:`${s} ${t.name}`}}}return{}}#s(e){if(m.getSetting("showSlowActions"))return e;const t=["minute","hour","day"],s=new Map;for(const[i,n]of e.entries()){const e=n.system?.activation?.type;t.includes(e)||s.set(i,n)}return s}#v(e){const t=CONFIG.DND5E.proficiencyLevels[e]??"",s=d[e];if(s)return``}#S(e){const t=CONFIG.DND5E.abilityActivationTypes[e]??"",s=n[e];if(s)return``}#U(t){if("spell"!==t?.type||!this.displaySpellInfo||!t.system?.properties?.has("concentration"))return null;return``}#C(t){if("spell"!==t?.type||!this.showUnpreparedSpells)return null;const s=t.system.level,i=t.system.preparation.mode,n=t.system.preparation.prepared,a=n?"fas fa-sun":"fas fa-sun tah-icon-disabled",l="always"===i?e.api.Utils.i18n("DND5E.SpellPrepAlways"):n?e.api.Utils.i18n("DND5E.SpellPrepared"):e.api.Utils.i18n("DND5E.SpellUnprepared");return"prepared"!==i&&"always"!==i||0===s?null:``}async#H(e){if("none"===this.tooltipsSetting)return"";const t=e?.name??"";if("nameOnly"===this.tooltipsSetting)return t;const s=!1===e.system?.identified,i="string"==typeof e?.system?.description?e?.system?.description:(s?e?.system?.unidentified?.description:e?.system?.description?.value)??"";let n,a,l,o;return s||(n=e?.modifiers??null,a=[...e.system?.chatProperties??[],...e.system?.equippableItemCardProperties??[],...e.system?.activatedEffectCardProperties??[]].filter((e=>e)),l=s?null:e?.rarity??null,o="weapon"===e?.type?this.#J(e?.system?.properties):null),{name:t,description:i,modifiers:n,properties:a,rarity:l,traits:o}}async#b(e,t){if("none"===this.tooltipsSetting)return"";if("nameOnly"===this.tooltipsSetting)return t;return{name:t,description:(l[e]&&l[e]?.uuid?await fromUuid(l[e].uuid):null)?.text?.content??""}}async#k(t){if("none"===this.tooltipsSetting)return"";if("string"==typeof t)return t;const s=e.api.Utils.i18n(t.name);if("nameOnly"===this.tooltipsSetting)return s;const i=`

${s}

`,n=t?.descriptionLocalised??await TextEditor.enrichHTML(e.api.Utils.i18n(t?.description??""),{async:!0}),a=t?.rarity?`${e.api.Utils.i18n(c[t.rarity])}`:"",l=t?.properties?`
${t.properties.map((t=>`${e.api.Utils.i18n(t)}`)).join("")}
`:"",o=t?.traits?t.traits.map((t=>`${e.api.Utils.i18n(t.label??t)}`)).join(""):"",r=t?.traits2?t.traits2.map((t=>`${e.api.Utils.i18n(t.label??t)}`)).join(""):"",d=t?.traitsAlt?t.traitsAlt.map((t=>`${e.api.Utils.i18n(t.label)}`)).join(""):"",p=t?.modifiers?`
${t.modifiers.filter((e=>e.enabled)).map((t=>`${e.api.Utils.i18n(t.label)} ${`${t.modifier>=0?"+":""}${t.modifier??""}`}`)).join("")}
`:"",u=[a,o,r,d].join(""),m=u?`
${u}
`:"";return n||m||p?`
${i}${m||p?`
${m}${p}
`:""}${n}${l}
`:s}#J(t){return t?Object.entries(t).filter((([e,t])=>t&&u[e])).map((([t,s])=>e.api.Utils.i18n(u[t]))):null}}}));let h=null;Hooks.once("tokenActionHudCoreApiReady",(async e=>{h=class MagicItemActionHandlerExtender extends e.api.ActionHandlerExtender{constructor(e){super(),this.actionHandler=e,this.actor=null}async extendActionHandler(){if(this.actor=this.actionHandler.actor,!this.actor)return;const t=await MagicItems.actor(this.actor.id);if(!t)return;const s=t.items??[];if(0===s.length)return;const i={id:"magic-items",type:"system"};s.forEach((t=>{if(t.attuned&&!this._isItemAttuned(t))return;if(t.equipped&&!this._isItemEquipped(t))return;const s={id:`magic-items_${t.id}`,name:t.name,type:"system-derived",info1:`${t.uses}/${t.charges}`};this.actionHandler.addGroup(s,i);const n=t.ownedEntries.map((s=>{const i=s.item,n=i.id;return{id:n,name:i.name,encodedValue:["magicItem",`${t.id}>${n}`].join("|"),img:e.api.Utils.getImage(i),info1:i.consumption,info2:i.baseLevel?`${e.api.Utils.i18n("DND5E.AbbreviationLevel")} ${i.baseLevel}`:"",selected:!0}}));this.actionHandler.addActions(n,s)}))}_isItemEquipped(e){return e.item.system.equipped}_isItemAttuned(e){return e.item.system.attunment!==(CONFIG.DND5E.attunementTypes?.REQUIRED??1)}}}));let g=null;Hooks.once("tokenActionHudCoreApiReady",(async e=>{g=class RollHandler extends e.api.RollHandler{async handleActionClick(t,s){const[i,n]=s.split("|");if(this.actor)await this.#Q(t,i,this.actor,this.token,n);else for(const s of e.api.Utils.getControlledTokens()){const e=s.actor;await this.#Q(t,i,e,s,n)}}async#Q(e,t,s,i,n){switch(t){case"ability":this.#x(e,s,n);break;case"check":this.#j(e,s,n);break;case"save":this.#B(e,s,n);break;case"condition":if(!i)return;await this.#q(e,s,i,n);break;case"counter":await this.#F(e,s,n);break;case"effect":await this.#_(e,s,n);break;case"exhaustion":await this.#L(e,s);break;case"feature":case"item":case"spell":case"weapon":this.isRenderItem()?this.renderItem(s,n):this.#O(e,s,n);break;case"magicItem":await this.#R(s,n);break;case"skill":this.#W(e,s,n);break;case"utility":await this.#G(e,s,i,n)}}async#F(e,t,s){switch(s){case"death-saves":this.#Z(e,t);break;case"exhaustion":await this.#L(e,t);break;case"inspiration":await this.#z(t);break;default:await this.#V(e,t,s)}}async#L(e,t){const s=this.isRightClick(e),i=t.system.attributes.exhaustion,n=s?i-1:i+1;n>=0&&t.update({"system.attributes.exhaustion":n})}async#z(e){const t=!e.system.attributes.inspiration;e.update({"system.attributes.inspiration":t})}async#V(t,s,i){if(!e.api.Utils.isModuleActive("dnd5e-custom-counters"))return;const[n,a]=decodeURIComponent(i).split(">"),l=this.isRightClick(t),o=this.isCtrl(t);let r=s.getFlag("dnd5e-custom-counters",n);switch(a){case"checkbox":await s.setFlag("dnd5e-custom-counters",n,!r);break;case"number":r=r??0,l?r>0&&await s.setFlag("dnd5e-custom-counters",n,r-1):await s.setFlag("dnd5e-custom-counters",n,r+1);break;case"successFailure":r=r??{},r.success=r?.success??0,r.failure=r?.failure??0,l?o?r?.failure>0&&await s.setFlag("dnd5e-custom-counters",`${n}.failure`,r.failure-1):r?.success>0&&await s.setFlag("dnd5e-custom-counters",`${n}.success`,r.success-1):o?await s.setFlag("dnd5e-custom-counters",`${n}.failure`,r.failure+1):await s.setFlag("dnd5e-custom-counters",`${n}.success`,r.success+1)}}#x(e,t,s){t&&t.system?.abilities&&t.rollAbility(s,{event:e})}#B(e,t,s){t&&t.system?.abilities&&t.rollAbilitySave(s,{event:e})}#j(e,t,s){t&&t.system?.abilities&&t.rollAbilityTest(s,{event:e})}#Z(e,t){t.rollDeathSave({event:e})}async#R(e,t){const s=t.split(">"),i=s[0],n=s[1];(await MagicItems.actor(e.id)).roll(i,n),Hooks.callAll("forceUpdateTokenActionHud")}#W(e,t,s){t&&t.system?.skills&&t.rollSkill(s,{event:e})}#O(t,s,i){const n=e.api.Utils.getItem(s,i);if(!this.#K(n))return n.use({event:t});n.rollRecharge()}#K(e){return e.system.recharge&&!e.system.recharge.charged&&e.system.recharge.value}async#G(e,t,s,i){switch(i){case"deathSave":this.#Z(e,t);break;case"endTurn":if(!s)break;game.combat?.current?.tokenId===s.id&&await(game.combat?.nextTurn());break;case"initiative":await this.#Y(t);break;case"inspiration":await this.#z(t);break;case"longRest":t.longRest();break;case"shortRest":t.shortRest()}Hooks.callAll("forceUpdateTokenActionHud")}async#Y(e){e&&(await e.rollInitiative({createCombatants:!0}),Hooks.callAll("forceUpdateTokenActionHud"))}async#q(e,t,s,i){if(!s)return;const n=this.isRightClick(e),a=CONFIG.statusEffects.find((e=>e.id===i)),l=a?.flags?Object.hasOwn(a.flags,"dfreds-convenient-effects")?a.flags["dfreds-convenient-effects"].isConvenient:null:i.startsWith("Convenient Effect");if(game.dfreds&&l)n?await game.dfreds.effectInterface.toggleEffect(a.name??a.label,{overlay:!0}):await game.dfreds.effectInterface.toggleEffect(a.name??a.label);else{const e=this.#X(i);if(!e)return;const a=this.#ee(t,i);a?.disabled&&await a.delete(),n?await s.toggleEffect(e,{overlay:!0}):await s.toggleEffect(e)}Hooks.callAll("forceUpdateTokenActionHud")}#X(e){return CONFIG.statusEffects.find((t=>t.id===e))}#ee(e,t){return game.version.startsWith("11")?e.effects.find((e=>e.statuses.every((e=>e===t)))):e.effects.find((e=>e.flags?.core?.statusId===t))}async#_(e,t,s){let i=("find"in t.effects.entries?t.effects.entries:t.effects).find((e=>e.id===s)),n=!0;if(!i){n=!1;for(const e of t.allApplicableEffects())e.id===s&&(i=e)}if(!i)return;this.isRightClick(e)&&n?await i.delete():await i.update({disabled:!i.disabled}),Hooks.callAll("forceUpdateTokenActionHud")}async handleActionHover(t,s){const[i,n]=s.split("|");if(!["feature","item","spell","weapon","magicItem"].includes(i))return;const a=e.api.Utils.getItem(this.actor,n);switch(t.type){case"mouseenter":case"mouseover":Hooks.call("tokenActionHudSystemActionHoverOn",t,a);break;case"mouseleave":case"mouseout":Hooks.call("tokenActionHudSystemActionHoverOff",t,a)}}}}));class RollHandlerObsidian extends g{_rollAbilityTest(e,t){OBSIDIAN.Items.roll(super.actor,{roll:"abl",abl:t})}_rollAbilitySave(e,t){OBSIDIAN.Items.roll(super.actor,{roll:"save",save:t})}_rollSkill(e,t){OBSIDIAN.Items.roll(super.actor,{roll:"skl",skl:t})}_useItem(e,t){OBSIDIAN.Items.roll(super.actor,{roll:"item",id:t})}}let f=null;function register(t){game.settings.register(e.ID,"abbreviateSkills",{name:game.i18n.localize("tokenActionHud.dnd5e.settings.abbreviateSkills.name"),hint:game.i18n.localize("tokenActionHud.dnd5e.settings.abbreviateSkills.hint"),scope:"client",config:!0,type:Boolean,default:!1,onChange:e=>{t(e)}}),game.settings.register(e.ID,"showSlowActions",{name:game.i18n.localize("tokenActionHud.dnd5e.settings.showSlowActions.name"),hint:game.i18n.localize("tokenActionHud.dnd5e.settings.showSlowActions.hint"),scope:"client",config:!0,type:Boolean,default:!0,onChange:e=>{t(e)}}),game.settings.register(e.ID,"displaySpellInfo",{name:game.i18n.localize("tokenActionHud.dnd5e.settings.displaySpellInfo.name"),hint:game.i18n.localize("tokenActionHud.dnd5e.settings.displaySpellInfo.hint"),scope:"client",config:!0,type:Boolean,default:!0,onChange:e=>{t(e)}}),game.settings.register(e.ID,"showUnchargedItems",{name:game.i18n.localize("tokenActionHud.dnd5e.settings.showUnchargedItems.name"),hint:game.i18n.localize("tokenActionHud.dnd5e.settings.showUnchargedItems.hint"),scope:"client",config:!0,type:Boolean,default:!1,onChange:e=>{t(e)}}),game.settings.register(e.ID,"showUnequippedItems",{name:game.i18n.localize("tokenActionHud.dnd5e.settings.showUnequippedItems.name"),hint:game.i18n.localize("tokenActionHud.dnd5e.settings.showUnequippedItems.hint"),scope:"client",config:!0,type:Boolean,default:!1,onChange:e=>{t(e)}}),game.settings.register(e.ID,"showUnequippedItemsNpcs",{name:game.i18n.localize("tokenActionHud.dnd5e.settings.showUnequippedItemsNpcs.name"),hint:game.i18n.localize("tokenActionHud.dnd5e.settings.showUnequippedItemsNpcs.hint"),scope:"client",config:!0,type:Boolean,default:!0,onChange:e=>{t(e)}}),game.settings.register(e.ID,"showUnpreparedSpells",{name:game.i18n.localize("tokenActionHud.dnd5e.settings.showUnpreparedSpells.name"),hint:game.i18n.localize("tokenActionHud.dnd5e.settings.showUnpreparedSpells.hint"),scope:"client",config:!0,type:Boolean,default:!1,onChange:e=>{t(e)}}),game.settings.register(e.ID,"showItemsWithoutActivationCosts",{name:game.i18n.localize("tokenActionHud.dnd5e.settings.showItemsWithoutActivationCosts.name"),hint:game.i18n.localize("tokenActionHud.dnd5e.settings.showItemsWithoutActivationCosts.hint"),scope:"client",config:!0,type:Boolean,default:!1,onChange:e=>{t(e)}})}Hooks.once("tokenActionHudCoreApiReady",(async e=>{const t=o;Object.values(t).forEach((t=>{t.name=e.api.Utils.i18n(t.name),t.listName=`Group: ${e.api.Utils.i18n(t.name)}`}));const s=Object.values(t);f={layout:[{nestId:"inventory",id:"inventory",name:e.api.Utils.i18n("DND5E.Inventory"),groups:[{...t.weapons,nestId:"inventory_weapons"},{...t.equipment,nestId:"inventory_equipment"},{...t.consumables,nestId:"inventory_consumables"},{...t.tools,nestId:"inventory_tools"},{...t.containers,nestId:"inventory_containers"},{...t.loot,nestId:"inventory_loot"}]},{nestId:"features",id:"features",name:e.api.Utils.i18n("DND5E.Features"),groups:[{...t.activeFeatures,nestId:"features_active-features"},{...t.passiveFeatures,nestId:"features_passive-features"}]},{nestId:"spells",id:"spells",name:e.api.Utils.i18n("ITEM.TypeSpellPl"),groups:[{...t.atWillSpells,nestId:"spells_at-will-spells"},{...t.innateSpells,nestId:"spells_innate-spells"},{...t.pactSpells,nestId:"spells_pact-spells"},{...t.cantrips,nestId:"spells_cantrips"},{...t._1stLevelSpells,nestId:"spells_1st-level-spells"},{...t._2ndLevelSpells,nestId:"spells_2nd-level-spells"},{...t._3rdLevelSpells,nestId:"spells_3rd-level-spells"},{...t._4thLevelSpells,nestId:"spells_4th-level-spells"},{...t._5thLevelSpells,nestId:"spells_5th-level-spells"},{...t._6thLevelSpells,nestId:"spells_6th-level-spells"},{...t._7thLevelSpells,nestId:"spells_7th-level-spells"},{...t._8thLevelSpells,nestId:"spells_8th-level-spells"},{...t._9thLevelSpells,nestId:"spells_9th-level-spells"}]},{nestId:"attributes",id:"attributes",name:e.api.Utils.i18n("DND5E.Attributes"),groups:[{...t.abilities,nestId:"attributes_abilities"},{...t.skills,nestId:"attributes_skills"}]},{nestId:"effects",id:"effects",name:e.api.Utils.i18n("DND5E.Effects"),groups:[{...t.temporaryEffects,nestId:"effects_temporary-effects"},{...t.passiveEffects,nestId:"effects_passive-effects"},{...t.conditions,nestId:"effects_conditions"}]},{nestId:"utility",id:"utility",name:e.api.Utils.i18n("tokenActionHud.utility"),groups:[{...t.combat,nestId:"utility_combat"},{...t.token,nestId:"utility_token"},{...t.rests,nestId:"utility_rests"},{...t.utility,nestId:"utility_utility"}]}],groups:s}}));let v=null;Hooks.once("tokenActionHudCoreApiReady",(async e=>{v=class SystemManager extends e.api.SystemManager{getActionHandler(){const t=new y;return(e.api.Utils.isModuleActive("magic-items-2")||e.api.Utils.isModuleActive("magicitems"))&&t.addActionHandlerExtender(new h(t)),t}getAvailableRollHandlers(){let t="Core D&D5e";e.api.Utils.isModuleActive("midi-qol")&&(t+=` [supports ${e.api.Utils.getModuleTitle("midi-qol")}]`);const s={core:t};return e.api.SystemManager.addHandler(s,"obsidian"),s}getRollHandler(e){let t;if("obsidian"===e)t=new RollHandlerObsidian;else t=new g;return t}registerSettings(e){register(e)}async registerDefaults(){const t=f;if(game.modules.get("magicitems")?.active||game.modules.get("magic-items-2")?.active){const s=e.api.Utils.i18n("tokenActionHud.dnd5e.magicItems");t.groups.push({id:"magic-items",name:s,listName:`Group: ${s}`,type:"system"}),t.groups.sort(((e,t)=>e.id.localeCompare(t.id)))}return t}}})),Hooks.on("tokenActionHudCoreApiReady",(async()=>{const t=game.modules.get(e.ID);t.api={requiredCoreModuleVersion:"1.5",SystemManager:v},Hooks.call("tokenActionHudSystemReady",t)}));export{i as ACTION_TYPE,n as ACTIVATION_TYPE_ICON,y as ActionHandler,a as CONCENTRATION_ICON,l as CONDITION,t as CORE_MODULE,f as DEFAULTS,o as GROUP,e as MODULE,h as MagicItemActionHandlerExtender,r as PREPARED_ICON,d as PROFICIENCY_LEVEL_ICON,c as RARITY,s as REQUIRED_CORE_MODULE_VERSION,p as RITUAL_ICON,g as RollHandler,RollHandlerObsidian,v as SystemManager,m as Utils,u as WEAPON_PROPERTY,register}; +//# sourceMappingURL=token-action-hud-dnd5e.min.js.map diff --git a/scripts/token-action-hud-dnd5e.min.js.map b/scripts/token-action-hud-dnd5e.min.js.map new file mode 100644 index 0000000..f14d79f --- /dev/null +++ b/scripts/token-action-hud-dnd5e.min.js.map @@ -0,0 +1 @@ +{"version":3,"file":"token-action-hud-dnd5e.min.js","sources":["constants.js","utils.js","action-handler.js","magic-items-extender.js","roll-handler.js","roll-handler-obsidian.js","defaults.js","settings.js","system-manager.js","init.js"],"sourcesContent":["/**\r\n * Module-based constants\r\n */\r\nexport const MODULE = {\r\n ID: 'token-action-hud-dnd5e'\r\n}\r\n\r\n/**\r\n * Core module\r\n */\r\nexport const CORE_MODULE = {\r\n ID: 'token-action-hud-core'\r\n}\r\n\r\n/**\r\n * Core module version required by the system module\r\n */\r\nexport const REQUIRED_CORE_MODULE_VERSION = '1.5'\r\n\r\n/**\r\n * Action type\r\n */\r\nexport const ACTION_TYPE = {\r\n ability: 'DND5E.Ability',\r\n check: 'tokenActionHud.dnd5e.check',\r\n condition: 'tokenActionHud.dnd5e.condition',\r\n counter: 'tokenActionHud.dnd5e.counter',\r\n effect: 'DND5E.Effect',\r\n exhaustion: 'DND5E.Exhaustion',\r\n feature: 'ITEM.TypeFeat',\r\n item: 'tokenActionHud.dnd5e.item',\r\n save: 'DND5E.ActionSave',\r\n skill: 'tokenActionHud.dnd5e.skill',\r\n spell: 'ITEM.TypeSpell',\r\n utility: 'DND5E.ActionUtil'\r\n}\r\n\r\n/**\r\n * Activation type icons\r\n */\r\nexport const ACTIVATION_TYPE_ICON = {\r\n bonus: 'fas fa-plus',\r\n crew: 'fas fa-users',\r\n day: 'fas fa-hourglass-end',\r\n hour: 'fas fa-hourglass-half',\r\n lair: 'fas fa-home',\r\n minute: 'fas fa-hourglass-start',\r\n legendary: 'fas fas fa-dragon',\r\n reaction: 'fas fa-bolt',\r\n special: 'fas fa-star'\r\n}\r\n\r\n/**\r\n * Concentration icon\r\n */\r\nexport const CONCENTRATION_ICON = 'systems/dnd5e/icons/svg/statuses/concentrating.svg'\r\n\r\n/**\r\n * Conditions\r\n */\r\nexport const CONDITION = {\r\n blind: { uuid: 'Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.0b8N4FymGGfbZGpJ' },\r\n blinded: { uuid: 'Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.0b8N4FymGGfbZGpJ' },\r\n 'Convenient Effect: Blinded': { uuid: 'Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.0b8N4FymGGfbZGpJ' },\r\n charmed: { uuid: 'Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.zZaEBrKkr66OWJvD' },\r\n 'Convenient Effect: Charmed': { uuid: 'Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.zZaEBrKkr66OWJvD' },\r\n deaf: { uuid: 'Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.6G8JSjhn701cBITY' },\r\n deafened: { uuid: 'Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.6G8JSjhn701cBITY' },\r\n 'Convenient Effect: Deafened': { uuid: 'Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.6G8JSjhn701cBITY' },\r\n fear: { uuid: 'Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.oreoyaFKnvZCrgij' },\r\n 'Convenient Effect: Frightened': { uuid: 'Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.oreoyaFKnvZCrgij' },\r\n frightened: { uuid: 'Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.oreoyaFKnvZCrgij' },\r\n grappled: { uuid: 'Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.gYDAhd02ryUmtwZn' },\r\n 'Convenient Effect: Grappled': { uuid: 'Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.gYDAhd02ryUmtwZn' },\r\n incapacitated: { uuid: 'Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.TpkZgLfxCmSndmpb' },\r\n 'Convenient Effect: Incapacitated': { uuid: 'Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.TpkZgLfxCmSndmpb' },\r\n invisible: { uuid: 'Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.3UU5GCTVeRDbZy9u' },\r\n 'Convenient Effect: Invisible': { uuid: 'Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.3UU5GCTVeRDbZy9u' },\r\n paralysis: { uuid: 'Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.xnSV5hLJIMaTABXP' },\r\n paralyzed: { uuid: 'Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.xnSV5hLJIMaTABXP' },\r\n 'Convenient Effect: Paralyzed': { uuid: 'Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.xnSV5hLJIMaTABXP' },\r\n petrified: { uuid: 'Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.xaNDaW6NwQTgHSmi' },\r\n 'Convenient Effect: Petrified': { uuid: 'Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.xaNDaW6NwQTgHSmi' },\r\n poison: { uuid: 'Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.lq3TRI6ZlED8ABMx' },\r\n poisoned: { uuid: 'Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.lq3TRI6ZlED8ABMx' },\r\n 'Convenient Effect: Poisoned': { uuid: 'Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.lq3TRI6ZlED8ABMx' },\r\n prone: { uuid: 'Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.y0TkcdyoZlOTmAFT' },\r\n 'Convenient Effect: Prone': { uuid: 'Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.y0TkcdyoZlOTmAFT' },\r\n restrain: { uuid: 'Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.cSVcyZyNe2iG1fIc' },\r\n restrained: { uuid: 'Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.cSVcyZyNe2iG1fIc' },\r\n 'Convenient Effect: Restrained': { uuid: 'Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.cSVcyZyNe2iG1fIc' },\r\n stun: { uuid: 'Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.ZyZMUwA2rboh4ObS' },\r\n stunned: { uuid: 'Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.ZyZMUwA2rboh4ObS' },\r\n 'Convenient Effect: Stunned': { uuid: 'Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.ZyZMUwA2rboh4ObS' },\r\n unconscious: { uuid: 'Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.UWw13ISmMxDzmwbd' },\r\n 'Convenient Effect: Unconscious': { uuid: 'Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.UWw13ISmMxDzmwbd' },\r\n exhaustion: { uuid: 'Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.cspWveykstnu3Zcv' },\r\n 'Convenient Effect: Exhaustion 1': { uuid: 'Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.cspWveykstnu3Zcv' },\r\n 'Convenient Effect: Exhaustion 2': { uuid: 'Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.cspWveykstnu3Zcv' },\r\n 'Convenient Effect: Exhaustion 3': { uuid: 'Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.cspWveykstnu3Zcv' },\r\n 'Convenient Effect: Exhaustion 4': { uuid: 'Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.cspWveykstnu3Zcv' },\r\n 'Convenient Effect: Exhaustion 5': { uuid: 'Compendium.dnd5e.rules.JournalEntry.w7eitkpD7QQTB6j0.JournalEntryPage.cspWveykstnu3Zcv' }\r\n}\r\n\r\n/**\r\n * Groups\r\n */\r\nexport const GROUP = {\r\n _1stLevelSpells: { id: '1st-level-spells', name: 'tokenActionHud.dnd5e.1stLevelSpells', type: 'system' },\r\n _2ndLevelSpells: { id: '2nd-level-spells', name: 'tokenActionHud.dnd5e.2ndLevelSpells', type: 'system' },\r\n _3rdLevelSpells: { id: '3rd-level-spells', name: 'tokenActionHud.dnd5e.3rdLevelSpells', type: 'system' },\r\n _4thLevelSpells: { id: '4th-level-spells', name: 'tokenActionHud.dnd5e.4thLevelSpells', type: 'system' },\r\n _5thLevelSpells: { id: '5th-level-spells', name: 'tokenActionHud.dnd5e.5thLevelSpells', type: 'system' },\r\n _6thLevelSpells: { id: '6th-level-spells', name: 'tokenActionHud.dnd5e.6thLevelSpells', type: 'system' },\r\n _7thLevelSpells: { id: '7th-level-spells', name: 'tokenActionHud.dnd5e.7thLevelSpells', type: 'system' },\r\n _8thLevelSpells: { id: '8th-level-spells', name: 'tokenActionHud.dnd5e.8thLevelSpells', type: 'system' },\r\n _9thLevelSpells: { id: '9th-level-spells', name: 'tokenActionHud.dnd5e.9thLevelSpells', type: 'system' },\r\n abilities: { id: 'abilities', name: 'tokenActionHud.dnd5e.abilities', type: 'system' },\r\n actions: { id: 'actions', name: 'DND5E.ActionPl', type: 'system' },\r\n activeFeatures: { id: 'active-features', name: 'tokenActionHud.dnd5e.activeFeatures', type: 'system' },\r\n artificerInfusions: { id: 'artificer-infusions', name: 'tokenActionHud.dnd5e.artificerInfusions', type: 'system' },\r\n atWillSpells: { id: 'at-will-spells', name: 'tokenActionHud.dnd5e.atWillSpells', type: 'system' },\r\n backgroundFeatures: { id: 'background-features', name: 'tokenActionHud.dnd5e.backgroundFeatures', type: 'system' },\r\n bonusActions: { id: 'bonus-actions', name: 'tokenActionHud.dnd5e.bonusActions', type: 'system' },\r\n cantrips: { id: 'cantrips', name: 'tokenActionHud.dnd5e.cantrips', type: 'system' },\r\n channelDivinity: { id: 'channel-divinity', name: 'tokenActionHud.dnd5e.channelDivinity', type: 'system' },\r\n checks: { id: 'checks', name: 'tokenActionHud.dnd5e.checks', type: 'system' },\r\n classFeatures: { id: 'class-features', name: 'tokenActionHud.dnd5e.classFeatures', type: 'system' },\r\n combat: { id: 'combat', name: 'tokenActionHud.combat', type: 'system' },\r\n conditions: { id: 'conditions', name: 'tokenActionHud.dnd5e.conditions', type: 'system' },\r\n consumables: { id: 'consumables', name: 'ITEM.TypeConsumablePl', type: 'system' },\r\n containers: { id: 'containers', name: 'ITEM.TypeContainerPl', type: 'system' },\r\n counters: { id: 'counters', name: 'tokenActionHud.dnd5e.counters', type: 'system' },\r\n crewActions: { id: 'crew-actions', name: 'tokenActionHud.dnd5e.crewActions', type: 'system' },\r\n defensiveTactics: { id: 'defensive-tactics', name: 'tokenActionHud.dnd5e.defensiveTactics', type: 'system' },\r\n eldritchInvocations: { id: 'eldritch-invocations', name: 'tokenActionHud.dnd5e.eldritchInvocations', type: 'system' },\r\n elementalDisciplines: { id: 'elemental-disciplines', name: 'tokenActionHud.dnd5e.elementalDisciplines', type: 'system' },\r\n equipment: { id: 'equipment', name: 'ITEM.TypeEquipmentPl', type: 'system' },\r\n equipped: { id: 'equipped', name: 'DND5E.Equipped', type: 'system' },\r\n exhaustion: { id: 'exhaustion', name: 'DND5E.Exhaustion', type: 'system' },\r\n feats: { id: 'feats', name: 'tokenActionHud.dnd5e.feats', type: 'system' },\r\n fightingStyles: { id: 'fighting-styles', name: 'tokenActionHud.dnd5e.fightingStyles', type: 'system' },\r\n huntersPrey: { id: 'hunters-prey', name: 'tokenActionHud.dnd5e.huntersPrey', type: 'system' },\r\n innateSpells: { id: 'innate-spells', name: 'tokenActionHud.dnd5e.innateSpells', type: 'system' },\r\n kiAbilities: { id: 'ki-abilities', name: 'tokenActionHud.dnd5e.kiAbilities', type: 'system' },\r\n lairActions: { id: 'lair-actions', name: 'tokenActionHud.dnd5e.lairActions', type: 'system' },\r\n legendaryActions: { id: 'legendary-actions', name: 'tokenActionHud.dnd5e.legendaryActions', type: 'system' },\r\n loot: { id: 'loot', name: 'ITEM.TypeLootPl', type: 'system' },\r\n maneuvers: { id: 'maneuvers', name: 'tokenActionHud.dnd5e.maneuvers', type: 'system' },\r\n metamagicOptions: { id: 'metamagic-options', name: 'tokenActionHud.dnd5e.metamagicOptions', type: 'system' },\r\n monsterFeatures: { id: 'monster-features', name: 'tokenActionHud.dnd5e.monsterFeatures', type: 'system' },\r\n multiattacks: { id: 'multiattacks', name: 'tokenActionHud.dnd5e.multiattacks', type: 'system' },\r\n otherActions: { id: 'other-actions', name: 'tokenActionHud.dnd5e.otherActions', type: 'system' },\r\n pactBoons: { id: 'pact-boons', name: 'tokenActionHud.dnd5e.pactBoons', type: 'system' },\r\n pactSpells: { id: 'pact-spells', name: 'tokenActionHud.dnd5e.pactSpells', type: 'system' },\r\n passiveEffects: { id: 'passive-effects', name: 'DND5E.EffectPassive', type: 'system' },\r\n passiveFeatures: { id: 'passive-features', name: 'tokenActionHud.dnd5e.passiveFeatures', type: 'system' },\r\n psionicPowers: { id: 'psionic-powers', name: 'tokenActionHud.dnd5e.psionicPowers', type: 'system' },\r\n raceFeatures: { id: 'race-features', name: 'tokenActionHud.dnd5e.raceFeatures', type: 'system' },\r\n reactions: { id: 'reactions', name: 'DND5E.ReactionPl', type: 'system' },\r\n rests: { id: 'rests', name: 'tokenActionHud.dnd5e.rests', type: 'system' },\r\n runes: { id: 'runes', name: 'tokenActionHud.dnd5e.runes', type: 'system' },\r\n saves: { id: 'saves', name: 'DND5E.ClassSaves', type: 'system' },\r\n skills: { id: 'skills', name: 'tokenActionHud.dnd5e.skills', type: 'system' },\r\n superiorHuntersDefense: { id: 'superior-hunters-defense', name: 'tokenActionHud.dnd5e.superiorHuntersDefense', type: 'system' },\r\n temporaryEffects: { id: 'temporary-effects', name: 'DND5E.EffectTemporary', type: 'system' },\r\n token: { id: 'token', name: 'tokenActionHud.token', type: 'system' },\r\n tools: { id: 'tools', name: 'ITEM.TypeToolPl', type: 'system' },\r\n unequipped: { id: 'unequipped', name: 'DND5E.Unequipped', type: 'system' },\r\n utility: { id: 'utility', name: 'tokenActionHud.utility', type: 'system' },\r\n weapons: { id: 'weapons', name: 'ITEM.TypeWeaponPl', type: 'system' }\r\n}\r\n\r\n/**\r\n * Prepared icon\r\n */\r\nexport const PREPARED_ICON = 'fas fa-sun'\r\n\r\n/**\r\n * Proficiency level icons\r\n */\r\nexport const PROFICIENCY_LEVEL_ICON = {\r\n 0.5: 'fas fa-adjust',\r\n 1: 'fas fa-check',\r\n 2: 'fas fa-check-double'\r\n}\r\n\r\n/**\r\n * Rarity\r\n */\r\nexport const RARITY = {\r\n common: 'tokenActionHud.dnd5e.common',\r\n uncommon: 'tokenActionHud.dnd5e.uncommon',\r\n rare: 'tokenActionHud.dnd5e.rare',\r\n veryRare: 'tokenActionHud.dnd5e.veryRare',\r\n legendary: 'tokenActionHud.dnd5e.legendary',\r\n artifact: 'tokenActionHud.dnd5e.artifact'\r\n}\r\n\r\n/**\r\n * Ritual icon\r\n */\r\nexport const RITUAL_ICON = 'fas fa-circle-r'\r\n\r\n/**\r\n * Weapon properties\r\n */\r\nexport const WEAPON_PROPERTY = {\r\n ada: 'DND5E.WeaponPropertiesAda',\r\n amm: 'DND5E.WeaponPropertiesAmm',\r\n fin: 'DND5E.WeaponPropertiesFin',\r\n fir: 'DND5E.WeaponPropertiesFir',\r\n foc: 'DND5E.WeaponPropertiesFoc',\r\n hvy: 'DND5E.WeaponPropertiesHvy',\r\n lgt: 'DND5E.WeaponPropertiesLgt',\r\n lod: 'DND5E.WeaponPropertiesLod',\r\n mgc: 'DND5E.WeaponPropertiesMgc',\r\n rch: 'DND5E.WeaponPropertiesRch',\r\n rel: 'DND5E.WeaponPropertiesRel',\r\n ret: 'DND5E.WeaponPropertiesRet',\r\n sil: 'DND5E.WeaponPropertiesSil',\r\n spc: 'DND5E.WeaponPropertiesSpc',\r\n thr: 'DND5E.WeaponPropertiesThr',\r\n two: 'DND5E.WeaponPropertiesTwo',\r\n ver: 'DND5E.WeaponPropertiesVer'\r\n}\r\n","import { MODULE } from './constants.js'\r\n\r\nexport let Utils = null\r\n\r\nHooks.once('tokenActionHudCoreApiReady', async (coreModule) => {\r\n Utils = class Utils {\r\n /**\r\n * Get setting value\r\n * @param {string} key The key\r\n * @param {string=null} defaultValue The default value\r\n * @returns The setting value\r\n */\r\n static getSetting (key, defaultValue = null) {\r\n let value = defaultValue ?? null\r\n try {\r\n value = game.settings.get(MODULE.ID, key)\r\n } catch {\r\n coreModule.api.Logger.debug(`Setting '${key}' not found`)\r\n }\r\n return value\r\n }\r\n\r\n /**\r\n * Set setting value\r\n * @param {string} key The key\r\n * @param {string} value The value\r\n */\r\n static async setSetting (key, value) {\r\n try {\r\n value = await game.settings.set(MODULE.ID, key, value)\r\n coreModule.api.Logger.debug(`Setting '${key}' set to '${value}'`)\r\n } catch {\r\n coreModule.api.Logger.debug(`Setting '${key}' not found`)\r\n }\r\n }\r\n }\r\n})\r\n","// System Module Imports\r\nimport { ACTIVATION_TYPE_ICON, ACTION_TYPE, CONCENTRATION_ICON, CONDITION, PREPARED_ICON, PROFICIENCY_LEVEL_ICON, RARITY, WEAPON_PROPERTY } from './constants.js'\r\nimport { Utils } from './utils.js'\r\n\r\nexport let ActionHandler = null\r\n\r\nHooks.once('tokenActionHudCoreApiReady', async (coreModule) => {\r\n ActionHandler = class ActionHandler extends coreModule.api.ActionHandler {\r\n // Initialize actor and token variables\r\n actors = null\r\n tokens = null\r\n actorType = null\r\n\r\n // Initialize items variable\r\n items = null\r\n\r\n // Initialize setting variables\r\n abbreviateSkills = null\r\n displaySpellInfo = null\r\n showItemsWithoutActivationCosts = null\r\n showUnchargedItems = null\r\n showUnequippedItems = null\r\n showUnpreparedSpells = null\r\n\r\n // Initialize groupIds variables\r\n activationgroupIds = null\r\n featuregroupIds = null\r\n inventorygroupIds = null\r\n spellgroupIds = null\r\n\r\n // Initialize action variables\r\n featureActions = null\r\n inventoryActions = null\r\n spellActions = null\r\n\r\n systemVersion = game.dnd5e.version\r\n\r\n /**\r\n * Build System Actions\r\n * @override\r\n * @param {array} groupIds\r\n * @returns {object}\r\n */\r\n async buildSystemActions (groupIds) {\r\n // Set actor and token variables\r\n this.actors = (!this.actor) ? this.#getActors() : [this.actor]\r\n this.tokens = (!this.token) ? this.#getTokens() : [this.token]\r\n this.actorType = this.actor?.type\r\n\r\n // Set items variable\r\n if (this.actor) {\r\n let items = this.actor.items\r\n items = this.#discardSlowItems(items)\r\n items = coreModule.api.Utils.sortItemsByName(items)\r\n this.items = items\r\n }\r\n\r\n // Set settings variables\r\n this.abbreviateSkills = Utils.getSetting('abbreviateSkills')\r\n this.displaySpellInfo = Utils.getSetting('displaySpellInfo')\r\n this.showItemsWithoutActivationCosts = Utils.getSetting('showItemsWithoutActivationCosts')\r\n this.showUnchargedItems = Utils.getSetting('showUnchargedItems')\r\n this.showUnequippedItems = Utils.getSetting('showUnequippedItems')\r\n if (this.actorType === 'npc' && !this.showUnequippedItems) {\r\n this.showUnequippedItems = Utils.getSetting('showUnequippedItemsNpcs')\r\n }\r\n this.showUnpreparedSpells = Utils.getSetting('showUnpreparedSpells')\r\n\r\n this.activationgroupIds = [\r\n 'actions',\r\n 'bonus-actions',\r\n 'crew-actions',\r\n 'lair-actions',\r\n 'legendary-actions',\r\n 'reactions',\r\n 'other-actions'\r\n ]\r\n\r\n this.featuregroupIds = [\r\n 'active-features',\r\n 'passive-features',\r\n 'background-features',\r\n 'class-features',\r\n 'feats',\r\n 'monster-features',\r\n 'race-features',\r\n 'artificer-infusions',\r\n 'channel-divinity',\r\n 'defensive-tactics',\r\n 'eldritch-invocations',\r\n 'elemental-disciplines',\r\n 'fighting-styles',\r\n 'hunters-prey',\r\n 'ki-abilities',\r\n 'maneuvers',\r\n 'metamagic-options',\r\n 'multiattacks',\r\n 'pact-boons',\r\n 'psionic-powers',\r\n 'runes',\r\n 'superior-hunters-defense'\r\n ]\r\n\r\n this.spellgroupIds = [\r\n 'cantrips',\r\n '1st-level-spells',\r\n '2nd-level-spells',\r\n '3rd-level-spells',\r\n '4th-level-spells',\r\n '5th-level-spells',\r\n '6th-level-spells',\r\n '7th-level-spells',\r\n '8th-level-spells',\r\n '9th-level-spells',\r\n 'at-will-spells',\r\n 'innate-spells',\r\n 'pact-spells'\r\n ]\r\n\r\n if (this.actorType === 'character' || this.actorType === 'npc') {\r\n this.inventorygroupIds = [\r\n 'equipped',\r\n 'consumables',\r\n 'containers',\r\n 'equipment',\r\n 'loot',\r\n 'tools',\r\n 'weapons',\r\n 'unequipped'\r\n ]\r\n\r\n await this.#buildCharacterActions()\r\n } else if (this.actorType === 'vehicle') {\r\n this.inventorygroupIds = [\r\n 'consumables',\r\n 'equipment',\r\n 'tools',\r\n 'weapons'\r\n ]\r\n\r\n await this.#buildVehicleActions()\r\n } else if (!this.actor) {\r\n await this.#buildMultipleTokenActions()\r\n }\r\n }\r\n\r\n /**\r\n * Build character actions\r\n * @private\r\n * @returns {object}\r\n */\r\n async #buildCharacterActions () {\r\n await Promise.all([\r\n this.#buildConditions(),\r\n this.#buildEffects(),\r\n this.#buildFeatures(),\r\n this.#buildInventory(),\r\n this.#buildSpells()\r\n ])\r\n this.#buildAbilities('ability', 'abilities')\r\n this.#buildAbilities('check', 'checks')\r\n this.#buildAbilities('save', 'saves')\r\n this.#buildCombat()\r\n this.#buildCounters()\r\n this.#buildExhaustion()\r\n this.#buildRests()\r\n this.#buildSkills()\r\n this.#buildUtility()\r\n }\r\n\r\n /**\r\n * Build vehicle actions\r\n * @private\r\n * @returns {object}\r\n */\r\n async #buildVehicleActions () {\r\n await Promise.all([\r\n this.#buildConditions(),\r\n this.#buildEffects(),\r\n this.#buildFeatures(),\r\n this.#buildInventory()\r\n ])\r\n this.#buildAbilities('ability', 'abilities')\r\n this.#buildAbilities('check', 'checks')\r\n this.#buildAbilities('save', 'saves')\r\n this.#buildCombat()\r\n this.#buildUtility()\r\n }\r\n\r\n /**\r\n * Build multiple token actions\r\n * @private\r\n * @returns {object}\r\n */\r\n async #buildMultipleTokenActions () {\r\n this.#buildAbilities('ability', 'abilities')\r\n this.#buildAbilities('check', 'checks')\r\n this.#buildAbilities('save', 'saves')\r\n this.#buildCombat()\r\n await this.#buildConditions()\r\n this.#buildRests()\r\n this.#buildSkills()\r\n this.#buildUtility()\r\n }\r\n\r\n /**\r\n * Build abilities\r\n * @private\r\n * @param {string} actionType\r\n * @param {string} groupId\r\n */\r\n #buildAbilities (actionType, groupId) {\r\n // Get abilities\r\n const abilities = (!this.actor) ? CONFIG.DND5E.abilities : this.actor.system.abilities\r\n\r\n // Exit if no abilities exist\r\n if (abilities.length === 0) return\r\n\r\n // Get actions\r\n const actions = Object.entries(abilities)\r\n .filter((ability) => abilities[ability[0]].value !== 0)\r\n .map(([abilityId, ability]) => {\r\n const id = `${actionType}-${abilityId}`\r\n const abbreviatedName = abilityId.charAt(0).toUpperCase() + abilityId.slice(1)\r\n const label = this.systemVersion >= '2.2' ? CONFIG.DND5E.abilities[abilityId].label : CONFIG.DND5E.abilities[abilityId]\r\n const name = this.abbreviateSkills ? abbreviatedName : label\r\n // Localise\r\n const actionTypeName = `${coreModule.api.Utils.i18n(ACTION_TYPE[actionType])}: ` ?? ''\r\n const listName = `${actionTypeName}${label}`\r\n const encodedValue = [actionType, abilityId].join(this.delimiter)\r\n const icon1 = (groupId !== 'checks') ? this.#getProficiencyIcon(abilities[abilityId].proficient) : ''\r\n const mod = (groupId !== 'saves') ? ability?.mod : ((groupId === 'saves') ? ability?.save : '')\r\n const info1 = (this.actor) ? { text: coreModule.api.Utils.getModifier(mod) } : null\r\n const info2 = (this.actor && groupId === 'abilities') ? { text: `(${coreModule.api.Utils.getModifier(ability?.save)})` } : null\r\n return {\r\n id,\r\n name,\r\n encodedValue,\r\n icon1,\r\n info1,\r\n info2,\r\n listName\r\n }\r\n })\r\n\r\n // Create group data\r\n const groupData = { id: groupId, type: 'system' }\r\n\r\n // Add actions to action list\r\n this.addActions(actions, groupData)\r\n }\r\n\r\n /**\r\n * Build activations\r\n * @public\r\n * @param {object} data groupData, actionData, actionType\r\n */\r\n async buildActivations (data) {\r\n const { groupData, actionData, actionType = 'item' } = data\r\n\r\n // Create map of items according to activation type\r\n const activationItems = new Map()\r\n\r\n // Create activation type mappings\r\n const activationTypeMappings = {\r\n action: 'actions',\r\n bonus: 'bonus-actions',\r\n crew: 'crew-actions',\r\n lair: 'lair-actions',\r\n legendary: 'legendary-actions',\r\n reaction: 'reactions',\r\n reactiondamage: 'reactions',\r\n reactionmanual: 'reactions',\r\n other: 'other-actions'\r\n }\r\n\r\n // Loop through items\r\n for (const [key, value] of actionData) {\r\n const activationType = value.system?.activation?.type\r\n const activationTypeOther = (Object.keys(activationTypeMappings).includes(activationType)) ? activationType : 'other'\r\n const groupId = activationTypeMappings[activationTypeOther]\r\n if (!activationItems.has(groupId)) activationItems.set(groupId, new Map())\r\n activationItems.get(groupId).set(key, value)\r\n }\r\n\r\n // Loop through action group ids\r\n for (const activationGroupId of this.activationgroupIds) {\r\n // Skip if no items exist\r\n if (!activationItems.has(activationGroupId)) continue\r\n\r\n // Clone and add to group data\r\n const groupDataClone = { ...groupData, id: `${activationGroupId}+${groupData.id}`, type: 'system-derived' }\r\n\r\n // Set Equipped and Unequipped groups to not selected by default\r\n if (['equipped', 'unequipped'].includes(groupData.id)) { groupDataClone.defaultSelected = false }\r\n\r\n // Create parent group data\r\n const parentgroupData = { id: activationGroupId, type: 'system' }\r\n\r\n // Add group to HUD\r\n await this.addGroup(groupDataClone, parentgroupData)\r\n\r\n // Add spell slot info to group\r\n if (actionType === 'spell') {\r\n this.addGroupInfo(groupDataClone)\r\n }\r\n\r\n const actionData = activationItems.get(activationGroupId)\r\n\r\n // Build actions\r\n await this.buildActions({ groupData: groupDataClone, actionData, actionType })\r\n }\r\n }\r\n\r\n /**\r\n * Build combat\r\n * @private\r\n */\r\n #buildCombat () {\r\n const actionType = 'utility'\r\n\r\n // Set combat types\r\n const combatTypes = {\r\n initiative: { id: 'initiative', name: coreModule.api.Utils.i18n('tokenActionHud.dnd5e.rollInitiative') },\r\n endTurn: { id: 'endTurn', name: coreModule.api.Utils.i18n('tokenActionHud.endTurn') }\r\n }\r\n\r\n // Delete endTurn for multiple tokens\r\n if (game.combat?.current?.tokenId !== this.token?.id) delete combatTypes.endTurn\r\n\r\n // Get actions\r\n const actions = Object.entries(combatTypes).map((combatType) => {\r\n const id = combatType[1].id\r\n const name = combatType[1].name\r\n const actionTypeName = `${coreModule.api.Utils.i18n(ACTION_TYPE[actionType])}: ` ?? ''\r\n const listName = `${actionTypeName}${name}`\r\n const encodedValue = [actionType, id].join(this.delimiter)\r\n const info1 = {}\r\n let cssClass = ''\r\n if (combatType[0] === 'initiative' && game.combat) {\r\n const tokens = coreModule.api.Utils.getControlledTokens()\r\n const tokenIds = tokens?.map((token) => token.id)\r\n const combatants = game.combat.combatants.filter((combatant) => tokenIds.includes(combatant.tokenId))\r\n\r\n // Get initiative for single token\r\n if (combatants.length === 1) {\r\n const currentInitiative = combatants[0].initiative\r\n info1.class = 'tah-spotlight'\r\n info1.text = currentInitiative\r\n }\r\n\r\n const active = combatants.length > 0 && (combatants.every((combatant) => combatant?.initiative)) ? ' active' : ''\r\n cssClass = `toggle${active}`\r\n }\r\n return {\r\n id,\r\n name,\r\n encodedValue,\r\n info1,\r\n cssClass,\r\n listName\r\n }\r\n })\r\n\r\n // Create group data\r\n const groupData = { id: 'combat', type: 'system' }\r\n\r\n // Add actions to HUD\r\n this.addActions(actions, groupData)\r\n }\r\n\r\n /**\r\n * Build conditions\r\n * @private\r\n */\r\n async #buildConditions () {\r\n if (this.tokens?.length === 0) return\r\n\r\n const actionType = 'condition'\r\n\r\n // Get conditions\r\n const conditions = CONFIG.statusEffects.filter((condition) => condition.id !== '')\r\n\r\n // Exit if no conditions exist\r\n if (conditions.length === 0) return\r\n\r\n // Get actions\r\n const actions = await Promise.all(conditions.map(async (condition) => {\r\n const id = condition.id\r\n const name = coreModule.api.Utils.i18n(condition.label) ?? condition.name\r\n const actionTypeName = `${coreModule.api.Utils.i18n(ACTION_TYPE[actionType])}: ` ?? ''\r\n const listName = `${actionTypeName}${name}`\r\n const encodedValue = [actionType, id].join(this.delimiter)\r\n const active = this.actors.every((actor) => {\r\n if (game.version.startsWith('11')) {\r\n return actor.effects.some(effect => effect.statuses.some(status => status === id) && !effect?.disabled)\r\n } else {\r\n // V10\r\n return actor.effects.some(effect => effect.flags?.core?.statusId === id && !effect?.disabled)\r\n }\r\n })\r\n ? ' active'\r\n : ''\r\n const cssClass = `toggle${active}`\r\n const img = coreModule.api.Utils.getImage(condition)\r\n const tooltipData = await this.#getConditionTooltipData(id, name)\r\n const tooltip = await this.#getTooltip(tooltipData)\r\n return {\r\n id,\r\n name,\r\n encodedValue,\r\n img,\r\n cssClass,\r\n listName,\r\n tooltip\r\n }\r\n }))\r\n\r\n // Create group data\r\n const groupData = { id: 'conditions', type: 'system' }\r\n\r\n // Add actions to HUD\r\n this.addActions(actions, groupData)\r\n }\r\n\r\n /**\r\n * Build counters\r\n * @private\r\n */\r\n async #buildCounters () {\r\n if (this.actorType !== 'character') return\r\n\r\n const actionType = 'counter'\r\n\r\n // Get counters\r\n let counters = []\r\n\r\n if (coreModule.api.Utils.isModuleActive('dnd5e-custom-counters')) {\r\n if (this.actorType === 'character') {\r\n counters = Object.entries(game.settings.get('dnd5e-custom-counters', 'characterCounters'))\r\n .filter(([_, value]) => value.visible)\r\n .map(([key, value]) => {\r\n value.key = key\r\n return value\r\n })\r\n } else {\r\n return\r\n }\r\n } else {\r\n counters = [\r\n {\r\n name: coreModule.api.Utils.i18n('DND5E.DeathSave'),\r\n type: 'successFailure',\r\n system: true,\r\n visible: true,\r\n key: 'death-saves'\r\n },\r\n {\r\n name: coreModule.api.Utils.i18n('DND5E.Exhaustion'),\r\n type: 'number',\r\n system: true,\r\n visible: true,\r\n key: 'exhaustion'\r\n },\r\n {\r\n name: coreModule.api.Utils.i18n('DND5E.Inspiration'),\r\n type: 'checkbox',\r\n system: true,\r\n visible: true,\r\n key: 'inspiration'\r\n }\r\n ]\r\n }\r\n\r\n // Get actions\r\n const actions = counters.map(counter => {\r\n const id = counter.key\r\n const name = counter.name\r\n const actionTypeName = `${coreModule.api.Utils.i18n(ACTION_TYPE[actionType])}: ` ?? ''\r\n const listName = `${actionTypeName}${name}`\r\n const value = (counter.system) ? id : encodeURIComponent(`${id}>${counter.type}`)\r\n const encodedValue = [actionType, value].join(this.delimiter)\r\n let active = ''\r\n let cssClass = ''\r\n let img = ''\r\n let info1 = ''\r\n if (counter.system) {\r\n switch (id) {\r\n case 'exhaustion':\r\n active = (this.actor.system.attributes.exhaustion > 0) ? ' active' : ''\r\n cssClass = `toggle${active}`\r\n img = coreModule.api.Utils.getImage('modules/token-action-hud-dnd5e/icons/exhaustion.svg')\r\n info1 = { text: this.actor.system.attributes.exhaustion }\r\n break\r\n case 'death-saves':\r\n img = coreModule.api.Utils.getImage('modules/token-action-hud-dnd5e/icons/death-saves.svg')\r\n info1 = { text: `${this.actor.system.attributes.death.success}/${this.actor.system.attributes.death.failure}` }\r\n break\r\n case 'inspiration':\r\n active = (this.actor.system.attributes.inspiration) ? ' active' : ''\r\n cssClass = `toggle${active}`\r\n img = coreModule.api.Utils.getImage('modules/token-action-hud-dnd5e/icons/inspiration.svg')\r\n break\r\n }\r\n } else {\r\n const value = this.actor.getFlag('dnd5e-custom-counters', id)\r\n switch (counter.type) {\r\n case 'checkbox':\r\n active = (value) ? ' active' : ''\r\n cssClass = `toggle${active}`\r\n break\r\n case 'number':\r\n active = (value > 0) ? ' active' : ''\r\n cssClass = `toggle${active}`\r\n info1 = { text: value }\r\n break\r\n case 'successFailure':\r\n info1 = { text: `${value?.success ?? 0}/${value?.failure ?? 0}` }\r\n break\r\n }\r\n }\r\n\r\n return {\r\n id,\r\n name,\r\n listName,\r\n encodedValue,\r\n cssClass,\r\n img,\r\n info1\r\n }\r\n })\r\n\r\n // Create group data\r\n const groupData = { id: 'counters', type: 'system' }\r\n\r\n // Add actions to HUD\r\n this.addActions(actions, groupData)\r\n }\r\n\r\n /**\r\n * Build effects\r\n * @private\r\n */\r\n async #buildEffects () {\r\n const actionType = 'effect'\r\n\r\n // Get effects\r\n const effects = new Map()\r\n for (const effect of this.actor.allApplicableEffects()) {\r\n effects.set(effect.id, effect)\r\n }\r\n\r\n // Exit if no effects exist\r\n if (effects.size === 0) return\r\n\r\n // Map passive and temporary effects to new maps\r\n const passiveEffects = new Map()\r\n const temporaryEffects = new Map()\r\n\r\n // Iterate effects and add to a map based on the isTemporary value\r\n for (const [effectId, effect] of effects.entries()) {\r\n if (effect.isSuppressed || (effect.parent?.system?.identified === false && !game.user.isGM)) continue\r\n const isTemporary = effect.isTemporary\r\n if (isTemporary) {\r\n temporaryEffects.set(effectId, effect)\r\n } else {\r\n passiveEffects.set(effectId, effect)\r\n }\r\n }\r\n\r\n await Promise.all([\r\n // Build passive effects\r\n this.buildActions({ groupData: { id: 'passive-effects', type: 'system' }, actionData: passiveEffects, actionType }),\r\n // Build temporary effects\r\n this.buildActions({ groupData: { id: 'temporary-effects', type: 'system' }, actionData: temporaryEffects, actionType })\r\n ])\r\n }\r\n\r\n /**\r\n * Build exhaustion\r\n * @private\r\n */\r\n #buildExhaustion () {\r\n // Exit if every actor is not the character type\r\n if (this.actors.length === 0) return\r\n if (!this.actors.every(actor => actor.type === 'character')) return\r\n\r\n const actionType = 'exhaustion'\r\n\r\n const id = 'exhaustion'\r\n const name = coreModule.api.Utils.i18n('DND5E.Exhaustion')\r\n const actionTypeName = `${coreModule.api.Utils.i18n(ACTION_TYPE[actionType])}: ` ?? ''\r\n const listName = `${actionTypeName}${name}`\r\n const encodedValue = [actionType, id].join(this.delimiter)\r\n const img = coreModule.api.Utils.getImage('modules/token-action-hud-dnd5e/icons/exhaustion.svg')\r\n const info1 = { text: this.actor.system.attributes.exhaustion }\r\n let cssClass = ''\r\n const active = this.actor.system.attributes.exhaustion > 0\r\n ? ' active'\r\n : ''\r\n cssClass = `toggle${active}`\r\n\r\n // Get actions\r\n const actions = [{\r\n cssClass,\r\n id,\r\n name,\r\n encodedValue,\r\n img,\r\n info1,\r\n listName\r\n }]\r\n\r\n // Create group data\r\n const groupData = { id: 'exhaustion', type: 'system' }\r\n\r\n // Add actions to HUD\r\n this.addActions(actions, groupData)\r\n }\r\n\r\n /**\r\n * Build features\r\n * @private\r\n */\r\n async #buildFeatures () {\r\n const actionType = 'feature'\r\n\r\n // Get feats\r\n const feats = new Map()\r\n for (const [key, value] of this.items) {\r\n const type = value.type\r\n if (type === 'feat') feats.set(key, value)\r\n }\r\n\r\n // Early exit if no feats exist\r\n if (feats.size === 0) return\r\n\r\n // Map active and passive features to new maps\r\n const featuresMap = new Map()\r\n\r\n const featureTypes = [\r\n { type: 'background', groupId: 'background-features' },\r\n { type: 'class', groupId: 'class-features' },\r\n { type: 'monster', groupId: 'monster-features' },\r\n { type: 'race', groupId: 'race-features' },\r\n { type: 'feats', groupId: 'feats' }\r\n ]\r\n\r\n const classFeatureTypes = [\r\n { type: 'artificerInfusion', groupId: 'artificer-infusions' },\r\n { type: 'channelDivinity', groupId: 'channel-divinity' },\r\n { type: 'defensiveTactic', groupId: 'defensive-tactics' },\r\n { type: 'eldritchInvocation', groupId: 'eldritch-invocations' },\r\n { type: 'elementalDiscipline', groupId: 'elemental-disciplines' },\r\n { type: 'fightingStyle', groupId: 'fighting-styles' },\r\n { type: 'huntersPrey', groupId: 'hunters-prey' },\r\n { type: 'ki', groupId: 'ki-abilities' },\r\n { type: 'maneuver', groupId: 'maneuvers' },\r\n { type: 'metamagic', groupId: 'metamagic-options' },\r\n { type: 'multiattack', groupId: 'multiattacks' },\r\n { type: 'pact', groupId: 'pact-boons' },\r\n { type: 'psionicPower', groupId: 'psionic-powers' },\r\n { type: 'rune', groupId: 'runes' },\r\n { type: 'superiorHuntersDefense', groupId: 'superior-hunters-defense' }\r\n ]\r\n\r\n for (const [key, value] of feats) {\r\n const activationType = value.system.activation?.type\r\n const type = value.system.type.value\r\n const subType = value.system.type?.subtype\r\n if (activationType) {\r\n if (!featuresMap.has('active-features')) featuresMap.set('active-features', new Map())\r\n featuresMap.get('active-features').set(key, value)\r\n }\r\n if (!activationType || activationType === '') {\r\n if (!featuresMap.has('passive-features')) featuresMap.set('passive-features', new Map())\r\n featuresMap.get('passive-features').set(key, value)\r\n }\r\n for (const featureType of featureTypes) {\r\n const groupId = featureType.groupId\r\n if (featureType.type === type) {\r\n if (!featuresMap.has(groupId)) featuresMap.set(groupId, new Map())\r\n featuresMap.get(groupId).set(key, value)\r\n }\r\n }\r\n for (const featureType of classFeatureTypes) {\r\n const groupId = featureType.groupId\r\n if (subType && featureType.type === subType) {\r\n if (!featuresMap.has(groupId)) featuresMap.set(groupId, new Map())\r\n featuresMap.get(groupId).set(key, value)\r\n }\r\n }\r\n }\r\n\r\n // Create group name mappings\r\n const groupNameMappings = {\r\n 'active-features': coreModule.api.Utils.i18n('tokenActionHud.dnd5e.activeFeatures'),\r\n 'passive-features': coreModule.api.Utils.i18n('tokenActionHud.dnd5e.passiveFeatures')\r\n }\r\n\r\n // Loop through inventory groups ids\r\n for (const groupId of this.featuregroupIds) {\r\n if (!featuresMap.has(groupId)) continue\r\n\r\n // Create group data\r\n const groupData = {\r\n id: groupId,\r\n name: groupNameMappings[groupId] ?? '',\r\n type: 'system'\r\n }\r\n\r\n const actionData = featuresMap.get(groupId)\r\n const data = { groupData, actionData, actionType }\r\n\r\n // Build actions\r\n await this.buildActions(data)\r\n\r\n // Build activations\r\n if (groupNameMappings[groupId]) await this.buildActivations(data)\r\n }\r\n }\r\n\r\n /**\r\n * Build inventory\r\n * @private\r\n */\r\n async #buildInventory () {\r\n // Exit early if no items exist\r\n if (this.items.size === 0) return\r\n\r\n const inventoryMap = new Map()\r\n\r\n for (const [key, value] of this.items) {\r\n // Set variables\r\n const equipped = value.system.equipped\r\n const hasQuantity = value.system?.quantity > 0\r\n const isActiveItem = this.#isActiveItem(value)\r\n const isUsableItem = this.#isUsableItem(value)\r\n const isEquippedItem = this.#isEquippedItem(value)\r\n const type = value.type\r\n\r\n // Set items into maps\r\n if (hasQuantity && isActiveItem) {\r\n if (equipped) {\r\n if (!inventoryMap.has('equipped')) inventoryMap.set('equipped', new Map())\r\n inventoryMap.get('equipped').set(key, value)\r\n }\r\n if (!equipped) {\r\n if (!inventoryMap.has('unequipped')) inventoryMap.set('unequipped', new Map())\r\n inventoryMap.get('unequipped').set(key, value)\r\n }\r\n if (isUsableItem && type === 'consumable') {\r\n if (!inventoryMap.has('consumables')) inventoryMap.set('consumables', new Map())\r\n inventoryMap.get('consumables').set(key, value)\r\n }\r\n if (isEquippedItem) {\r\n if (type === 'container') {\r\n if (!inventoryMap.has('containers')) inventoryMap.set('containers', new Map())\r\n inventoryMap.get('containers').set(key, value)\r\n }\r\n if (type === 'equipment') {\r\n if (!inventoryMap.has('equipment')) inventoryMap.set('equipment', new Map())\r\n inventoryMap.get('equipment').set(key, value)\r\n }\r\n if (type === 'loot') {\r\n if (!inventoryMap.has('loot')) inventoryMap.set('loot', new Map())\r\n inventoryMap.get('loot').set(key, value)\r\n }\r\n if (type === 'tool') {\r\n if (!inventoryMap.has('tools')) inventoryMap.set('tools', new Map())\r\n inventoryMap.get('tools').set(key, value)\r\n }\r\n if (type === 'weapon') {\r\n if (!inventoryMap.has('weapons')) inventoryMap.set('weapons', new Map())\r\n inventoryMap.get('weapons').set(key, value)\r\n }\r\n }\r\n }\r\n }\r\n\r\n // Create group name mappings\r\n const groupNameMappings = {\r\n equipped: coreModule.api.Utils.i18n('DND5E.Equipped'),\r\n unequipped: coreModule.api.Utils.i18n('DND5E.Unequipped'),\r\n consumables: coreModule.api.Utils.i18n('ITEM.TypeConsumablePl'),\r\n containers: coreModule.api.Utils.i18n('ITEM.TypeContainerPl'),\r\n equipment: coreModule.api.Utils.i18n('ITEM.TypeEquipmentPl'),\r\n loot: coreModule.api.Utils.i18n('ITEM.TypeLootPl'),\r\n tools: coreModule.api.Utils.i18n('ITEM.TypeToolPl'),\r\n weapons: coreModule.api.Utils.i18n('ITEM.TypeWeaponPl')\r\n }\r\n\r\n // Loop through inventory subcateogry ids\r\n for (const groupId of this.inventorygroupIds) {\r\n if (!inventoryMap.has(groupId)) continue\r\n\r\n // Create group data\r\n const groupData = {\r\n id: groupId,\r\n name: groupNameMappings[groupId],\r\n type: 'system'\r\n }\r\n\r\n const actionData = inventoryMap.get(groupId)\r\n const data = { groupData, actionData }\r\n\r\n // Build actions\r\n await this.buildActions(data)\r\n\r\n // Build activations\r\n if (this.activationgroupIds) {\r\n await this.buildActivations(data)\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Build rests\r\n * @private\r\n */\r\n #buildRests () {\r\n // Exit if every actor is not the character type\r\n if (this.actors.length === 0) return\r\n if (!this.actors.every(actor => actor.type === 'character')) return\r\n\r\n const actionType = 'utility'\r\n\r\n // Set rest types\r\n const restTypes = {\r\n shortRest: { name: coreModule.api.Utils.i18n('DND5E.ShortRest') },\r\n longRest: { name: coreModule.api.Utils.i18n('DND5E.LongRest') }\r\n }\r\n\r\n // Get actions\r\n const actions = Object.entries(restTypes)\r\n .map((restType) => {\r\n const id = restType[0]\r\n const name = restType[1].name\r\n const actionTypeName = `${coreModule.api.Utils.i18n(ACTION_TYPE[actionType])}: ` ?? ''\r\n const listName = `${actionTypeName}${name}`\r\n const encodedValue = [actionType, id].join(this.delimiter)\r\n return {\r\n id,\r\n name,\r\n encodedValue,\r\n listName\r\n }\r\n })\r\n\r\n // Create group data\r\n const groupData = { id: 'rests', type: 'system' }\r\n\r\n // Add actions to HUD\r\n this.addActions(actions, groupData)\r\n }\r\n\r\n /**\r\n * Build skills\r\n * @private\r\n */\r\n #buildSkills () {\r\n const actionType = 'skill'\r\n\r\n // Get skills\r\n const skills = (!this.actor) ? CONFIG.DND5E.skills : this.actor.system.skills\r\n\r\n // Exit if there are no skills\r\n if (skills.length === 0) return\r\n\r\n // Get actions\r\n const actions = Object.entries(skills)\r\n .map((skill) => {\r\n try {\r\n const id = skill[0]\r\n const abbreviatedName = id.charAt(0).toUpperCase() + id.slice(1)\r\n const name = this.abbreviateSkills ? abbreviatedName : CONFIG.DND5E.skills[id].label\r\n const actionTypeName = `${coreModule.api.Utils.i18n(ACTION_TYPE[actionType])}: ` ?? ''\r\n const listName = `${actionTypeName}${CONFIG.DND5E.skills[id].label}`\r\n const encodedValue = [actionType, id].join(this.delimiter)\r\n const icon1 = this.#getProficiencyIcon(skills[id].value)\r\n const mod = skills[id].total\r\n const info1 = (this.actor) ? { text: (mod || mod === 0) ? `${(mod >= 0) ? '+' : ''}${mod}` : '' } : ''\r\n return {\r\n id,\r\n name,\r\n encodedValue,\r\n icon1,\r\n info1,\r\n listName\r\n }\r\n } catch (error) {\r\n coreModule.api.Logger.error(skill)\r\n return null\r\n }\r\n })\r\n .filter((skill) => !!skill)\r\n\r\n // Create group data\r\n const groupData = { id: 'skills', type: 'system' }\r\n\r\n // Add actions to HUD\r\n this.addActions(actions, groupData)\r\n }\r\n\r\n /**\r\n * Build spells\r\n */\r\n async #buildSpells () {\r\n const actionType = 'spell'\r\n\r\n const spellsMap = new Map()\r\n\r\n // Loop through items\r\n for (const [key, value] of this.items) {\r\n const type = value.type\r\n if (type === 'spell') {\r\n const isUsableItem = this.#isUsableItem(value)\r\n const isUsableSpell = this.#isUsableSpell(value)\r\n if (isUsableItem && isUsableSpell) {\r\n const preparationMode = value.system.preparation.mode\r\n switch (preparationMode) {\r\n case 'atwill':\r\n if (!spellsMap.has('at-will-spells')) spellsMap.set('at-will-spells', new Map())\r\n spellsMap.get('at-will-spells').set(key, value)\r\n break\r\n case 'innate':\r\n if (!spellsMap.has('innate-spells')) spellsMap.set('innate-spells', new Map())\r\n spellsMap.get('innate-spells').set(key, value)\r\n break\r\n case 'pact':\r\n if (!spellsMap.has('pact-spells')) spellsMap.set('pact-spells', new Map())\r\n spellsMap.get('pact-spells').set(key, value)\r\n break\r\n default:\r\n { const level = value.system.level\r\n switch (level) {\r\n case 0:\r\n if (!spellsMap.has('cantrips')) spellsMap.set('cantrips', new Map())\r\n spellsMap.get('cantrips').set(key, value)\r\n break\r\n case 1:\r\n if (!spellsMap.has('1st-level-spells')) spellsMap.set('1st-level-spells', new Map())\r\n spellsMap.get('1st-level-spells').set(key, value)\r\n break\r\n case 2:\r\n if (!spellsMap.has('2nd-level-spells')) spellsMap.set('2nd-level-spells', new Map())\r\n spellsMap.get('2nd-level-spells').set(key, value)\r\n break\r\n case 3:\r\n if (!spellsMap.has('3rd-level-spells')) spellsMap.set('3rd-level-spells', new Map())\r\n spellsMap.get('3rd-level-spells').set(key, value)\r\n break\r\n case 4:\r\n if (!spellsMap.has('4th-level-spells')) spellsMap.set('4th-level-spells', new Map())\r\n spellsMap.get('4th-level-spells').set(key, value)\r\n break\r\n case 5:\r\n if (!spellsMap.has('5th-level-spells')) spellsMap.set('5th-level-spells', new Map())\r\n spellsMap.get('5th-level-spells').set(key, value)\r\n break\r\n case 6:\r\n if (!spellsMap.has('6th-level-spells')) spellsMap.set('6th-level-spells', new Map())\r\n spellsMap.get('6th-level-spells').set(key, value)\r\n break\r\n case 7:\r\n if (!spellsMap.has('7th-level-spells')) spellsMap.set('7th-level-spells', new Map())\r\n spellsMap.get('7th-level-spells').set(key, value)\r\n break\r\n case 8:\r\n if (!spellsMap.has('8th-level-spells')) spellsMap.set('8th-level-spells', new Map())\r\n spellsMap.get('8th-level-spells').set(key, value)\r\n break\r\n case 9:\r\n if (!spellsMap.has('9th-level-spells')) spellsMap.set('9th-level-spells', new Map())\r\n spellsMap.get('9th-level-spells').set(key, value)\r\n break\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n // Reverse sort spell slots by level\r\n const systemSpells = Object.entries(this.actor.system.spells).reverse()\r\n\r\n // Set spell slot availability\r\n let pactSlot = null\r\n const spellSlots = []\r\n let spellSlotAvailable = this.showUnchargedItems\r\n let pactSlotAvailable = this.showUnchargedItems\r\n for (const [key, value] of systemSpells) {\r\n const hasValue = value.value > 0\r\n const hasMax = value.max > 0\r\n const hasLevel = value.level > 0\r\n if (key === 'pact') {\r\n if (!pactSlotAvailable && hasValue && hasMax && hasLevel) pactSlotAvailable = true\r\n if (!hasLevel) pactSlotAvailable = false\r\n value.slotAvailable = pactSlotAvailable\r\n pactSlot = [key, value]\r\n }\r\n if (key.startsWith('spell') && key !== 'spell0') {\r\n if (!spellSlotAvailable && hasValue && hasMax) spellSlotAvailable = true\r\n value.slotAvailable = spellSlotAvailable\r\n spellSlots.push([key, value])\r\n } else {\r\n if (hasValue) {\r\n value.slotsAvailable = true\r\n spellSlots.push(key, value)\r\n }\r\n }\r\n }\r\n\r\n // Set equivalent spell slot where pact slot is available\r\n if (pactSlot[1].slotAvailable) {\r\n const pactSpellEquivalent = spellSlots.findIndex(spell => spell[0] === 'spell' + pactSlot[1].level)\r\n spellSlots[pactSpellEquivalent][1].slotsAvailable = true\r\n }\r\n\r\n const groupMappings = {\r\n '1st-level-spells': { spellMode: 1, name: coreModule.api.Utils.i18n('tokenActionHud.dnd5e.1stLevelSpells') },\r\n '2nd-level-spells': { spellMode: 2, name: coreModule.api.Utils.i18n('tokenActionHud.dnd5e.2ndLevelSpells') },\r\n '3rd-level-spells': { spellMode: 3, name: coreModule.api.Utils.i18n('tokenActionHud.dnd5e.3rdLevelSpells') },\r\n '4th-level-spells': { spellMode: 4, name: coreModule.api.Utils.i18n('tokenActionHud.dnd5e.4thLevelSpells') },\r\n '5th-level-spells': { spellMode: 5, name: coreModule.api.Utils.i18n('tokenActionHud.dnd5e.5thLevelSpells') },\r\n '6th-level-spells': { spellMode: 6, name: coreModule.api.Utils.i18n('tokenActionHud.dnd5e.6thLevelSpells') },\r\n '7th-level-spells': { spellMode: 7, name: coreModule.api.Utils.i18n('tokenActionHud.dnd5e.7thLevelSpells') },\r\n '8th-level-spells': { spellMode: 8, name: coreModule.api.Utils.i18n('tokenActionHud.dnd5e.8thLevelSpells') },\r\n '9th-level-spells': { spellMode: 9, name: coreModule.api.Utils.i18n('tokenActionHud.dnd5e.9thLevelSpells') },\r\n 'at-will-spells': { spellMode: 'atwill', name: coreModule.api.Utils.i18n('tokenActionHud.dnd5e.atWillSpells') },\r\n cantrips: { spellMode: 0, name: coreModule.api.Utils.i18n('tokenActionHud.dnd5e.cantrips') },\r\n 'innate-spells': { spellMode: 'innate', name: coreModule.api.Utils.i18n('tokenActionHud.dnd5e.innateSpells') },\r\n 'pact-spells': { spellMode: 'pact', name: coreModule.api.Utils.i18n('tokenActionHud.dnd5e.pactSpells') }\r\n }\r\n\r\n const spellSlotModes = ['1', '2', '3', '4', '5', '6', '7', '8', '9', 'pact']\r\n\r\n for (const groupId of this.spellgroupIds) {\r\n const spellMode = groupMappings[groupId].spellMode\r\n const groupName = groupMappings[groupId].name\r\n\r\n // Skip if no spells exist\r\n if (!spellsMap.has(groupId)) continue\r\n\r\n const levelInfo = (spellMode === 'pact') ? pactSlot[1] : spellSlots.find(spellSlot => spellSlot[0] === `spell${spellMode}`)?.[1]\r\n const slots = levelInfo?.value\r\n const max = levelInfo?.max\r\n const slotsAvailable = levelInfo?.slotAvailable\r\n\r\n // Skip if spells require spell slots and none are available\r\n if (!slotsAvailable && spellSlotModes.includes(spellMode)) continue\r\n\r\n // Create group data=\r\n const groupInfo = {}\r\n groupInfo.info1 = { class: 'tah-spotlight', text: (max >= 0) ? `${slots}/${max}` : '' }\r\n const groupData = {\r\n id: groupId,\r\n name: groupName,\r\n type: 'system',\r\n info: groupInfo\r\n }\r\n\r\n // Add spell slot info to group\r\n this.addGroupInfo(groupData)\r\n\r\n const actionData = spellsMap.get(groupId)\r\n const data = { groupData, actionData, actionType }\r\n\r\n // Build actions\r\n await this.buildActions(data)\r\n\r\n // Build activations\r\n if (this.activationgroupIds) { await this.buildActivations(data) }\r\n }\r\n }\r\n\r\n /**\r\n * Build utility\r\n * @private\r\n */\r\n #buildUtility () {\r\n // Exit if every actor is not the character type\r\n if (this.actors.length === 0) return\r\n if (!this.actors.every((actor) => actor.type === 'character')) return\r\n\r\n const actionType = 'utility'\r\n\r\n // Set utility types\r\n const utilityTypes = {\r\n deathSave: { name: coreModule.api.Utils.i18n('DND5E.DeathSave') },\r\n inspiration: { name: coreModule.api.Utils.i18n('DND5E.Inspiration') }\r\n }\r\n\r\n // Delete 'deathSave' for multiple tokens\r\n if (!this.actor || this.actor.system.attributes.hp.value > 0) delete utilityTypes.deathSave\r\n\r\n // Get actions\r\n const actions = Object.entries(utilityTypes)\r\n .map((utilityType) => {\r\n const id = utilityType[0]\r\n const name = utilityType[1].name\r\n const actionTypeName = `${coreModule.api.Utils.i18n(ACTION_TYPE[actionType])}: ` ?? ''\r\n const listName = `${actionTypeName}${name}`\r\n const encodedValue = [actionType, id].join(this.delimiter)\r\n let cssClass = ''\r\n if (utilityType[0] === 'inspiration') {\r\n const active = this.actors.every((actor) => actor.system.attributes?.inspiration)\r\n ? ' active'\r\n : ''\r\n cssClass = `toggle${active}`\r\n }\r\n return {\r\n id,\r\n name,\r\n encodedValue,\r\n cssClass,\r\n listName\r\n }\r\n })\r\n\r\n // Crreate group data\r\n const groupData = { id: 'utility', type: 'system' }\r\n\r\n // Add actions to HUD\r\n this.addActions(actions, groupData)\r\n }\r\n\r\n /**\r\n * Build actions\r\n * @public\r\n * @param {object} data actionData, groupData, actionType\r\n * @param {object} options\r\n */\r\n async buildActions (data, options) {\r\n const { actionData, groupData, actionType } = data\r\n\r\n // Exit if there is no action data\r\n if (actionData.size === 0) return\r\n\r\n // Exit if there is no groupId\r\n const groupId = (typeof groupData === 'string' ? groupData : groupData?.id)\r\n if (!groupId) return\r\n\r\n // Get actions\r\n const actions = await Promise.all([...actionData].map(async item => await this.#getAction(actionType, item[1])))\r\n\r\n // Add actions to action list\r\n this.addActions(actions, groupData)\r\n }\r\n\r\n /**\r\n * Get action\r\n * @private\r\n * @param {string} actionType\r\n * @param {object} entity\r\n * @param {object} options\r\n * @returns {object}\r\n */\r\n async #getAction (actionType = 'item', entity) {\r\n const id = entity.id ?? entity._id\r\n let name = entity?.name ?? entity?.label\r\n if (\r\n entity?.system?.recharge &&\r\n !entity?.system?.recharge?.charged &&\r\n entity?.system?.recharge?.value\r\n ) {\r\n name += ` (${coreModule.api.Utils.i18n('DND5E.Recharge')})`\r\n }\r\n const actionTypeName = `${coreModule.api.Utils.i18n(ACTION_TYPE[actionType])}: ` ?? ''\r\n const listName = `${actionTypeName}${name}`\r\n let cssClass = ''\r\n if (Object.hasOwn(entity, 'disabled')) {\r\n const active = (!entity.disabled) ? ' active' : ''\r\n cssClass = `toggle${active}`\r\n }\r\n const encodedValue = [actionType, id].join(this.delimiter)\r\n const img = coreModule.api.Utils.getImage(entity)\r\n const icon1 = this.#getActivationTypeIcon(entity?.system?.activation?.type)\r\n const icon2 = this.#getPreparedIcon(entity)\r\n const icon3 = this.#getConcentrationIcon(entity)\r\n const info = this.#getItemInfo(entity)\r\n const info1 = info?.info1\r\n const info2 = info?.info2\r\n const info3 = info?.info3\r\n const tooltipData = await this.#getTooltipData(entity)\r\n const tooltip = await this.#getTooltip(tooltipData)\r\n return {\r\n id,\r\n name,\r\n encodedValue,\r\n cssClass,\r\n img,\r\n icon1,\r\n icon2,\r\n icon3,\r\n info1,\r\n info2,\r\n info3,\r\n listName,\r\n tooltip\r\n }\r\n }\r\n\r\n /**\r\n * Is active item\r\n * @param {object} item\r\n * @returns {boolean}\r\n */\r\n #isActiveItem (item) {\r\n if (this.showItemsWithoutActivationCosts) return true\r\n const activationTypes = Object.keys(CONFIG.DND5E.abilityActivationTypes).filter((at) => at !== 'none')\r\n const activation = item.system.activation\r\n const activationType = activation?.type\r\n if ((activation && activationTypes.includes(activationType)) || item.type === 'tool') return true\r\n return false\r\n }\r\n\r\n /**\r\n * Is equipped item\r\n * @private\r\n * @param {object} item\r\n * @returns {boolean}\r\n */\r\n #isEquippedItem (item) {\r\n const type = item.type\r\n const excludedTypes = ['consumable', 'spell', 'feat']\r\n if (this.showUnequippedItems && !excludedTypes.includes(type)) return true\r\n const equipped = item.system.equipped\r\n if (equipped && type !== 'consumable') return true\r\n return false\r\n }\r\n\r\n /**\r\n * Is usable item\r\n * @private\r\n * @param {object} item The item\r\n * @returns {boolean}\r\n */\r\n #isUsableItem (item) {\r\n if (this.showUnchargedItems) return true\r\n const uses = item.system.uses\r\n if (!uses) return false\r\n return true\r\n }\r\n\r\n /**\r\n * Is usable spell\r\n * @param {object} spell The spell\r\n * @returns {boolean}\r\n */\r\n #isUsableSpell (spell) {\r\n if (this.actorType !== 'character' && this.showUnequippedItems) return true\r\n const prepared = spell.system.preparation.prepared\r\n if (this.showUnpreparedSpells) return true\r\n // Set variables\r\n const level = spell.system.level\r\n const preparationModes = Object.keys(CONFIG.DND5E.spellPreparationModes)\r\n .filter(preparationMode => preparationMode !== 'prepared')\r\n const preparationMode = spell.system.preparation.mode\r\n\r\n // Return true if spell is a cantrip, has a preparation mode other than 'prepared' or is prepared\r\n if (level === 0 || preparationModes.includes(preparationMode) || prepared) return true\r\n return false\r\n }\r\n\r\n /**\r\n * Get item info\r\n * @private\r\n * @param {object} item\r\n * @returns {object}\r\n */\r\n #getItemInfo (item) {\r\n const info1 = item.type === 'spell' ? this.#getSpellInfo(item) : this.#getQuantityData(item)\r\n const info2 = this.#getUsesData(item)\r\n const info3 = this.#getConsumeData(item)\r\n\r\n return { info1, info2, info3 }\r\n }\r\n\r\n /**\r\n * Add spell info\r\n * @param {object} spell\r\n */\r\n #getSpellInfo (spell) {\r\n if (!this.displaySpellInfo) return null\r\n const info = { text: '' }\r\n const componentsArray = []\r\n const components = spell.system?.properties\r\n const componentTypes = [\r\n ['vocal', 'DND5E.ComponentVerbal'],\r\n ['somatic', 'DND5E.ComponentSomatic'],\r\n ['material', 'DND5E.ComponentMaterial']\r\n ]\r\n componentTypes.forEach(component => {\r\n if (components?.has(component[0])) {\r\n componentsArray.push(coreModule.api.Utils.i18n(component[1]))\r\n info.text += coreModule.api.Utils.i18n(`${component[1]}Abbr`)\r\n }\r\n })\r\n\r\n // Ritual\r\n if (components?.has('ritual')) {\r\n componentsArray.push(`[${coreModule.api.Utils.i18n('DND5E.Ritual')}]`)\r\n info.text += ` [${coreModule.api.Utils.i18n('DND5E.RitualAbbr')}]`\r\n }\r\n\r\n info.title = componentsArray.join(', ')\r\n\r\n return info\r\n }\r\n\r\n /**\r\n * Get actors\r\n * @private\r\n * @returns {object}\r\n */\r\n #getActors () {\r\n const allowedTypes = ['character', 'npc']\r\n const tokens = coreModule.api.Utils.getControlledTokens()\r\n const actors = tokens?.filter(token => token.actor).map((token) => token.actor)\r\n if (actors.every((actor) => allowedTypes.includes(actor.type))) {\r\n return actors\r\n } else {\r\n return []\r\n }\r\n }\r\n\r\n /**\r\n * Get tokens\r\n * @private\r\n * @returns {object}\r\n */\r\n #getTokens () {\r\n const allowedTypes = ['character', 'npc']\r\n const tokens = coreModule.api.Utils.getControlledTokens()\r\n const actors = tokens?.filter(token => token.actor).map((token) => token.actor)\r\n if (actors.every((actor) => allowedTypes.includes(actor.type))) {\r\n return tokens\r\n } else {\r\n return []\r\n }\r\n }\r\n\r\n /**\r\n * Get quantity\r\n * @private\r\n * @param {object} item\r\n * @returns {string}\r\n */\r\n #getQuantityData (item) {\r\n const quantity = item?.system?.quantity ?? 0\r\n return {\r\n text: (quantity > 1) ? quantity : '',\r\n title: `${coreModule.api.Utils.i18n('DND5E.Quantity')}: ${quantity}`\r\n }\r\n }\r\n\r\n /**\r\n * Get uses\r\n * @private\r\n * @param {object} item\r\n * @param {string} consumeName\r\n * @param {integer} consumeAmount\r\n * @returns {string}\r\n */\r\n #getUsesData (item, consumeName, consumeAmount) {\r\n const uses = item?.system?.uses\r\n if (uses?.per && (consumeName || uses?.prompt) && (uses.value > 0 || uses.max > 0)) {\r\n const of = coreModule.api.Utils.i18n('DND5E.of')\r\n const per = uses.per === 'charges' ? '' : ` ${coreModule.api.Utils.i18n('DND5E.per')}`\r\n const period = CONFIG.DND5E.limitedUsePeriods[uses.per]?.label ?? uses.per\r\n const amount = consumeAmount !== undefined ? consumeAmount : uses.amount\r\n const text = `${amount > 1 ? `${amount} ${of} ` : ''}${uses.value ?? '0'}${uses.max > 0 ? `/${uses.max}` : ''}`\r\n const title = `${text}${per} ${period}${consumeName ? ` (${of} ${consumeName})` : ''}`\r\n return { text, title }\r\n }\r\n return {}\r\n }\r\n\r\n /**\r\n * Get consume\r\n * @private\r\n * @param {object} item\r\n * @param {object} actor\r\n * @returns {string}\r\n */\r\n #getConsumeData (item) {\r\n // Get consume target and type\r\n const consumeId = item?.system?.consume?.target\r\n const consumeType = item?.system?.consume?.type\r\n const consumeAmount = item?.system?.consume?.amount\r\n\r\n if (!consumeId || !consumeType || consumeId === item.id) return {}\r\n\r\n // Return resources\r\n if (consumeType === 'attribute') {\r\n const parentId = consumeId.substr(0, consumeId.lastIndexOf('.'))\r\n const target = foundry.utils.getProperty(this.actor.system, parentId)\r\n\r\n if (target) {\r\n const text = `${target.value ?? '0'}${target.max ? `/${target.max}` : ''}`\r\n return {\r\n text,\r\n title: `${text} ${target.label ?? ''}`\r\n }\r\n }\r\n } else {\r\n const target = this.items.get(consumeId)\r\n\r\n // Return charges\r\n if (consumeType === 'charges') {\r\n return this.#getUsesData(target, target.name, consumeAmount)\r\n }\r\n\r\n // Return quantity\r\n if (target?.system?.quantity) {\r\n const text = `${consumeAmount > 1 ? `${consumeAmount} ${coreModule.api.Utils.i18n('DND5E.of')} ` : ''}${target.system.quantity}`\r\n return {\r\n text,\r\n title: `${text} ${target.name}`\r\n }\r\n }\r\n }\r\n\r\n return {}\r\n }\r\n\r\n /**\r\n * Discard slow items\r\n * @private\r\n * @param {object} items\r\n * @returns {object}\r\n */\r\n #discardSlowItems (items) {\r\n // Get setting\r\n const showSlowActions = Utils.getSetting('showSlowActions')\r\n\r\n // Return all items\r\n if (showSlowActions) return items\r\n\r\n // Return filtered items\r\n const slowActivationTypes = ['minute', 'hour', 'day']\r\n\r\n // Initialize map\r\n const filteredItems = new Map()\r\n\r\n // Loop items and set those with fast activation types into the new map\r\n for (const [key, value] of items.entries()) {\r\n const activationType = value.system?.activation?.type\r\n if (!slowActivationTypes.includes(activationType)) filteredItems.set(key, value)\r\n }\r\n\r\n return filteredItems\r\n }\r\n\r\n /**\r\n * Get proficiency icon\r\n * @param {string} level\r\n * @returns {string}\r\n */\r\n #getProficiencyIcon (level) {\r\n const title = CONFIG.DND5E.proficiencyLevels[level] ?? ''\r\n const icon = PROFICIENCY_LEVEL_ICON[level]\r\n if (icon) return ``\r\n }\r\n\r\n /**\r\n * Get icon for the activation type\r\n * @private\r\n * @param {object} activationType\r\n * @returns {string}\r\n */\r\n #getActivationTypeIcon (activationType) {\r\n const title = CONFIG.DND5E.abilityActivationTypes[activationType] ?? ''\r\n const icon = ACTIVATION_TYPE_ICON[activationType]\r\n if (icon) return ``\r\n }\r\n\r\n /**\r\n * Get icon for concentration type\r\n * @private\r\n * @param {object} spell\r\n * @returns {string}\r\n */\r\n #getConcentrationIcon (spell) {\r\n if (spell?.type !== 'spell' || !this.displaySpellInfo || !spell.system?.properties?.has('concentration')) return null\r\n const title = coreModule.api.Utils.i18n('DND5E.Scroll.RequiresConcentration')\r\n const icon = CONCENTRATION_ICON\r\n return ``\r\n }\r\n\r\n /**\r\n * Get icon for a prepared spell\r\n * @private\r\n * @param {object} spell\r\n * @returns\r\n */\r\n #getPreparedIcon (spell) {\r\n if (spell?.type !== 'spell' || !this.showUnpreparedSpells) return null\r\n const level = spell.system.level\r\n const preparationMode = spell.system.preparation.mode\r\n const prepared = spell.system.preparation.prepared\r\n const icon = prepared ? PREPARED_ICON : `${PREPARED_ICON} tah-icon-disabled`\r\n const title = preparationMode === 'always' ? coreModule.api.Utils.i18n('DND5E.SpellPrepAlways') : prepared ? coreModule.api.Utils.i18n('DND5E.SpellPrepared') : coreModule.api.Utils.i18n('DND5E.SpellUnprepared')\r\n\r\n // Return icon if the preparation mode is 'prepared' or 'always' and the spell is not a cantrip\r\n return ((preparationMode === 'prepared' || preparationMode === 'always') && level !== 0) ? `` : null\r\n }\r\n\r\n async #getTooltipData (entity) {\r\n if (this.tooltipsSetting === 'none') return ''\r\n\r\n const name = entity?.name ?? ''\r\n\r\n if (this.tooltipsSetting === 'nameOnly') return name\r\n\r\n const unidentified = entity.system?.identified === false\r\n const description = (typeof entity?.system?.description === 'string') ? entity?.system?.description : (unidentified ? entity?.system?.unidentified?.description : entity?.system?.description?.value) ?? ''\r\n let modifiers, properties, rarity, traits\r\n if (!unidentified) {\r\n modifiers = entity?.modifiers ?? null\r\n properties = [\r\n ...entity.system?.chatProperties ?? [],\r\n ...entity.system?.equippableItemCardProperties ?? [],\r\n ...entity.system?.activatedEffectCardProperties ?? []\r\n ].filter(p => p)\r\n rarity = unidentified ? null : entity?.rarity ?? null\r\n traits = (entity?.type === 'weapon') ? this.#getWeaponProperties(entity?.system?.properties) : null\r\n }\r\n return { name, description, modifiers, properties, rarity, traits }\r\n }\r\n\r\n /**\r\n * Get condition tooltip data\r\n * @param {*} id The condition id\r\n * @param {*} name The condition name\r\n * @returns {object} The tooltip data\r\n */\r\n async #getConditionTooltipData (id, name) {\r\n if (this.tooltipsSetting === 'none') return ''\r\n if (this.tooltipsSetting === 'nameOnly') return name\r\n\r\n const journalEntry = (CONDITION[id]) ? (CONDITION[id]?.uuid) ? await fromUuid(CONDITION[id].uuid) : null : null\r\n const description = journalEntry?.text?.content ?? ''\r\n return {\r\n name,\r\n description\r\n }\r\n }\r\n\r\n /**\r\n * Get tooltip\r\n * @param {object} tooltipData The tooltip data\r\n * @returns {string} The tooltip\r\n */\r\n async #getTooltip (tooltipData) {\r\n if (this.tooltipsSetting === 'none') return ''\r\n if (typeof tooltipData === 'string') return tooltipData\r\n\r\n const name = coreModule.api.Utils.i18n(tooltipData.name)\r\n\r\n if (this.tooltipsSetting === 'nameOnly') return name\r\n\r\n const nameHtml = `

${name}

`\r\n\r\n const description = tooltipData?.descriptionLocalised ??\r\n await TextEditor.enrichHTML(coreModule.api.Utils.i18n(tooltipData?.description ?? ''), { async: true })\r\n\r\n const rarityHtml = tooltipData?.rarity\r\n ? `${coreModule.api.Utils.i18n(RARITY[tooltipData.rarity])}`\r\n : ''\r\n\r\n const propertiesHtml = tooltipData?.properties\r\n ? `
${tooltipData.properties.map(property => `${coreModule.api.Utils.i18n(property)}`).join('')}
`\r\n : ''\r\n\r\n const traitsHtml = tooltipData?.traits\r\n ? tooltipData.traits.map(trait => `${coreModule.api.Utils.i18n(trait.label ?? trait)}`).join('')\r\n : ''\r\n\r\n const traits2Html = tooltipData?.traits2\r\n ? tooltipData.traits2.map(trait => `${coreModule.api.Utils.i18n(trait.label ?? trait)}`).join('')\r\n : ''\r\n\r\n const traitsAltHtml = tooltipData?.traitsAlt\r\n ? tooltipData.traitsAlt.map(trait => `${coreModule.api.Utils.i18n(trait.label)}`).join('')\r\n : ''\r\n\r\n const modifiersHtml = tooltipData?.modifiers\r\n ? `
${tooltipData.modifiers.filter(modifier => modifier.enabled).map(modifier => {\r\n const label = coreModule.api.Utils.i18n(modifier.label)\r\n const sign = modifier.modifier >= 0 ? '+' : ''\r\n const mod = `${sign}${modifier.modifier ?? ''}`\r\n return `${label} ${mod}`\r\n }).join('')}
`\r\n : ''\r\n\r\n const tagsJoined = [rarityHtml, traitsHtml, traits2Html, traitsAltHtml].join('')\r\n\r\n const tagsHtml = (tagsJoined) ? `
${tagsJoined}
` : ''\r\n\r\n const headerTags = (tagsHtml || modifiersHtml) ? `
${tagsHtml}${modifiersHtml}
` : ''\r\n\r\n if (!description && !tagsHtml && !modifiersHtml) return name\r\n\r\n return `
${nameHtml}${headerTags}${description}${propertiesHtml}
`\r\n }\r\n\r\n #getWeaponProperties (weaponProperties) {\r\n if (!weaponProperties) return null\r\n return Object.entries(weaponProperties)\r\n .filter(([id, selected]) => selected && WEAPON_PROPERTY[id])\r\n .map(([id, _]) => coreModule.api.Utils.i18n(WEAPON_PROPERTY[id]))\r\n }\r\n }\r\n})\r\n","export let MagicItemActionHandlerExtender = null\r\n\r\nHooks.once('tokenActionHudCoreApiReady', async (coreModule) => {\r\n MagicItemActionHandlerExtender = class MagicItemActionHandlerExtender extends coreModule.api.ActionHandlerExtender {\r\n constructor (actionHandler) {\r\n super()\r\n this.actionHandler = actionHandler\r\n this.actor = null\r\n }\r\n\r\n /**\r\n * Extend the action list\r\n */\r\n async extendActionHandler () {\r\n this.actor = this.actionHandler.actor\r\n if (!this.actor) return\r\n\r\n const actor = await MagicItems.actor(this.actor.id)\r\n\r\n if (!actor) return\r\n\r\n const magicItems = actor.items ?? []\r\n\r\n if (magicItems.length === 0) return\r\n\r\n const parentGroupId = 'magic-items'\r\n const parentGroupType = 'system'\r\n const parentGroupData = {\r\n id: parentGroupId,\r\n type: parentGroupType\r\n }\r\n\r\n magicItems.forEach((magicItem) => {\r\n if (magicItem.attuned && !this._isItemAttuned(magicItem)) return\r\n if (magicItem.equipped && !this._isItemEquipped(magicItem)) return\r\n\r\n const groupId = `magic-items_${magicItem.id}`\r\n const groupName = magicItem.name\r\n const groupType = 'system-derived'\r\n const groupInfo1 = `${magicItem.uses}/${magicItem.charges}`\r\n const groupData = {\r\n id: groupId,\r\n name: groupName,\r\n type: groupType,\r\n info1: groupInfo1\r\n }\r\n\r\n // Add group to HUD\r\n this.actionHandler.addGroup(groupData, parentGroupData)\r\n\r\n const actions = magicItem.ownedEntries.map((entry) => {\r\n const effect = entry.item\r\n const id = effect.id\r\n const name = effect.name\r\n const encodedValue = [\r\n 'magicItem',\r\n `${magicItem.id}>${id}`\r\n ].join('|')\r\n const img = coreModule.api.Utils.getImage(effect)\r\n const info1 = effect.consumption\r\n const info2 = (effect.baseLevel) ? `${coreModule.api.Utils.i18n('DND5E.AbbreviationLevel')} ${effect.baseLevel}` : ''\r\n return {\r\n id,\r\n name,\r\n encodedValue,\r\n img,\r\n info1,\r\n info2,\r\n selected: true\r\n }\r\n })\r\n\r\n // Add actions to action list\r\n this.actionHandler.addActions(actions, groupData)\r\n })\r\n }\r\n\r\n /**\r\n * Whether the magic item is equipped or not\r\n * @param {object} magicItem The item\r\n * @returns {boolean}\r\n */\r\n _isItemEquipped (magicItem) {\r\n return magicItem.item.system.equipped\r\n }\r\n\r\n /**\r\n * Whether the magic items is attuned or not\r\n * @param {object} magicItem The item\r\n * @returns {boolean}\r\n */\r\n _isItemAttuned (magicItem) {\r\n const attunement = magicItem.item.system.attunment\r\n const attunementRequired = CONFIG.DND5E.attunementTypes?.REQUIRED ?? 1\r\n\r\n if (attunement === attunementRequired) return false\r\n\r\n return true\r\n }\r\n }\r\n})\r\n","export let RollHandler = null\r\n\r\nHooks.once('tokenActionHudCoreApiReady', async (coreModule) => {\r\n RollHandler = class RollHandler extends coreModule.api.RollHandler {\r\n /**\r\n * Handle action click\r\n * @override\r\n * @param {object} event\r\n * @param {string} encodedValue\r\n */\r\n async handleActionClick (event, encodedValue) {\r\n const [actionType, actionId] = encodedValue.split('|')\r\n\r\n if (!this.actor) {\r\n for (const token of coreModule.api.Utils.getControlledTokens()) {\r\n const actor = token.actor\r\n await this.#handleAction(event, actionType, actor, token, actionId)\r\n }\r\n } else {\r\n await this.#handleAction(event, actionType, this.actor, this.token, actionId)\r\n }\r\n }\r\n\r\n /**\r\n * Handle action\r\n * @private\r\n * @param {object} event\r\n * @param {string} actionType\r\n * @param {object} actor\r\n * @param {object} token\r\n * @param {string} actionId\r\n */\r\n async #handleAction (event, actionType, actor, token, actionId) {\r\n switch (actionType) {\r\n case 'ability':\r\n this.#rollAbility(event, actor, actionId)\r\n break\r\n case 'check':\r\n this.#rollAbilityTest(event, actor, actionId)\r\n break\r\n case 'save':\r\n this.#rollAbilitySave(event, actor, actionId)\r\n break\r\n case 'condition':\r\n if (!token) return\r\n await this.#toggleCondition(event, actor, token, actionId)\r\n break\r\n case 'counter':\r\n await this.#modifyCounter(event, actor, actionId)\r\n break\r\n case 'effect':\r\n await this.#toggleEffect(event, actor, actionId)\r\n break\r\n case 'exhaustion':\r\n await this.#modifyExhaustion(event, actor)\r\n break\r\n case 'feature':\r\n case 'item':\r\n case 'spell':\r\n case 'weapon':\r\n if (this.isRenderItem()) this.renderItem(actor, actionId)\r\n else this.#useItem(event, actor, actionId)\r\n break\r\n case 'magicItem':\r\n await this.#rollMagicItem(actor, actionId)\r\n break\r\n case 'skill':\r\n this.#rollSkill(event, actor, actionId)\r\n break\r\n case 'utility':\r\n await this.#performUtilityAction(event, actor, token, actionId)\r\n break\r\n default:\r\n break\r\n }\r\n }\r\n\r\n /**\r\n * Modify Counter\r\n * @private\r\n * @param {object} event The event\r\n * @param {object} actor The actor\r\n * @param {string} actionId The action id\r\n */\r\n async #modifyCounter (event, actor, actionId) {\r\n switch (actionId) {\r\n case 'death-saves':\r\n this.#rollDeathSave(event, actor)\r\n break\r\n case 'exhaustion':\r\n await this.#modifyExhaustion(event, actor)\r\n break\r\n case 'inspiration':\r\n await this.#modifyInspiration(actor)\r\n break\r\n default:\r\n await this.#modifyCustomCounter(event, actor, actionId)\r\n break\r\n }\r\n }\r\n\r\n /**\r\n * Modify Exhaustion\r\n * @private\r\n * @param {object} event The event\r\n * @param {object} actor The actor\r\n */\r\n async #modifyExhaustion (event, actor) {\r\n const isRightClick = this.isRightClick(event)\r\n const exhaustion = actor.system.attributes.exhaustion\r\n const update = (isRightClick) ? exhaustion - 1 : exhaustion + 1\r\n if (update >= 0) {\r\n actor.update({ 'system.attributes.exhaustion': update })\r\n }\r\n }\r\n\r\n /**\r\n * Modify Inspiration\r\n * @private\r\n * @param {object} actor The actor\r\n */\r\n async #modifyInspiration (actor) {\r\n const update = !actor.system.attributes.inspiration\r\n actor.update({ 'system.attributes.inspiration': update })\r\n }\r\n\r\n /**\r\n * Modify Custom Counter\r\n * @private\r\n * @param {object} event The event\r\n * @param {object} actor The actor\r\n * * @param {string} actionId The action id\r\n */\r\n async #modifyCustomCounter (event, actor, actionId) {\r\n if (!coreModule.api.Utils.isModuleActive('dnd5e-custom-counters')) return\r\n\r\n const [id, type] = decodeURIComponent(actionId).split('>')\r\n\r\n const isRightClick = this.isRightClick(event)\r\n const isCtrl = this.isCtrl(event)\r\n let value = actor.getFlag('dnd5e-custom-counters', id)\r\n\r\n switch (type) {\r\n case 'checkbox':\r\n await actor.setFlag('dnd5e-custom-counters', id, !value)\r\n break\r\n case 'number':\r\n value = value ?? 0\r\n if (isRightClick) {\r\n if (value > 0) {\r\n await actor.setFlag('dnd5e-custom-counters', id, value - 1)\r\n }\r\n } else {\r\n await actor.setFlag('dnd5e-custom-counters', id, value + 1)\r\n }\r\n break\r\n case 'successFailure':\r\n value = value ?? {}\r\n value.success = value?.success ?? 0\r\n value.failure = value?.failure ?? 0\r\n if (isRightClick) {\r\n if (isCtrl) {\r\n if (value?.failure > 0) {\r\n await actor.setFlag('dnd5e-custom-counters', `${id}.failure`, value.failure - 1)\r\n }\r\n } else {\r\n if (value?.success > 0) {\r\n await actor.setFlag('dnd5e-custom-counters', `${id}.success`, value.success - 1)\r\n }\r\n }\r\n } else {\r\n if (isCtrl) {\r\n await actor.setFlag('dnd5e-custom-counters', `${id}.failure`, value.failure + 1)\r\n } else {\r\n await actor.setFlag('dnd5e-custom-counters', `${id}.success`, value.success + 1)\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Roll Ability\r\n * @private\r\n * @param {object} event The event\r\n * @param {object} actor The actor\r\n * @param {string} actionId The action id\r\n */\r\n #rollAbility (event, actor, actionId) {\r\n if (!actor) return\r\n if (!actor.system?.abilities) return\r\n actor.rollAbility(actionId, { event })\r\n }\r\n\r\n /**\r\n * Roll Ability Save\r\n * @private\r\n * @param {object} event The event\r\n * @param {object} actor The actor\r\n * @param {string} actionId The action id\r\n */\r\n #rollAbilitySave (event, actor, actionId) {\r\n if (!actor) return\r\n if (!actor.system?.abilities) return\r\n actor.rollAbilitySave(actionId, { event })\r\n }\r\n\r\n /**\r\n * Roll Ability Test\r\n * @private\r\n * @param {object} event The event\r\n * @param {object} actor The actor\r\n * @param {string} actionId The action id\r\n */\r\n #rollAbilityTest (event, actor, actionId) {\r\n if (!actor) return\r\n if (!actor.system?.abilities) return\r\n actor.rollAbilityTest(actionId, { event })\r\n }\r\n\r\n /**\r\n * Roll Death Save\r\n * @private\r\n * @param {object} event The event\r\n * @param {object} actor The actor\r\n */\r\n #rollDeathSave (event, actor) {\r\n actor.rollDeathSave({ event })\r\n }\r\n\r\n /**\r\n * Roll Magic Item\r\n * @private\r\n * @param {object} actor The actor\r\n * @param {string} actionId The action id\r\n */\r\n async #rollMagicItem (actor, actionId) {\r\n const actionParts = actionId.split('>')\r\n\r\n const itemId = actionParts[0]\r\n const magicEffectId = actionParts[1]\r\n\r\n const magicItemActor = await MagicItems.actor(actor.id)\r\n\r\n // magicitems module 3.0.0 does not support Item5e#use\r\n magicItemActor.roll(itemId, magicEffectId)\r\n\r\n Hooks.callAll('forceUpdateTokenActionHud')\r\n }\r\n\r\n /**\r\n * Roll Skill\r\n * @private\r\n * @param {object} event The event\r\n * @param {object} actor The actor\r\n * @param {string} actionId The action id\r\n */\r\n #rollSkill (event, actor, actionId) {\r\n if (!actor) return\r\n if (!actor.system?.skills) return\r\n actor.rollSkill(actionId, { event })\r\n }\r\n\r\n /**\r\n * Use Item\r\n * @private\r\n * @param {object} event The event\r\n * @param {object} actor The actor\r\n * @param {string} actionId The action id\r\n * @returns {object} The item\r\n */\r\n #useItem (event, actor, actionId) {\r\n const item = coreModule.api.Utils.getItem(actor, actionId)\r\n\r\n if (this.#needsRecharge(item)) {\r\n item.rollRecharge()\r\n return\r\n }\r\n\r\n return item.use({ event })\r\n }\r\n\r\n /**\r\n * Needs Recharge\r\n * @private\r\n * @param {object} item\r\n * @returns {boolean}\r\n */\r\n #needsRecharge (item) {\r\n return (\r\n item.system.recharge &&\r\n !item.system.recharge.charged &&\r\n item.system.recharge.value\r\n )\r\n }\r\n\r\n /**\r\n * Perform utility action\r\n * @param {object} event The event\r\n * @param {object} actor The actor\r\n * @param {object} token The token\r\n * @param {string} actionId The action id\r\n */\r\n async #performUtilityAction (event, actor, token, actionId) {\r\n switch (actionId) {\r\n case 'deathSave':\r\n this.#rollDeathSave(event, actor)\r\n break\r\n case 'endTurn':\r\n if (!token) break\r\n if (game.combat?.current?.tokenId === token.id) {\r\n await game.combat?.nextTurn()\r\n }\r\n break\r\n case 'initiative':\r\n await this.#rollInitiative(actor)\r\n break\r\n case 'inspiration':\r\n await this.#modifyInspiration(actor)\r\n break\r\n case 'longRest':\r\n actor.longRest()\r\n break\r\n case 'shortRest':\r\n actor.shortRest()\r\n break\r\n }\r\n\r\n // Update HUD\r\n Hooks.callAll('forceUpdateTokenActionHud')\r\n }\r\n\r\n /**\r\n * Roll Initiative\r\n * @param {object} actor The actor\r\n * @private\r\n */\r\n async #rollInitiative (actor) {\r\n if (!actor) return\r\n await actor.rollInitiative({ createCombatants: true })\r\n\r\n Hooks.callAll('forceUpdateTokenActionHud')\r\n }\r\n\r\n /**\r\n * Toggle Condition\r\n * @private\r\n * @param {object} event The event\r\n * @param {object} actor The actor\r\n * @param {object} token The token\r\n * @param {string} actionId The action id\r\n */\r\n async #toggleCondition (event, actor, token, actionId) {\r\n if (!token) return\r\n\r\n const isRightClick = this.isRightClick(event)\r\n const statusEffect = CONFIG.statusEffects.find(statusEffect => statusEffect.id === actionId)\r\n const isConvenient = (statusEffect?.flags)\r\n ? Object.hasOwn(statusEffect.flags, 'dfreds-convenient-effects')\r\n ? statusEffect.flags['dfreds-convenient-effects'].isConvenient\r\n : null\r\n : null ??\r\n actionId.startsWith('Convenient Effect')\r\n\r\n if (game.dfreds && isConvenient) {\r\n isRightClick\r\n ? await game.dfreds.effectInterface.toggleEffect(statusEffect.name ?? statusEffect.label, { overlay: true })\r\n : await game.dfreds.effectInterface.toggleEffect(statusEffect.name ?? statusEffect.label)\r\n } else {\r\n const condition = this.#findCondition(actionId)\r\n if (!condition) return\r\n const effect = this.#findEffect(actor, actionId)\r\n if (effect?.disabled) { await effect.delete() }\r\n\r\n isRightClick\r\n ? await token.toggleEffect(condition, { overlay: true })\r\n : await token.toggleEffect(condition)\r\n }\r\n\r\n Hooks.callAll('forceUpdateTokenActionHud')\r\n }\r\n\r\n /**\r\n * Find condition\r\n * @private\r\n * @param {string} actionId The action id\r\n * @returns {object} The condition\r\n */\r\n #findCondition (actionId) {\r\n return CONFIG.statusEffects.find((effect) => effect.id === actionId)\r\n }\r\n\r\n /**\r\n * Find effect\r\n * @param {object} actor The actor\r\n * @param {string} actionId The action id\r\n * @returns {object} The effect\r\n */\r\n #findEffect (actor, actionId) {\r\n if (game.version.startsWith('11')) {\r\n return actor.effects.find(effect => effect.statuses.every(status => status === actionId))\r\n } else {\r\n // V10\r\n return actor.effects.find(effect => effect.flags?.core?.statusId === actionId)\r\n }\r\n }\r\n\r\n /**\r\n * Toggle Effect\r\n * @private\r\n * @param {object} event The event\r\n * @param {object} actor The actor\r\n * @param {string} actionId The action id\r\n */\r\n async #toggleEffect (event, actor, actionId) {\r\n const effects = 'find' in actor.effects.entries ? actor.effects.entries : actor.effects\r\n let effect = effects.find(effect => effect.id === actionId)\r\n\r\n // only allow deletion if effect is directly on this actor\r\n let internalEffect = true\r\n\r\n // if the effect isn't directly on the actor, search all applicable effects for it\r\n if (!effect) {\r\n internalEffect = false\r\n for (const e of actor.allApplicableEffects()) {\r\n if (e.id === actionId) {\r\n effect = e\r\n }\r\n }\r\n }\r\n\r\n if (!effect) return\r\n\r\n const isRightClick = this.isRightClick(event)\r\n\r\n if (isRightClick && internalEffect) {\r\n await effect.delete()\r\n } else {\r\n await effect.update({ disabled: !effect.disabled })\r\n }\r\n\r\n Hooks.callAll('forceUpdateTokenActionHud')\r\n }\r\n\r\n /**\r\n * Handle action hover\r\n * @override\r\n * @param {object} event\r\n * @param {string} encodedValue\r\n */\r\n async handleActionHover (event, encodedValue) {\r\n const types = ['feature', 'item', 'spell', 'weapon', 'magicItem']\r\n const [actionType, actionId] = encodedValue.split('|')\r\n\r\n if (!types.includes(actionType)) return\r\n\r\n const item = coreModule.api.Utils.getItem(this.actor, actionId)\r\n\r\n switch (event.type) {\r\n case 'mouseenter':\r\n case 'mouseover':\r\n Hooks.call('tokenActionHudSystemActionHoverOn', event, item)\r\n break\r\n case 'mouseleave':\r\n case 'mouseout':\r\n Hooks.call('tokenActionHudSystemActionHoverOff', event, item)\r\n break\r\n }\r\n }\r\n }\r\n})\r\n","import { RollHandler } from './roll-handler.js'\r\n\r\nexport class RollHandlerObsidian extends RollHandler {\r\n /**\r\n * Roll Ability Test\r\n * @override\r\n * @param {object} event\r\n * @param {string} actionId\r\n */\r\n _rollAbilityTest (event, actionId) {\r\n OBSIDIAN.Items.roll(super.actor, { roll: 'abl', abl: actionId })\r\n }\r\n\r\n /**\r\n * Roll Ability Save\r\n * @override\r\n * @param {object} event\r\n * @param {string} actorId\r\n * @param {string} tokenId\r\n * @param {string} actionId\r\n */\r\n _rollAbilitySave (event, actionId) {\r\n OBSIDIAN.Items.roll(super.actor, { roll: 'save', save: actionId })\r\n }\r\n\r\n /**\r\n * Roll Skill\r\n * @override\r\n * @param {object} event\r\n * @param {string} actionId\r\n */\r\n _rollSkill (event, actionId) {\r\n OBSIDIAN.Items.roll(super.actor, { roll: 'skl', skl: actionId })\r\n }\r\n\r\n /**\r\n * Use Item\r\n * @override\r\n * @param {object} event\r\n * @param {string} actionId\r\n */\r\n _useItem (event, actionId) {\r\n OBSIDIAN.Items.roll(super.actor, { roll: 'item', id: actionId })\r\n }\r\n}\r\n","import { GROUP } from './constants.js'\r\n\r\n/**\r\n * Default categories and groups\r\n */\r\nexport let DEFAULTS = null\r\n\r\nHooks.once('tokenActionHudCoreApiReady', async (coreModule) => {\r\n const groups = GROUP\r\n Object.values(groups).forEach(group => {\r\n group.name = coreModule.api.Utils.i18n(group.name)\r\n group.listName = `Group: ${coreModule.api.Utils.i18n(group.name)}`\r\n })\r\n const groupsArray = Object.values(groups)\r\n DEFAULTS = {\r\n layout: [\r\n {\r\n nestId: 'inventory',\r\n id: 'inventory',\r\n name: coreModule.api.Utils.i18n('DND5E.Inventory'),\r\n groups: [\r\n { ...groups.weapons, nestId: 'inventory_weapons' },\r\n { ...groups.equipment, nestId: 'inventory_equipment' },\r\n { ...groups.consumables, nestId: 'inventory_consumables' },\r\n { ...groups.tools, nestId: 'inventory_tools' },\r\n { ...groups.containers, nestId: 'inventory_containers' },\r\n { ...groups.loot, nestId: 'inventory_loot' }\r\n ]\r\n },\r\n {\r\n nestId: 'features',\r\n id: 'features',\r\n name: coreModule.api.Utils.i18n('DND5E.Features'),\r\n groups: [\r\n { ...groups.activeFeatures, nestId: 'features_active-features' },\r\n { ...groups.passiveFeatures, nestId: 'features_passive-features' }\r\n ]\r\n },\r\n {\r\n nestId: 'spells',\r\n id: 'spells',\r\n name: coreModule.api.Utils.i18n('ITEM.TypeSpellPl'),\r\n groups: [\r\n { ...groups.atWillSpells, nestId: 'spells_at-will-spells' },\r\n { ...groups.innateSpells, nestId: 'spells_innate-spells' },\r\n { ...groups.pactSpells, nestId: 'spells_pact-spells' },\r\n { ...groups.cantrips, nestId: 'spells_cantrips' },\r\n { ...groups._1stLevelSpells, nestId: 'spells_1st-level-spells' },\r\n { ...groups._2ndLevelSpells, nestId: 'spells_2nd-level-spells' },\r\n { ...groups._3rdLevelSpells, nestId: 'spells_3rd-level-spells' },\r\n { ...groups._4thLevelSpells, nestId: 'spells_4th-level-spells' },\r\n { ...groups._5thLevelSpells, nestId: 'spells_5th-level-spells' },\r\n { ...groups._6thLevelSpells, nestId: 'spells_6th-level-spells' },\r\n { ...groups._7thLevelSpells, nestId: 'spells_7th-level-spells' },\r\n { ...groups._8thLevelSpells, nestId: 'spells_8th-level-spells' },\r\n { ...groups._9thLevelSpells, nestId: 'spells_9th-level-spells' }\r\n ]\r\n },\r\n {\r\n nestId: 'attributes',\r\n id: 'attributes',\r\n name: coreModule.api.Utils.i18n('DND5E.Attributes'),\r\n groups: [\r\n { ...groups.abilities, nestId: 'attributes_abilities' },\r\n { ...groups.skills, nestId: 'attributes_skills' }\r\n ]\r\n },\r\n {\r\n nestId: 'effects',\r\n id: 'effects',\r\n name: coreModule.api.Utils.i18n('DND5E.Effects'),\r\n groups: [\r\n { ...groups.temporaryEffects, nestId: 'effects_temporary-effects' },\r\n { ...groups.passiveEffects, nestId: 'effects_passive-effects' },\r\n { ...groups.conditions, nestId: 'effects_conditions' }\r\n ]\r\n },\r\n {\r\n nestId: 'utility',\r\n id: 'utility',\r\n name: coreModule.api.Utils.i18n('tokenActionHud.utility'),\r\n groups: [\r\n { ...groups.combat, nestId: 'utility_combat' },\r\n { ...groups.token, nestId: 'utility_token' },\r\n { ...groups.rests, nestId: 'utility_rests' },\r\n { ...groups.utility, nestId: 'utility_utility' }\r\n ]\r\n }\r\n ],\r\n groups: groupsArray\r\n }\r\n})\r\n","import { MODULE } from './constants.js'\r\n\r\nexport function register (updateFunc) {\r\n game.settings.register(MODULE.ID, 'abbreviateSkills', {\r\n name: game.i18n.localize(\r\n 'tokenActionHud.dnd5e.settings.abbreviateSkills.name'\r\n ),\r\n hint: game.i18n.localize(\r\n 'tokenActionHud.dnd5e.settings.abbreviateSkills.hint'\r\n ),\r\n scope: 'client',\r\n config: true,\r\n type: Boolean,\r\n default: false,\r\n onChange: (value) => {\r\n updateFunc(value)\r\n }\r\n })\r\n\r\n game.settings.register(MODULE.ID, 'showSlowActions', {\r\n name: game.i18n.localize(\r\n 'tokenActionHud.dnd5e.settings.showSlowActions.name'\r\n ),\r\n hint: game.i18n.localize(\r\n 'tokenActionHud.dnd5e.settings.showSlowActions.hint'\r\n ),\r\n scope: 'client',\r\n config: true,\r\n type: Boolean,\r\n default: true,\r\n onChange: (value) => {\r\n updateFunc(value)\r\n }\r\n })\r\n\r\n game.settings.register(MODULE.ID, 'displaySpellInfo', {\r\n name: game.i18n.localize(\r\n 'tokenActionHud.dnd5e.settings.displaySpellInfo.name'\r\n ),\r\n hint: game.i18n.localize(\r\n 'tokenActionHud.dnd5e.settings.displaySpellInfo.hint'\r\n ),\r\n scope: 'client',\r\n config: true,\r\n type: Boolean,\r\n default: true,\r\n onChange: (value) => {\r\n updateFunc(value)\r\n }\r\n })\r\n\r\n game.settings.register(MODULE.ID, 'showUnchargedItems', {\r\n name: game.i18n.localize(\r\n 'tokenActionHud.dnd5e.settings.showUnchargedItems.name'\r\n ),\r\n hint: game.i18n.localize(\r\n 'tokenActionHud.dnd5e.settings.showUnchargedItems.hint'\r\n ),\r\n scope: 'client',\r\n config: true,\r\n type: Boolean,\r\n default: false,\r\n onChange: (value) => {\r\n updateFunc(value)\r\n }\r\n })\r\n\r\n game.settings.register(MODULE.ID, 'showUnequippedItems', {\r\n name: game.i18n.localize(\r\n 'tokenActionHud.dnd5e.settings.showUnequippedItems.name'\r\n ),\r\n hint: game.i18n.localize(\r\n 'tokenActionHud.dnd5e.settings.showUnequippedItems.hint'\r\n ),\r\n scope: 'client',\r\n config: true,\r\n type: Boolean,\r\n default: false,\r\n onChange: (value) => {\r\n updateFunc(value)\r\n }\r\n })\r\n\r\n game.settings.register(MODULE.ID, 'showUnequippedItemsNpcs', {\r\n name: game.i18n.localize(\r\n 'tokenActionHud.dnd5e.settings.showUnequippedItemsNpcs.name'\r\n ),\r\n hint: game.i18n.localize(\r\n 'tokenActionHud.dnd5e.settings.showUnequippedItemsNpcs.hint'\r\n ),\r\n scope: 'client',\r\n config: true,\r\n type: Boolean,\r\n default: true,\r\n onChange: (value) => {\r\n updateFunc(value)\r\n }\r\n })\r\n\r\n game.settings.register(MODULE.ID, 'showUnpreparedSpells', {\r\n name: game.i18n.localize(\r\n 'tokenActionHud.dnd5e.settings.showUnpreparedSpells.name'\r\n ),\r\n hint: game.i18n.localize(\r\n 'tokenActionHud.dnd5e.settings.showUnpreparedSpells.hint'\r\n ),\r\n scope: 'client',\r\n config: true,\r\n type: Boolean,\r\n default: false,\r\n onChange: (value) => {\r\n updateFunc(value)\r\n }\r\n })\r\n\r\n game.settings.register(MODULE.ID, 'showItemsWithoutActivationCosts', {\r\n name: game.i18n.localize(\r\n 'tokenActionHud.dnd5e.settings.showItemsWithoutActivationCosts.name'\r\n ),\r\n hint: game.i18n.localize(\r\n 'tokenActionHud.dnd5e.settings.showItemsWithoutActivationCosts.hint'\r\n ),\r\n scope: 'client',\r\n config: true,\r\n type: Boolean,\r\n default: false,\r\n onChange: (value) => {\r\n updateFunc(value)\r\n }\r\n })\r\n}\r\n","// System Module Imports\r\nimport { ActionHandler } from './action-handler.js'\r\nimport { MagicItemActionHandlerExtender } from './magic-items-extender.js'\r\nimport { RollHandler as Core } from './roll-handler.js'\r\nimport { RollHandlerObsidian as Obsidian5e } from './roll-handler-obsidian.js'\r\nimport { DEFAULTS } from './defaults.js'\r\nimport * as systemSettings from './settings.js'\r\n\r\nexport let SystemManager = null\r\n\r\nHooks.once('tokenActionHudCoreApiReady', async (coreModule) => {\r\n SystemManager = class SystemManager extends coreModule.api.SystemManager {\r\n /** @override */\r\n getActionHandler () {\r\n const actionHandler = new ActionHandler()\r\n if (coreModule.api.Utils.isModuleActive('magic-items-2') || coreModule.api.Utils.isModuleActive('magicitems')) { actionHandler.addActionHandlerExtender(new MagicItemActionHandlerExtender(actionHandler)) }\r\n return actionHandler\r\n }\r\n\r\n /** @override */\r\n getAvailableRollHandlers () {\r\n let coreTitle = 'Core D&D5e'\r\n\r\n if (coreModule.api.Utils.isModuleActive('midi-qol')) { coreTitle += ` [supports ${coreModule.api.Utils.getModuleTitle('midi-qol')}]` }\r\n\r\n const choices = { core: coreTitle }\r\n coreModule.api.SystemManager.addHandler(choices, 'obsidian')\r\n\r\n return choices\r\n }\r\n\r\n /** @override */\r\n getRollHandler (rollHandlerId) {\r\n let rollHandler\r\n switch (rollHandlerId) {\r\n case 'obsidian':\r\n rollHandler = new Obsidian5e()\r\n break\r\n case 'core':\r\n default:\r\n rollHandler = new Core()\r\n break\r\n }\r\n\r\n return rollHandler\r\n }\r\n\r\n /** @override */\r\n registerSettings (onChangeFunction) {\r\n systemSettings.register(onChangeFunction)\r\n }\r\n\r\n /** @override */\r\n async registerDefaults () {\r\n const defaults = DEFAULTS\r\n // If the 'Magic Items' module is active, then add a group for it\r\n if (game.modules.get('magicitems')?.active || game.modules.get('magic-items-2')?.active) {\r\n const name = coreModule.api.Utils.i18n('tokenActionHud.dnd5e.magicItems')\r\n defaults.groups.push(\r\n {\r\n id: 'magic-items',\r\n name,\r\n listName: `Group: ${name}`,\r\n type: 'system'\r\n }\r\n )\r\n defaults.groups.sort((a, b) => a.id.localeCompare(b.id))\r\n }\r\n return defaults\r\n }\r\n }\r\n})\r\n","import { SystemManager } from './system-manager.js'\r\nimport { MODULE, REQUIRED_CORE_MODULE_VERSION } from './constants.js'\r\n\r\nHooks.on('tokenActionHudCoreApiReady', async () => {\r\n const module = game.modules.get(MODULE.ID)\r\n module.api = {\r\n requiredCoreModuleVersion: REQUIRED_CORE_MODULE_VERSION,\r\n SystemManager\r\n }\r\n Hooks.call('tokenActionHudSystemReady', module)\r\n})\r\n"],"names":["MODULE","ID","CORE_MODULE","REQUIRED_CORE_MODULE_VERSION","ACTION_TYPE","ability","check","condition","counter","effect","exhaustion","feature","item","save","skill","spell","utility","ACTIVATION_TYPE_ICON","bonus","crew","day","hour","lair","minute","legendary","reaction","special","CONCENTRATION_ICON","CONDITION","blind","uuid","blinded","charmed","deaf","deafened","fear","frightened","grappled","incapacitated","invisible","paralysis","paralyzed","petrified","poison","poisoned","prone","restrain","restrained","stun","stunned","unconscious","GROUP","_1stLevelSpells","id","name","type","_2ndLevelSpells","_3rdLevelSpells","_4thLevelSpells","_5thLevelSpells","_6thLevelSpells","_7thLevelSpells","_8thLevelSpells","_9thLevelSpells","abilities","actions","activeFeatures","artificerInfusions","atWillSpells","backgroundFeatures","bonusActions","cantrips","channelDivinity","checks","classFeatures","combat","conditions","consumables","containers","counters","crewActions","defensiveTactics","eldritchInvocations","elementalDisciplines","equipment","equipped","feats","fightingStyles","huntersPrey","innateSpells","kiAbilities","lairActions","legendaryActions","loot","maneuvers","metamagicOptions","monsterFeatures","multiattacks","otherActions","pactBoons","pactSpells","passiveEffects","passiveFeatures","psionicPowers","raceFeatures","reactions","rests","runes","saves","skills","superiorHuntersDefense","temporaryEffects","token","tools","unequipped","weapons","PREPARED_ICON","PROFICIENCY_LEVEL_ICON","RARITY","common","uncommon","rare","veryRare","artifact","RITUAL_ICON","WEAPON_PROPERTY","ada","amm","fin","fir","foc","hvy","lgt","lod","mgc","rch","rel","ret","sil","spc","thr","two","ver","Utils","Hooks","once","async","coreModule","static","key","defaultValue","value","game","settings","get","api","Logger","debug","set","ActionHandler","actors","tokens","actorType","items","abbreviateSkills","displaySpellInfo","showItemsWithoutActivationCosts","showUnchargedItems","showUnequippedItems","showUnpreparedSpells","activationgroupIds","featuregroupIds","inventorygroupIds","spellgroupIds","featureActions","inventoryActions","spellActions","systemVersion","dnd5e","version","groupIds","this","actor","getActors","getTokens","discardSlowItems","sortItemsByName","getSetting","buildCharacterActions","buildVehicleActions","buildMultipleTokenActions","Promise","all","buildConditions","buildEffects","buildFeatures","buildInventory","buildSpells","buildAbilities","buildCombat","buildCounters","buildExhaustion","buildRests","buildSkills","buildUtility","actionType","groupId","system","CONFIG","DND5E","length","Object","entries","filter","map","abilityId","abbreviatedName","charAt","toUpperCase","slice","label","listName","i18n","encodedValue","join","delimiter","icon1","getProficiencyIcon","proficient","mod","info1","text","getModifier","info2","groupData","addActions","data","actionData","activationItems","Map","activationTypeMappings","action","reactiondamage","reactionmanual","other","activationType","activation","keys","includes","has","activationGroupId","groupDataClone","defaultSelected","parentgroupData","addGroup","addGroupInfo","buildActions","combatTypes","initiative","endTurn","current","tokenId","combatType","cssClass","tokenIds","getControlledTokens","combatants","combatant","currentInitiative","class","every","statusEffects","startsWith","effects","some","statuses","status","disabled","flags","core","statusId","img","getImage","tooltipData","getConditionTooltipData","tooltip","getTooltip","isModuleActive","_","visible","encodeURIComponent","active","attributes","death","success","failure","getFlag","allApplicableEffects","size","effectId","isSuppressed","parent","identified","user","isGM","isTemporary","featuresMap","featureTypes","classFeatureTypes","subType","subtype","featureType","groupNameMappings","buildActivations","inventoryMap","hasQuantity","quantity","isActiveItem","isUsableItem","isEquippedItem","restTypes","shortRest","longRest","restType","total","error","spellsMap","isUsableSpell","preparation","mode","level","systemSpells","spells","reverse","pactSlot","spellSlots","spellSlotAvailable","pactSlotAvailable","hasValue","hasMax","max","hasLevel","slotAvailable","push","slotsAvailable","pactSpellEquivalent","findIndex","groupMappings","spellMode","spellSlotModes","groupName","levelInfo","find","spellSlot","slots","groupInfo","info","utilityTypes","deathSave","inspiration","hp","utilityType","options","getAction","entity","_id","recharge","charged","hasOwn","getActivationTypeIcon","icon2","getPreparedIcon","icon3","getConcentrationIcon","getItemInfo","info3","getTooltipData","activationTypes","abilityActivationTypes","at","uses","prepared","preparationModes","spellPreparationModes","preparationMode","getSpellInfo","getQuantityData","getUsesData","getConsumeData","componentsArray","components","properties","forEach","component","title","allowedTypes","consumeName","consumeAmount","per","prompt","of","period","limitedUsePeriods","amount","undefined","consumeId","consume","target","consumeType","parentId","substr","lastIndexOf","foundry","utils","getProperty","slowActivationTypes","filteredItems","proficiencyLevels","icon","tooltipsSetting","unidentified","description","modifiers","rarity","traits","chatProperties","equippableItemCardProperties","activatedEffectCardProperties","p","getWeaponProperties","fromUuid","content","nameHtml","descriptionLocalised","TextEditor","enrichHTML","rarityHtml","propertiesHtml","property","traitsHtml","trait","traits2Html","traits2","traitsAltHtml","traitsAlt","modifiersHtml","modifier","enabled","tagsJoined","tagsHtml","weaponProperties","selected","MagicItemActionHandlerExtender","ActionHandlerExtender","constructor","actionHandler","super","MagicItems","magicItems","parentGroupData","magicItem","attuned","_isItemAttuned","_isItemEquipped","charges","ownedEntries","entry","consumption","baseLevel","attunment","attunementTypes","REQUIRED","RollHandler","event","actionId","split","handleAction","rollAbility","rollAbilityTest","rollAbilitySave","toggleCondition","modifyCounter","toggleEffect","modifyExhaustion","isRenderItem","renderItem","useItem","rollMagicItem","rollSkill","performUtilityAction","rollDeathSave","modifyInspiration","modifyCustomCounter","isRightClick","update","decodeURIComponent","isCtrl","setFlag","actionParts","itemId","magicEffectId","roll","callAll","getItem","needsRecharge","use","rollRecharge","nextTurn","rollInitiative","createCombatants","statusEffect","isConvenient","dfreds","effectInterface","overlay","findCondition","findEffect","delete","internalEffect","e","call","RollHandlerObsidian","_rollAbilityTest","OBSIDIAN","Items","abl","_rollAbilitySave","_rollSkill","skl","_useItem","DEFAULTS","register","updateFunc","localize","hint","scope","config","Boolean","default","onChange","groups","values","group","groupsArray","layout","nestId","SystemManager","getActionHandler","addActionHandlerExtender","getAvailableRollHandlers","coreTitle","getModuleTitle","choices","addHandler","getRollHandler","rollHandlerId","rollHandler","Obsidian5e","Core","registerSettings","onChangeFunction","systemSettings.register","defaults","modules","sort","a","b","localeCompare","on","module","requiredCoreModuleVersion"],"mappings":"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"} \ No newline at end of file