{"version":3,"file":"xdy-pf2e-workbench.js","names":["#handleRollButtonClick","t","e","#macro","#compendium","#target","#initiateCore"],"sources":["../src/module/constants.ts","../src/module/preloadTemplates.ts","../src/module/utils/systems.ts","../src/module/lifecycle.ts","../src/module/utils/logging.ts","../src/module/utils.ts","../src/module/feature/settingsHandler/index.ts","../src/module/settings/menu.ts","../src/module/settings/npc-mystification.ts","../src/module/xdy-pf2e-constants.ts","../src/module/feature/tokenMystificationHandler/traits-name-generator.ts","../src/module/feature/tokenMystificationHandler/index.ts","../src/module/feature/heroPointHandler/index.ts","../src/module/feature/initiativeHandler/index.ts","../src/module/feature/canvas-pointer/constants.ts","../src/module/feature/canvas-pointer/network.ts","../src/module/feature/canvas-pointer/index.ts","../src/module/keybinds.ts","../src/module/feature/npc-scale-data.json","../src/module/feature/npc-roller/NpcRoller.ts","../src/module/feature/cr-scaler/Utilities.ts","../src/module/feature/cr-scaler/NPCScalerUtil.ts","../src/module/feature/cr-scaler/NPCScaler.ts","../node_modules/.pnpm/remeda@2.39.0/node_modules/remeda/dist/lazyDataLastImpl--3B10z3s.js","../node_modules/.pnpm/remeda@2.39.0/node_modules/remeda/dist/purry.js","../node_modules/.pnpm/remeda@2.39.0/node_modules/remeda/dist/pick.js","../src/module/feature/macros/follow-the-expert.ts","../src/module/feature/macros/basicActionMacros.ts","../src/module/feature/macros/buildNpcSpellbookJournal.ts","../src/module/utils/settings.ts","../src/module/feature/damageHandler/index.ts","../src/module/feature/damageHandler/toolbeltIntegration.ts","../src/module/hooks/combatStartHook.ts","../src/module/feature/damageHandler/dyingHandling.ts","../src/module/feature/reminders/checkAttackValidity.ts","../src/module/feature/reminders/index.ts","../src/module/feature/reminders/reminderBreathWeapon.ts","../src/module/hooks/createChatMessageHook.ts","../src/module/feature/qolHandler/index.ts","../src/module/hooks/createTokenHook.ts","../src/module/hooks/deleteCombatHook.ts","../src/module/hooks/deleteItemHook.ts","../src/module/feature/conditionHandler/index.ts","../src/module/hooks/pf2eEndTurnHook.ts","../src/module/hooks/pf2eRerollHook.ts","../src/module/hooks/pf2eToolbeltRollSaveHook.ts","../src/module/hooks/pf2eStartTurnHook.ts","../src/module/hooks/pf2eSystemReadyHook.ts","../src/module/feature/qolHandler/buildPublicSpellMessage.ts","../src/module/feature/qolHandler/handlePrivateSpellcasting.ts","../src/module/hooks/preCreateChatMessageHook.ts","../src/module/feature/spells/flags.ts","../src/module/feature/spells/helpers.ts","../src/module/utils/locks.ts","../src/module/feature/spells/spellChatUtils.ts","../src/module/feature/spells/economyHandler.ts","../src/module/feature/spells/spellData.ts","../src/module/feature/spells/spellActorQueries.ts","../src/module/feature/spells/dialogHelper.ts","../src/module/feature/spells/learn/spellRoll.ts","../src/module/feature/spells/learn/batchLearn.ts","../src/module/feature/spells/learn/learnSpellHandler.ts","../src/module/feature/spells/learn/spellAddInterceptHandler.ts","../src/module/feature/spells/learn/scrollCreateIntercept.ts","../src/module/hooks/preCreateItemHook.ts","../src/module/hooks/preUpdateActorHook.ts","../src/module/hooks/preUpdateTokenHook.ts","../src/module/hooks/readyHook.ts","../src/module/feature/characterOglContent/index.ts","../src/module/feature/actorSheet/index.ts","../src/module/hooks/renderActorSheetHook.ts","../src/module/feature/qolHandler/hidePrivateSpellName.ts","../src/module/hooks/renderChatMessageHook.ts","../src/module/hooks/renderGamePauseHook.ts","../src/module/hooks/renderItemSheetHook.ts","../src/module/hooks/renderTokenHUDHook.ts","../src/module/hooks/updateCombatHook.ts","../src/module/feature/cr-scaler/NPCScalerSetup.ts","../src/module/settings/item-mystification.ts","../src/module/settings/reminders.ts","../src/module/settings/automation-world.ts","../src/module/settings/automation-client.ts","../src/module/settings/qol-world.ts","../src/module/settings/houseRules.ts","../src/module/settings/canvas-features.ts","../src/module/settings/index.ts","../src/module/feature/api/getAllFromAllowedPacks.ts","../src/module/feature/macros/refocus.ts","../src/module/feature/macros/hypercognition.ts","../src/module/feature/macros/npcScaler.ts","../src/module/utils/handlebarsHelpers.ts","../src/module/xdy-pf2e-workbench.ts"],"sourcesContent":["export const MODULENAME = \"xdy-pf2e-workbench\";\n","import { MODULENAME } from \"./constants.ts\";\n\nexport async function preloadTemplates(): Promise {\n const templatePaths: string[] = [`modules/${MODULENAME}/templates/feature/heropoint-handler/index.hbs`];\n\n await foundry.applications.handlebars.loadTemplates(templatePaths);\n}\n","/**\n * System utilities for handling both PF2e and SF2e systems.\n */\n\nexport enum GameSystem {\n PF2E = \"pf2e\",\n SF2E = \"sf2e\",\n}\n\ninterface FlaggableObject {\n flags?: Record>;\n}\n\ninterface FlagOperableObject extends FlaggableObject {\n setFlag?: (scope: string, key: string, value: unknown) => Promise;\n unsetFlag?: (scope: string, key: string) => Promise;\n}\n\nexport function getSystemId(): GameSystem {\n const DEFAULT_SYSTEM = GameSystem.PF2E;\n const systemId = String(game.system.id);\n return systemId === GameSystem.SF2E ? GameSystem.SF2E : DEFAULT_SYSTEM;\n}\n\nexport function getFlag(obj: FlaggableObject, path: string): T | undefined {\n // Supports dot notation, e.g., \"context.type\"\n const systemId = getSystemId();\n const systemFlags = obj?.flags?.[systemId];\n if (!systemFlags) return undefined;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return path.split(\".\").reduce((acc: any, part) => acc?.[part], systemFlags) as T | undefined;\n}\n\nexport async function setFlag(obj: FlagOperableObject, path: string, value: unknown): Promise {\n const systemId = getSystemId();\n const flagPath = `${systemId}.${path}`;\n if (typeof obj.setFlag === \"function\") {\n return await obj.setFlag(\"core\", flagPath, value);\n }\n throw new Error(\"Object does not support setFlag method\");\n}\n\nexport async function unsetFlag(obj: FlagOperableObject, path: string): Promise {\n const systemId = getSystemId();\n const flagPath = `${systemId}.${path}`;\n if (typeof obj.unsetFlag === \"function\") {\n return await obj.unsetFlag(\"core\", flagPath);\n }\n throw new Error(\"Object does not support unsetFlag method\");\n}\n\nexport function getSystemSetting(namespace: string, key: string): T {\n const systemId = getSystemId();\n return game.settings.get(systemId, `${namespace}.${key}`) as T;\n}\n\nexport async function setSystemSetting(namespace: string, key: string, value: unknown): Promise {\n const systemId = getSystemId();\n return await game.settings.set(systemId, `${namespace}.${key}`, value);\n}\n\nexport function getSetting(key: string): T {\n const systemId = getSystemId();\n return game.settings.get(systemId, key) as T;\n}\n\nexport async function setSetting(key: string, value: unknown): Promise {\n const systemId = getSystemId();\n return await game.settings.set(systemId, key, value);\n}\n\nexport function getPackName(baseName: string): string {\n const systemId = getSystemId();\n return systemId === GameSystem.SF2E ? `${baseName}-sf2e` : baseName;\n}\n\nexport function getModulePackId(packBaseName: string, moduleId = \"xdy-pf2e-workbench\"): string {\n const systemSpecificName = getPackName(packBaseName);\n return `${moduleId}.${systemSpecificName}`;\n}\n","export enum Phase {\n DOWN = 0, // Before init, not sure if it has a name in foundry\n INIT = 10,\n SETUP = 20,\n READY = 30,\n ACTIVE = 40, // After ready, not sure if it has a name in foundry\n}\n\nexport let phase: Phase = Phase.DOWN;\n\nexport function setPhase(value: Phase): void {\n phase = value;\n}\n","import { MODULENAME } from \"../constants.ts\";\nimport { Phase, phase } from \"../lifecycle.ts\";\n\nconst LogLevel = {\n TRACE: 0,\n DEBUG: 1,\n INFO: 2,\n WARN: 3,\n ERROR: 4,\n} as const;\n\nexport function logTrace(...args: unknown[]): void {\n log(LogLevel.TRACE, ...args);\n}\n\nexport function logDebug(...args: unknown[]): void {\n log(LogLevel.DEBUG, ...args);\n}\n\nexport function logInfo(...args: unknown[]): void {\n log(LogLevel.INFO, ...args);\n}\n\nexport function logWarn(...args: unknown[]): void {\n log(LogLevel.WARN, ...args);\n}\n\nexport function logError(...args: unknown[]): void {\n log(LogLevel.ERROR, ...args);\n}\n\nfunction log(logLevel: number = LogLevel.INFO, ...args: unknown[]): void {\n let threshold: number = LogLevel.INFO;\n if (phase >= Phase.READY) {\n threshold = Number(game.settings.get(MODULENAME, \"logLevel\")) ?? LogLevel.INFO;\n }\n\n if (logLevel < threshold) return;\n\n switch (logLevel) {\n case LogLevel.TRACE:\n console.trace(...args);\n break;\n case LogLevel.DEBUG:\n console.debug(...args);\n break;\n case LogLevel.INFO:\n console.info(...args);\n break;\n case LogLevel.WARN:\n console.warn(...args);\n break;\n case LogLevel.ERROR:\n console.error(...args);\n break;\n }\n}\n","import { ActorPF2e, ChatMessagePF2e, PhysicalItemPF2e } from \"foundry-pf2e\";\nimport { MODULENAME } from \"./constants.ts\";\nimport BaseUser from \"foundry/common/documents/user.mjs\";\nimport * as systems from \"./utils/systems.ts\";\nimport { logError } from \"./utils/logging.ts\";\n\nexport function getModuleSetting(key: string): T {\n const value = game.settings.get(MODULENAME, key);\n if (value === undefined || value === null) {\n logError(`${MODULENAME} | Setting \"${key}\" returned ${value}`);\n }\n return value as T;\n}\n\nexport function getModuleSettingAsNumber(key: string, fallback = 0): number {\n const raw = game.settings.get(MODULENAME, key);\n if (raw === null || raw === undefined) return fallback;\n const n = Number.parseInt(String(raw));\n return Number.isNaN(n) ? fallback : n;\n}\n\nexport function actorHasItemBySlug(actor: ActorPF2e, slug: string): boolean {\n for (const item of actor.items) {\n if ((item as unknown as { slug?: string }).slug === slug) return true;\n }\n return false;\n}\n\nfunction shouldIHandleThisMessage(message: ChatMessagePF2e, playerCondition = true, gmCondition = true): boolean {\n const amIMessageSender = message.author?.id === game.user?.id;\n if (!game.user?.isGM && playerCondition && amIMessageSender) {\n return true;\n } else if (game.user?.isGM && gmCondition && amIMessageSender) {\n return true;\n }\n return false;\n}\n\n// TODO Can this be reworked to not parse the message?\nfunction degreeOfSuccessWithRerollHandling(message: ChatMessagePF2e): string {\n const context = systems.getFlag>(message, \"context\");\n let degreeOfSuccess = context?.outcome ?? \"\";\n if (context?.isReroll) {\n const match = message.flavor?.match('Result: )[0];\n}\n\nexport function sendHeldItemChatMessage(\n actor: ActorPF2e,\n items: PhysicalItemPF2e[],\n i18nKey: string,\n context: string,\n): void {\n const message = game.i18n.format(i18nKey, {\n name: game?.scenes?.current?.tokens?.find((t) => t.actor?.id === actor.id)?.name ?? actor.name,\n items: items.map((i) => i.name).join(\", \"),\n });\n fireAndForget(\n ChatMessage.create({\n flavor: message,\n speaker: ChatMessage.getSpeaker({ actor }),\n }),\n context,\n );\n}\n\nexport {\n shouldIHandleThisMessage,\n degreeOfSuccessWithRerollHandling,\n isFirstGM,\n isActuallyDamageRoll,\n getActorFromMessage,\n};\n\nexport function capitalize(s: string): string {\n return s.charAt(0).toUpperCase() + s.slice(1);\n}\n\nexport const NOT_MYSTIFIED_VALUE = \"999\";\n\nexport const MAX_ABSOLUTE_LEVEL = 20;\n\ntype Result = { ok: true; value: T } | { ok: false };\n\n/**\n * Fire-and-forget a promise with error logging.\n * Use when there is no result or it does not matter.\n */\nexport function fireAndForget(promise: Promise, context: string): void {\n promise.catch((err) => logError(`${MODULENAME} | ${context}:`, err));\n}\n\nasync function tryWithLogging(fn: () => Promise, context: string): Promise> {\n try {\n return { ok: true, value: await fn() };\n } catch (err) {\n logError(`${MODULENAME} | ${context}:`, err);\n return { ok: false };\n }\n}\n\nexport async function tryOrDefault(fn: () => Promise, fallback: T, context: string): Promise {\n const result = await tryWithLogging(fn, context);\n return result.ok ? result.value : fallback;\n}\n\nexport function shouldIHandleThis(actor: ActorPF2e | null): boolean | null {\n if (!actor) return null;\n const currentUser = game.users.current;\n const activePlayers = game.users.players.filter((u) => u.active);\n const assignedUser = activePlayers.find((u) => u.character === actor);\n const anyoneWithPermission = activePlayers.find((u) => actor.canUserModify(u, \"update\"));\n const updater =\n currentUser?.active && actor.canUserModify(currentUser, \"update\")\n ? currentUser\n : (assignedUser ?? game.users.activeGM ?? anyoneWithPermission ?? null);\n return game.user.id === updater?.id;\n}\n\nexport function pushNotification(type: string, message: string): void {\n game.socket.emit(\"module.\" + MODULENAME, { operation: \"notification\", args: [type, message] });\n}\n\nfunction unflatten(object: Record): Record {\n const result: Record = {};\n for (const key of Object.keys(object)) {\n setValue(result, key, object[key]);\n }\n return result;\n}\n\nfunction setValue(object: Record, path: string, value: unknown): void {\n const split = path.split(\".\");\n const top = split.pop();\n\n if (top !== undefined) {\n // @ts-expect-error TODO fix typing\n split.reduce(function (o, k, i, kk) {\n return (o[k] = o[k] || (isFinite(i + 1 in kk ? Number(kk[i + 1]) : Number(top)) ? [] : {}));\n }, object)[top] = value;\n }\n}\n\n/**\n * Applies patches to a housepatcher object.\n *\n * @param {string} housepatcher - The housepatcher object containing patches.\n * @return {Promise} A promise that resolves when the patches have been applied.\n */\nexport async function housepatcher(housepatcher: unknown): Promise {\n try {\n const patches = JSON.parse(decodeURI(String(housepatcher)));\n let count = 0;\n\n for (const { uuid, action, data } of patches) {\n const document = await fromUuid(uuid);\n if (document?.inCompendium) {\n // @ts-expect-error I think Document#get compendium is missing from the types\n const compendium: CompendiumCollection = document.compendium;\n\n if (action === \"update\") {\n const original: Record = document.toObject();\n const system = original?.system as Record | undefined;\n const traitsObj = system?.traits as Record | undefined;\n const traits = traitsObj?.value as string[] | undefined;\n\n const housepatchedTrait = \"xdy-pf2e-housepatched\";\n const cccPatchedTrait = \"pf2e-ccc-patched\";\n if (!(traits?.includes(cccPatchedTrait) || traits?.includes(housepatchedTrait))) {\n const update = unflatten(data) as Record;\n const updateSystem = (update.system ??= {}) as Record;\n const updateTraits = (updateSystem.traits ??= {}) as Record;\n const updateValue = (updateTraits.value ??= []) as string[];\n updateValue.push(housepatchedTrait);\n\n const merged = fu.mergeObject(original, update);\n await document.update(unflatten(merged));\n count += 1;\n }\n } else if (action === \"unlock\") {\n if (compendium.locked) {\n await compendium.configure({ locked: false });\n }\n } else if (action === \"lock\") {\n if (!compendium.locked) {\n await compendium.configure({ locked: true });\n }\n } else if (action === \"delete\") {\n await document.delete();\n await compendium.getIndex();\n }\n }\n }\n\n const message = game.i18n.format(`${MODULENAME}.SETTINGS.housepatcher.notification`, { count });\n ui.notifications.info(message);\n } catch {\n ui.notifications.error(game.i18n.format(`${MODULENAME}.SETTINGS.housepatcher.error`));\n game.settings.set(MODULENAME, \"housepatcher\", \"\");\n }\n}\n\nexport function minionsInCurrentScene(actor: ActorPF2e): ActorPF2e[] {\n return actor.isOfType(\"character\") ? game.scenes.current?.tokens\n ?.filter(() => !game.user.isGM)\n ?.filter((token) => token.canUserModify((game.user), \"update\"))\n ?.map((token) => token.actor)\n ?.filter((x) => x?.traits.has(\"minion\")) : [];\n}\n\nexport function getModuleFlag(\n doc: { getFlag?: (scope: string, key: string) => unknown } | null | undefined,\n flag: string,\n fallback: T,\n): T;\nexport function getModuleFlag(\n doc: { getFlag?: (scope: string, key: string) => unknown } | null | undefined,\n flag: string,\n): T | undefined;\nexport function getModuleFlag(\n doc: { getFlag?: (scope: string, key: string) => unknown } | null | undefined,\n flag: string,\n fallback?: T,\n): T | undefined {\n const raw = doc?.getFlag?.(MODULENAME, flag) as T | undefined;\n return raw !== undefined && raw !== null ? raw : fallback;\n}\n\n/**\n * Retrieves the list of party members that are characters\n *\n * @return {Array} The list of hero actors.\n */\nexport function heroes(): ActorPF2e[] {\n return (\n game.actors?.party?.members\n .filter((actor) => actor?.isOfType(\"character\"))\n .filter((actor) => !actor?.system.traits?.value.toString().includes(\"minion\"))\n .filter((actor) => !actor?.system.traits?.value.toString().includes(\"eidolon\")) || []\n );\n}\n\n// Functions copied from C:\\Users\\jk\\foundryvtt\\forks\\pf2e\\build\\lib\\foundry-utils.ts\n// Not sure why I can't use directly.\n\n/**\n * Check if a key is present in a given object in a type safe way\n *\n * @param obj The object to check\n * @param key The key to check\n */\nexport function objectHasKey(obj: O, key: unknown): key is keyof O {\n return (typeof key === \"string\" || typeof key === \"number\") && key in obj;\n}\n","import type { MenuTemplateData } from \"../../settings/menu.ts\";\nimport { getModuleSetting } from \"../../utils.ts\";\n\nfunction setFormGroupVisibility(html: HTMLElement, selector: string, visible: boolean) {\n const el = html.querySelector(selector)?.closest(\".form-group\");\n if (el) el.style.display = visible ? \"\" : \"none\";\n}\n\nexport function toggleMenuSettings(html: HTMLElement, settings: MenuTemplateData): void {\n for (const settingElement of settings.settings) {\n if (settingElement) {\n const settingName = settingElement.key;\n\n if (settingName !== `handleDyingRecoveryRollAllow` && settingName.startsWith(\"handleDyingRecoveryRoll\")) {\n const applyToggle = !(\n getModuleSetting(\"handleDyingRecoveryRollAllow\") === \"none\" ||\n (game.user?.isGM\n ? getModuleSetting(\"handleDyingRecoveryRollAllow\") === \"players\"\n : getModuleSetting(\"handleDyingRecoveryRollAllow\") === \"gm\")\n );\n setFormGroupVisibility(html, `input[name=\"${settingName}\"]`, applyToggle);\n }\n if (settingName !== `autoRollDamageAllow` && settingName.startsWith(`autoRollDamage`)) {\n const applyToggle = !(\n getModuleSetting(\"autoRollDamageAllow\") === \"none\" ||\n (game.user?.isGM\n ? getModuleSetting(\"autoRollDamageAllow\") === \"players\"\n : getModuleSetting(\"autoRollDamageAllow\") === \"gm\")\n );\n\n setFormGroupVisibility(html, `input[name=\"${settingName}\"]`, applyToggle);\n setFormGroupVisibility(html, `select[name=\"${settingName}\"]`, applyToggle);\n }\n }\n }\n\n const pingMode = getModuleSetting(\"canvasPointerPingMode\");\n const showSoundSettings = pingMode === \"sound\" || pingMode === \"visualAndSound\";\n setFormGroupVisibility(html, `[name=\"canvasPointerPingSound\"]`, showSoundSettings);\n setFormGroupVisibility(html, `[name=\"canvasPointerPingVolume\"]`, showSoundSettings);\n\n const pingModeSelect = html.querySelector(`[name=\"canvasPointerPingMode\"]`);\n if (pingModeSelect && !pingModeSelect.dataset.pingListenerAttached) {\n pingModeSelect.dataset.pingListenerAttached = \"true\";\n pingModeSelect.addEventListener(\"change\", () => {\n const mode = pingModeSelect.value;\n const showSettings = mode === \"sound\" || mode === \"visualAndSound\";\n setFormGroupVisibility(html, `[name=\"canvasPointerPingSound\"]`, showSettings);\n setFormGroupVisibility(html, `[name=\"canvasPointerPingVolume\"]`, showSettings);\n });\n }\n}\n","import { MODULENAME } from \"../constants.ts\";\nimport { SettingRegistration } from \"foundry/client/helpers/client-settings.mts\";\nimport { toggleMenuSettings } from \"../feature/settingsHandler/index.ts\";\nimport { getModuleSetting } from \"../utils.ts\";\n\nexport type PartialSettingsData = Omit;\n\ninterface SettingsTemplateData extends PartialSettingsData {\n key: string;\n value: unknown;\n}\n\n// Note, this type is not quite the same as MenuTemplateData from the pf2e settings menu\nexport interface MenuTemplateData {\n settings: SettingsTemplateData[];\n buttons: object[];\n}\n\n/**\n * @var {string} type The HTMLElement's type (e.g. \"input\" or \"select\"). Defaults to \"input\".\n * @var {string} falsy The falsy value. Useful for select-type elements. Defaults to false.\n * @var {string[]} list A list with the setting IDs that should be toggled when the setting is changed.\n */\nexport interface HideListTemplateData {\n [key: string]: {\n type?: string;\n falsy?: string | boolean;\n list?: string[];\n };\n}\n\n/** An adjusted copy of the settings menu from core pf2e meant for the module */\nexport class SettingsMenuPF2eWorkbench extends foundry.applications.api.HandlebarsApplicationMixin(\n foundry.applications.api.ApplicationV2,\n) {\n static readonly namespace: string;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n static override DEFAULT_OPTIONS: Record = {\n tag: \"form\",\n window: {\n contentClasses: [\"form\", \"xdy-pf2e-workbench\", \"settings-menu\", \"standard-form\"],\n resizable: true,\n },\n position: { width: 780, height: 680 },\n form: {\n handler: SettingsMenuPF2eWorkbench.formHandler,\n closeOnSubmit: true,\n },\n };\n static readonly hidelist: HideListTemplateData = {};\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n constructor(options?: any) {\n const cls = new.target as typeof SettingsMenuPF2eWorkbench;\n super(fu.mergeObject({ id: `${cls.namespace}-settings` }, options ?? {}));\n }\n\n static override get PARTS(): { content: { template: string }; footer: { template: string } } {\n return {\n content: { template: `modules/${MODULENAME}/templates/menu.hbs` },\n footer: { template: \"templates/generic/form-footer.hbs\" },\n };\n }\n\n /** Settings to be registered and also later referenced during user updates */\n protected static get settings(): Record {\n return {};\n }\n\n override get title(): string {\n return game.i18n.localize(`${MODULENAME}.SETTINGS.${this.namespace}.name`);\n }\n\n get namespace(): string {\n return (this.constructor as typeof SettingsMenuPF2eWorkbench).namespace;\n }\n\n static registerSettings(): void {\n const settings = this.settings;\n for (const setting of Object.keys(settings)) {\n const spreadElements = { ...settings[setting] };\n game.settings.register(MODULENAME, setting, {\n ...spreadElements,\n config: false,\n });\n }\n }\n\n static hideForm(form: HTMLElement | null | undefined, condition: boolean): void {\n if (form === null || form === undefined) {\n return;\n }\n form.style.display = !condition ? \"none\" : \"\";\n }\n\n static registerSettingsAndCreateMenu(icon: string, restricted = true): void {\n game.settings.registerMenu(MODULENAME, this.namespace, {\n name: `${MODULENAME}.SETTINGS.${this.namespace}.name`, // lgtm [js/mixed-static-instance-this-access]\n label: `${MODULENAME}.SETTINGS.${this.namespace}.label`, // lgtm [js/mixed-static-instance-this-access]\n hint: `${MODULENAME}.SETTINGS.${this.namespace}.hint`, // lgtm [js/mixed-static-instance-this-access]\n icon: icon,\n // @ts-expect-error TODO Fix typing\n type: this,\n restricted: restricted,\n });\n this.registerSettings();\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n static async formHandler(_event: Event, _form: HTMLFormElement, formData: any): Promise {\n const data = foundry.utils.expandObject(formData.object) as Record;\n for (const key of Object.keys(data)) {\n let datum = data[key];\n // \"null\" check is due to a previous bug that may have left invalid data in text fields\n if (datum === null || datum === \"null\") {\n datum = \"\";\n }\n // If statement handles bug in foundry\n if (![\"submit\", \"reset\"].includes(key)) {\n await game.settings.set(MODULENAME, key, datum);\n }\n }\n }\n\n // @ts-expect-error TODO Fix typing\n override async _prepareContext(_options?: object): Promise {\n const settings = (this.constructor as typeof SettingsMenuPF2eWorkbench).settings;\n const templateData: SettingsTemplateData[] = Object.entries(settings).map(([key, setting]) => {\n const value = getModuleSetting(key);\n const hasRange = setting.type === Number && setting.range;\n return {\n ...setting,\n key,\n value,\n isCheckbox: setting.type === Boolean,\n // @ts-expect-error filePicker is not typed in SettingRegistration\n isFilepicker: setting.type === String && setting.filePicker,\n isNumber: setting.type === Number && !hasRange,\n isRange: hasRange,\n isSelect: !!setting.choices,\n // @ts-expect-error filePicker is not typed in SettingRegistration\n isText: setting.type === String && !setting.filePicker,\n };\n });\n return {\n settings: templateData,\n buttons: [{ type: \"submit\", icon: \"fa-solid fa-save\", label: \"SETTINGS.Save\" }],\n };\n }\n\n override async _onRender(context: object, _options: object): Promise {\n toggleMenuSettings(this.element, context as unknown as MenuTemplateData);\n const hidelist = (this.constructor as typeof SettingsMenuPF2eWorkbench).hidelist as HideListTemplateData;\n Object.entries(hidelist).forEach(([k, v]) => {\n const setting = game.settings.get(\"xdy-pf2e-workbench\", k) !== (v.falsy ?? false);\n const settingCheckbox = this.element.querySelector(\n `.form-fields [name=\"${k}\"]`,\n );\n for (const form of v.list ?? []) {\n const settingForm = this.element.querySelector(\n `.form-group:has(.form-fields [name=\"${form}\"])`,\n );\n SettingsMenuPF2eWorkbench.hideForm(settingForm, setting);\n }\n settingCheckbox?.addEventListener(\"change\", (event) => {\n for (const form of v.list ?? []) {\n const settingForm = this.element.querySelector(\n `.form-group:has(.form-fields [name=\"${form}\"])`,\n );\n let condition = (event.target as HTMLInputElement).checked;\n switch (v.type) {\n case \"select\":\n condition = (event.target as HTMLSelectElement).value !== v.falsy;\n break;\n case \"input\":\n default:\n break;\n }\n SettingsMenuPF2eWorkbench.hideForm(settingForm, condition);\n }\n });\n });\n }\n}\n","import { updateHooks } from \"../xdy-pf2e-workbench.ts\";\nimport { MODULENAME } from \"../constants.ts\";\nimport { SettingsMenuPF2eWorkbench } from \"./menu.ts\";\nimport { SettingRegistration } from \"foundry/client/helpers/client-settings.mts\";\nimport { getModuleSetting } from \"../utils.ts\";\n\nexport let mystifyRandomPropertyType: string;\nexport let mystifyModifierKey: string;\n\nexport class WorkbenchNpcMystificationSettings extends SettingsMenuPF2eWorkbench {\n static override namespace = \"npcMystificationSettings\";\n\n public static override get settings(): Record {\n return {\n npcMystifier: {\n name: `${MODULENAME}.SETTINGS.npcMystifier.name`,\n hint: `${MODULENAME}.SETTINGS.npcMystifier.hint`,\n scope: \"world\",\n default: false,\n type: Boolean,\n onChange: () => updateHooks(),\n requiresReload: true,\n },\n npcMystifierDemystifyAllTokensBasedOnTheSameActor: {\n name: `${MODULENAME}.SETTINGS.npcMystifierDemystifyAllTokensBasedOnTheSameActor.name`,\n hint: `${MODULENAME}.SETTINGS.npcMystifierDemystifyAllTokensBasedOnTheSameActor.hint`,\n scope: \"world\",\n default: true,\n type: Boolean,\n },\n npcMystifierAddRandomProperty: {\n name: `${MODULENAME}.SETTINGS.npcMystifierAddRandomProperty.name`,\n hint: `${MODULENAME}.SETTINGS.npcMystifierAddRandomProperty.hint`,\n scope: \"world\",\n type: String,\n choices: {\n none: game.i18n.localize(`${MODULENAME}.SETTINGS.npcMystifierAddRandomProperty.none`),\n numberPostfix: game.i18n.localize(\n `${MODULENAME}.SETTINGS.npcMystifierAddRandomProperty.numberPostfix`,\n ),\n wordPrefix: game.i18n.localize(`${MODULENAME}.SETTINGS.npcMystifierAddRandomProperty.wordPrefix`),\n },\n default: \"none\",\n onChange: (key) => {\n mystifyRandomPropertyType = key;\n },\n },\n npcMystifierRandomWordPrefixRollTable: {\n name: `${MODULENAME}.SETTINGS.npcMystifierWordPrefix.name`,\n hint: `${MODULENAME}.SETTINGS.npcMystifierWordPrefix.hint`,\n scope: \"world\",\n default: \"\",\n type: String,\n },\n npcMystifierKeepRandomProperty: {\n name: `${MODULENAME}.SETTINGS.npcMystifierKeepRandomProperty.name`,\n hint: `${MODULENAME}.SETTINGS.npcMystifierKeepRandomProperty.hint`,\n scope: \"world\",\n default: true,\n type: Boolean,\n },\n npcMystifierRandomPropertySkipForUnique: {\n name: `${MODULENAME}.SETTINGS.npcMystifierRandomPropertySkipForUnique.name`,\n hint: `${MODULENAME}.SETTINGS.npcMystifierRandomPropertySkipForUnique.hint`,\n scope: \"world\",\n default: true,\n type: Boolean,\n },\n npcMystifierIncludeCreaturesOfThisRarityOrGreater: {\n name: `${MODULENAME}.SETTINGS.npcMystifierIncludeCreaturesOfThisRarityOrGreater.name`,\n hint: `${MODULENAME}.SETTINGS.npcMystifierIncludeCreaturesOfThisRarityOrGreater.hint`,\n scope: \"world\",\n default: \"common\",\n type: String,\n choices: {\n common: game.i18n.localize(\"PF2E.TraitCommon\"),\n uncommon: game.i18n.localize(\"PF2E.TraitUncommon\"),\n rare: game.i18n.localize(\"PF2E.TraitRare\"),\n unique: game.i18n.localize(\"PF2E.TraitUnique\"),\n },\n },\n npcMystifierIncludeCreaturesOfThisLevelOrGreater: {\n name: `${MODULENAME}.SETTINGS.npcMystifierIncludeCreaturesOfThisLevelOrGreater.name`,\n hint: `${MODULENAME}.SETTINGS.npcMystifierIncludeCreaturesOfThisLevelOrGreater.hint`,\n scope: \"world\",\n default: -1,\n type: Number,\n },\n npcMystifierIncludeCreaturesOfThisLevelOrGreaterUsingPartyLevel: {\n name: `${MODULENAME}.SETTINGS.npcMystifierIncludeCreaturesOfThisLevelOrGreaterUsingPartyLevel.name`,\n hint: `${MODULENAME}.SETTINGS.npcMystifierIncludeCreaturesOfThisLevelOrGreaterUsingPartyLevel.hint`,\n scope: \"world\",\n default: false,\n type: Boolean,\n },\n npcMystifierPrefix: {\n name: `${MODULENAME}.SETTINGS.npcMystifierPrefix.name`,\n hint: `${MODULENAME}.SETTINGS.npcMystifierPrefix.hint`,\n scope: \"world\",\n type: String,\n default: \"\",\n },\n npcMystifierPostfix: {\n name: `${MODULENAME}.SETTINGS.npcMystifierPostfix.name`,\n hint: `${MODULENAME}.SETTINGS.npcMystifierPostfix.hint`,\n scope: \"world\",\n type: String,\n default: \"Workbench Adjectives\",\n },\n npcMystifierUseSize: {\n name: `${MODULENAME}.SETTINGS.npcMystifierUseSize.name`,\n hint: `${MODULENAME}.SETTINGS.npcMystifierUseSize.hint`,\n scope: \"world\",\n default: true,\n type: Boolean,\n },\n npcMystifierUseRarities: {\n name: `${MODULENAME}.SETTINGS.npcMystifierUseRarities.name`,\n hint: `${MODULENAME}.SETTINGS.npcMystifierUseRarities.hint`,\n scope: \"world\",\n default: false,\n type: Boolean,\n },\n npcMystifierUseRaritiesReplacement: {\n name: `${MODULENAME}.SETTINGS.npcMystifierUseRaritiesReplacement.name`,\n hint: `${MODULENAME}.SETTINGS.npcMystifierUseRaritiesReplacement.hint`,\n scope: \"world\",\n default: \"\",\n type: String,\n },\n npcMystifierUseEliteWeak: {\n name: `${MODULENAME}.SETTINGS.npcMystifierUseEliteWeak.name`,\n hint: `${MODULENAME}.SETTINGS.npcMystifierUseEliteWeak.hint`,\n scope: \"world\",\n default: false,\n type: Boolean,\n },\n npcMystifierUseCreatureTypesTraits: {\n name: `${MODULENAME}.SETTINGS.npcMystifierUseCreatureTypesTraits.name`,\n hint: `${MODULENAME}.SETTINGS.npcMystifierUseCreatureTypesTraits.hint`,\n scope: \"world\",\n default: true,\n type: Boolean,\n },\n npcMystifierUseCreatureTraits: {\n name: `${MODULENAME}.SETTINGS.npcMystifierUseCreatureTraits.name`,\n hint: `${MODULENAME}.SETTINGS.npcMystifierUseCreatureTraits.hint`,\n scope: \"world\",\n default: false,\n type: Boolean,\n },\n npcMystifierUseOtherTraits: {\n name: `${MODULENAME}.SETTINGS.npcMystifierUseOtherTraits.name`,\n hint: `${MODULENAME}.SETTINGS.npcMystifierUseOtherTraits.hint`,\n scope: \"world\",\n default: false,\n type: Boolean,\n },\n npcMystifierBlacklist: {\n name: `${MODULENAME}.SETTINGS.npcMystifierBlacklist.name`,\n hint: `${MODULENAME}.SETTINGS.npcMystifierBlacklist.hint`,\n scope: \"world\",\n default: \"\",\n type: String,\n },\n npcMystifierNoMatch: {\n name: `${MODULENAME}.SETTINGS.npcMystifierNoMatch.name`,\n hint: `${MODULENAME}.SETTINGS.npcMystifierNoMatch.hint`,\n scope: \"world\",\n default: \"...\",\n type: String,\n onChange: async (choice) => {\n if (!choice) {\n // Sleep a bit, then set to a sane value...\n await new Promise((resolve) => setTimeout(resolve, 250));\n game.settings.set(MODULENAME, \"npcMystifierNoMatch\", \"...\");\n }\n },\n },\n npcMystifierModifierKey: {\n name: `${MODULENAME}.SETTINGS.npcMystifierModifierKey.name`,\n hint: `${MODULENAME}.SETTINGS.npcMystifierModifierKey.hint`,\n scope: \"world\",\n type: String,\n choices: {\n ALWAYS: game.i18n.localize(`${MODULENAME}.SETTINGS.npcMystifierModifierKey.always`),\n DISABLED: game.i18n.localize(`${MODULENAME}.SETTINGS.npcMystifierModifierKey.disabled`),\n ALT: game.i18n.localize(`${MODULENAME}.SETTINGS.npcMystifierModifierKey.alt`),\n CONTROL: game.i18n.localize(`${MODULENAME}.SETTINGS.npcMystifierModifierKey.control`),\n META: game.i18n.localize(`${MODULENAME}.SETTINGS.npcMystifierModifierKey.meta`),\n },\n default: \"CONTROL\",\n onChange: (key) => {\n mystifyModifierKey = key;\n },\n },\n npcMystifierDemystifyToOriginalTokenName: {\n name: `${MODULENAME}.SETTINGS.npcMystifierDemystifyToOriginalTokenName.name`,\n hint: `${MODULENAME}.SETTINGS.npcMystifierDemystifyToOriginalTokenName.hint`,\n scope: \"world\",\n type: Boolean,\n default: false,\n },\n npcMystifierExcludeActorTypes: {\n name: `${MODULENAME}.SETTINGS.npcMystifierExcludeActorTypes.name`,\n hint: `${MODULENAME}.SETTINGS.npcMystifierExcludeActorTypes.hint`,\n scope: \"world\",\n type: String,\n default: \"\",\n },\n npcMystifierIcon: {\n name: `${MODULENAME}.SETTINGS.npcMystifierIcon.name`,\n hint: `${MODULENAME}.SETTINGS.npcMystifierIcon.hint`,\n scope: \"world\",\n type: String,\n default: \"fa-solid fa-eye-slash\",\n },\n };\n }\n\n static override registerSettings(): void {\n super.registerSettings();\n mystifyModifierKey = getModuleSetting(\"npcMystifierModifierKey\");\n mystifyRandomPropertyType = getModuleSetting(\"npcMystifierAddRandomProperty\");\n }\n}\n","export const CREATURE_IDENTIFICATION_TRAITS: string[] = [\n \"aberration\",\n \"animal\",\n \"astral\",\n \"beast\",\n \"celestial\",\n \"construct\",\n \"dragon\",\n \"dream\",\n \"elemental\",\n \"ethereal\",\n \"fey\",\n \"fiend\",\n \"fungus\",\n \"humanoid\",\n \"monitor\",\n \"ooze\",\n \"plant\",\n \"shade\",\n \"spirit\",\n \"time\",\n \"undead\",\n];\n\nexport const ELITE_WEAK: string[] = [\"elite\", \"weak\"];\n","import { ActorPF2e, ScenePF2e, TokenDocumentPF2e } from \"foundry-pf2e\";\nimport { CREATURE_IDENTIFICATION_TRAITS, ELITE_WEAK } from \"../../xdy-pf2e-constants.ts\";\nimport { getModuleSetting } from \"../../utils.ts\";\nimport * as systems from \"../../utils/systems.ts\";\n\nlet TRAITS: {\n SIZES: string[];\n RARITIES: string[];\n PF2E_CREATURE_TRAITS: string[];\n CREATURE_IDENTIFICATION_TRAITS: string[];\n ELITE_WEAK: string[];\n};\n\nasync function fixesPreAndPost(settingkey: string): Promise {\n const fixSetting = getModuleSetting(settingkey).trim();\n\n // \"null\" check is due to a previous bug that may have left invalid data in text fields\n if (fixSetting !== null && fixSetting !== \"null\" && fixSetting !== \"\") {\n const table = game?.tables?.find((t) => t.name === fixSetting);\n if (!table) {\n const packId = systems.getModulePackId(\"xdy-internal-tables\");\n const pack = game.packs.get(packId);\n if (pack) {\n const index = await pack.getIndex();\n const id = index.find((e) => e.name.includes(fixSetting))?._id;\n if (id) {\n const document = await pack?.getDocument(id);\n const draw = await (document).draw({ displayChat: false });\n if (draw && draw?.results[0]) {\n // @ts-expect-error description works but not in the types it seems\n return draw?.results[0].description;\n }\n }\n }\n } else {\n const draw = await table?.draw({ displayChat: false });\n if (draw && draw?.results[0]) {\n // @ts-expect-error description works but not in the types it seems\n return draw?.results[0].description;\n }\n }\n return fixSetting;\n }\n return \"\";\n}\n\nfunction fillTraits() {\n TRAITS = {\n RARITIES: Object.keys(CONFIG.PF2E.rarityTraits),\n SIZES: Object.keys(CONFIG.PF2E.actorSizes),\n CREATURE_IDENTIFICATION_TRAITS: CREATURE_IDENTIFICATION_TRAITS,\n PF2E_CREATURE_TRAITS: Object.keys(CONFIG.PF2E.creatureTraits),\n ELITE_WEAK: ELITE_WEAK,\n };\n}\n\nfunction filterTraitList(traitsList: string[], prefix: string, postfix: string): string[] {\n if (getModuleSetting(\"npcMystifierBlacklist\")) {\n const blocklist = getModuleSetting(\"npcMystifierBlacklist\").toLocaleLowerCase().split(\",\") || null;\n if (blocklist) {\n traitsList = traitsList.filter((trait: string) => {\n return !blocklist.map((trait: string) => trait.trim()).includes(trait);\n });\n }\n }\n\n let size: string[] = [];\n if (getModuleSetting(\"npcMystifierUseSize\")) {\n size = traitsList.filter((trait: string) => TRAITS.SIZES.includes(trait));\n }\n\n let eliteWeak: string[] = [];\n if (getModuleSetting(\"npcMystifierUseEliteWeak\")) {\n eliteWeak = traitsList.filter((trait: string) => TRAITS.ELITE_WEAK.includes(trait));\n }\n\n let rarities: string[] = [];\n if (getModuleSetting(\"npcMystifierUseRarities\")) {\n rarities = traitsList.filter((trait: string) => TRAITS.RARITIES.includes(trait));\n const replacement: string = getModuleSetting(\"npcMystifierUseRaritiesReplacement\").toLocaleLowerCase();\n if (replacement !== \"\") {\n rarities = rarities.map((trait: string) => (trait !== \"common\" ? replacement : trait));\n }\n }\n\n let creatureIdentificationTraits: string[] = [];\n if (getModuleSetting(\"npcMystifierUseCreatureTypesTraits\")) {\n creatureIdentificationTraits = traitsList.filter((trait: string) =>\n TRAITS.CREATURE_IDENTIFICATION_TRAITS.includes(trait),\n );\n }\n\n let pf2eCreatureTraits: string[] = [];\n if (getModuleSetting(\"npcMystifierUseCreatureTraits\")) {\n pf2eCreatureTraits = traitsList.filter((trait: string) => TRAITS.PF2E_CREATURE_TRAITS.includes(trait));\n }\n\n let others: string[] = [];\n if (getModuleSetting(\"npcMystifierUseOtherTraits\")) {\n others = traitsList\n .filter((trait: string) => !TRAITS.ELITE_WEAK.includes(trait))\n .filter((trait: string) => !TRAITS.SIZES.includes(trait))\n .filter((trait: string) => !TRAITS.RARITIES.includes(trait))\n .filter((trait: string) => !TRAITS.CREATURE_IDENTIFICATION_TRAITS.includes(trait))\n .filter((trait: string) => !TRAITS.PF2E_CREATURE_TRAITS.includes(trait));\n }\n\n // Deduplicate using set\n return Array.from(\n new Set(\n [prefix]\n .concat(size)\n .concat(eliteWeak)\n .concat(rarities)\n .concat(others)\n .concat(creatureIdentificationTraits)\n .concat(pf2eCreatureTraits)\n .concat([postfix]),\n ).values(),\n );\n}\n\n/**\n * Generates a name from traits using the current mystification settings for a given token ID.\n *\n * @param {string} tokenId - The ID of the token.\n * @returns {Promise} A promise that resolves with the generated name from traits.\n */\nexport async function generateNameFromTraitsForToken(tokenId: string): Promise {\n const token = game.scenes?.current?.tokens?.get(tokenId);\n if (token) {\n return generateNameFromTraits(token as TokenDocumentPF2e);\n }\n return undefined;\n}\n\nexport async function generateNameFromTraits(token: TokenDocumentPF2e): Promise {\n let result = \"\";\n const traits = (token?.actor as ActorPF2e | null)?.system?.traits;\n if (!TRAITS) {\n fillTraits();\n }\n\n if (traits) {\n let traitsList = traits[\"value\"];\n if (traitsList) {\n const tokenRarities: string | undefined = traits.rarity;\n if (tokenRarities) {\n traitsList = traitsList.concat(tokenRarities);\n }\n\n const size = traits?.size?.value;\n if (size) {\n traitsList.push(size);\n }\n\n const actor: ActorPF2e | null = token.actor;\n const adjustment = (actor?.system?.attributes as unknown as Record)?.adjustment;\n if (adjustment) {\n traitsList.push(String(adjustment));\n }\n\n const prefix = (await fixesPreAndPost(\"npcMystifierPrefix\")) || \"\";\n const postfix = (await fixesPreAndPost(\"npcMystifierPostfix\")) || \"\";\n traitsList = filterTraitList(traitsList, prefix, postfix);\n\n result = traitsList\n .map((trait: string) => trait.trim())\n .filter((trait: string, index: number) => {\n return traitsList.indexOf(trait) === index;\n })\n .filter((trait) => trait.trim().length > 0)\n .map((trait: string) => {\n return trait?.charAt(0).toLocaleUpperCase() + trait?.slice(1);\n })\n .map((trait: string) => {\n const lowercaseTrait = trait.toLocaleLowerCase();\n if (TRAITS.ELITE_WEAK.includes(lowercaseTrait)) {\n switch (lowercaseTrait) {\n case TRAITS.ELITE_WEAK[0]:\n return game.i18n.localize(\"PF2E.NPC.Adjustment.EliteLabel\");\n case TRAITS.ELITE_WEAK[1]:\n return game.i18n.localize(\"PF2E.NPC.Adjustment.WeakLabel\");\n }\n } else if (TRAITS.SIZES.includes(lowercaseTrait)) {\n // @ts-expect-error actorSizes indexing not fully typed\n return game.i18n.localize(CONFIG.PF2E.actorSizes[lowercaseTrait]);\n }\n\n const translations: Record =\n (game.i18n.translations.PF2E as Record) ?? {};\n return (\n (trait !== prefix && trait !== postfix\n ? (translations[`Trait${trait}`] as string | undefined)\n : trait) ?? trait\n );\n })\n .join(\" \");\n }\n } else {\n // Shouldn't happen. But, just in case...\n result = getModuleSetting(\"npcMystifierNoMatch\");\n }\n return result;\n}\n","import { ActorSystemData, CreaturePF2e, ScenePF2e, TokenDocumentPF2e } from \"foundry-pf2e\";\nimport { MODULENAME } from \"../../constants.ts\";\nimport { mystifyModifierKey, mystifyRandomPropertyType } from \"../../settings/npc-mystification.ts\";\nimport { generateNameFromTraits } from \"./traits-name-generator.ts\";\nimport { getModuleFlag, getModuleSetting, heroes } from \"../../utils.ts\";\nimport { logError } from \"../../utils/logging.ts\";\nimport * as systems from \"../../utils/systems.ts\";\n\nfunction shouldSkipRandomProperty(token: TokenDocumentPF2e): boolean {\n return (\n getModuleSetting(\"npcMystifierRandomPropertySkipForUnique\") &&\n (token?.actor?.system)?.traits?.rarity === \"unique\"\n );\n}\n\nfunction hasRandomProperty(token: TokenDocumentPF2e): boolean {\n switch (mystifyRandomPropertyType) {\n case \"numberPostfix\":\n case \"wordPrefix\":\n return token.name.split(\" \").length !== (token.actor?.prototypeToken.name.split(\" \") ?? [\"\"]).length;\n default:\n return false;\n }\n}\n\nasync function fetchRandomWordPrefix(): Promise {\n const fixSetting = getModuleSetting(\"npcMystifierRandomWordPrefixRollTable\").trim();\n\n // \"null\" check is due to a previous bug that may have left invalid data in text fields\n if (fixSetting !== null && fixSetting !== \"null\" && fixSetting !== \"\") {\n const table = game?.tables?.find((t) => t.name === fixSetting);\n if (!table) {\n const packId = systems.getModulePackId(\"xdy-internal-tables\");\n const pack = game.packs.get(packId);\n if (pack) {\n const index = await pack.getIndex();\n const id = index.find((e) => e.name.includes(fixSetting))?._id;\n if (id) {\n const document = await pack?.getDocument(id);\n const draw = await (document).draw({ displayChat: false });\n if (draw && draw?.results[0]) {\n // @ts-expect-error description works but not in the types it seems\n return draw?.results[0].description;\n } else {\n return fixSetting;\n }\n }\n }\n }\n const draw = await table?.draw({ displayChat: false });\n if (draw && draw?.results[0]) {\n // @ts-expect-error description works but not in the types it seems\n return draw?.results[0].description;\n } else {\n return fixSetting;\n }\n }\n\n logError(`Rolltable for ${fixSetting} setting not defined or not found.`);\n\n return \"\";\n}\n\nexport async function buildTokenName(\n token: TokenDocumentPF2e,\n isMystified: boolean,\n useFullTraitName = true,\n): Promise {\n let tokenName = \"\";\n\n function getTokenName(): string {\n const useOriginalTokenName = getModuleSetting(\"npcMystifierDemystifyToOriginalTokenName\");\n if (useOriginalTokenName) {\n const originalTokenName = getModuleFlag(token, \"originalTokenName\", \"\");\n if (originalTokenName) {\n return originalTokenName ?? \"\";\n }\n }\n return token.actor?.prototypeToken.name ?? \"\";\n }\n\n if (token && token.actor) {\n tokenName = token.name;\n const keep = getModuleSetting(\"npcMystifierKeepRandomProperty\");\n if (isMystified) {\n if (keep && !shouldSkipRandomProperty(token)) {\n switch (mystifyRandomPropertyType) {\n case \"numberPostfix\":\n tokenName = `${getTokenName()} ${tokenName.match(/\\d+$/)?.[0] ?? \"\"}`.trim();\n break;\n case \"wordPrefix\":\n tokenName = `${(tokenName.match(/\\b([a-zA-Z0-9_-]+)\\b/) ?? [\"\"])[0]} ${getTokenName()}`.trim();\n break;\n default:\n tokenName = getTokenName();\n }\n } else {\n tokenName = getTokenName();\n }\n } else {\n // Store the original name before mystifying\n if (!getModuleFlag(token, \"originalTokenName\")) {\n await token.setFlag(MODULENAME, \"originalTokenName\", token.name);\n }\n\n if (useFullTraitName) {\n tokenName = await generateNameFromTraits(token);\n } else {\n tokenName = getTokenName();\n }\n\n if (hasRandomProperty(token) && keep && !shouldSkipRandomProperty(token)) {\n switch (mystifyRandomPropertyType) {\n case \"numberPostfix\":\n tokenName = `${tokenName} ${token.name.match(/\\d+$/)?.[0] ?? \"\"}`.trim();\n break;\n case \"wordPrefix\":\n tokenName = `${(token.name.match(/\\b([a-zA-Z0-9_-]+)\\b/) ?? [\"\"])[0]} ${tokenName}`.trim();\n break;\n default:\n tokenName = getTokenName();\n }\n } else {\n if (!shouldSkipRandomProperty(token)) {\n let rolled = 0;\n\n switch (mystifyRandomPropertyType) {\n case \"numberPostfix\":\n rolled = Math.floor(Math.random() * 100) + 1;\n // Retry once if the number is already used, can't be bothered to roll until unique or keep track of used numbers\n if (canvas?.scene?.tokens?.find((t) => t.name.endsWith(` ${rolled}`))) {\n rolled = Math.floor(Math.random() * 100) + 1;\n }\n tokenName += ` ${rolled}`;\n break;\n case \"wordPrefix\":\n tokenName = `${await fetchRandomWordPrefix()} ${tokenName}`.trim();\n break;\n }\n }\n }\n }\n }\n\n // Never return an empty string\n return tokenName === \"\" ? getModuleSetting(\"npcMystifierNoMatch\") : tokenName;\n}\n\nfunction isMystifyModifierKeyPressed() {\n const keyboardManager = foundry.helpers.interaction.KeyboardManager;\n switch (mystifyModifierKey) {\n case \"ALT\":\n return game.keyboard.isModifierActive(keyboardManager.MODIFIER_KEYS.ALT);\n case \"CONTROL\":\n return game.keyboard.isModifierActive(keyboardManager.MODIFIER_KEYS.CONTROL);\n case \"META\":\n return game.keyboard.downKeys.has(\"MetaLeft\") || game.keyboard.downKeys.has(\"MetaRight\");\n default:\n return false;\n }\n}\n\nexport async function tokenCreateMystification(token: any): Promise {\n const key = getModuleSetting(\"npcMystifierModifierKey\");\n if (\n game.user?.isGM &&\n token &&\n !token?.actor?.hasPlayerOwner &&\n key !== \"DISABLED\" &&\n (key === \"ALWAYS\" || isMystifyModifierKeyPressed()) &&\n (!game.keyboard?.downKeys.has(\"V\") || game.keyboard?.downKeys.has(\"Insert\"))\n ) {\n if (Hooks.call(`${MODULENAME}.tokenCreateMystification`, token)) {\n await doMystification(token, false);\n }\n }\n}\n\n// @ts-expect-error TODO fix\nexport function isTokenMystified(token): boolean {\n const tokenName = token?.name;\n const prototypeTokenName = token?.actor?.prototypeToken.name ?? \"\";\n\n // TODO This needs improving. Basically, look at the various mystification settings and figure out what's been added, only check the non-added bits.\n return (tokenName?.indexOf(prototypeTokenName) ?? -1) < 0;\n}\n\n/**\n * Takes a token ID and a boolean value to perform a mystification.\n *\n * @param {string} tokenId - The ID of the token.\n * @param {boolean} active - Whether the mystification should be active or not.\n * @return {Promise} A promise that resolves when the mystification is complete.\n */\nexport async function doMystificationFromToken(tokenId: string, active: boolean): Promise {\n const token = game.scenes?.current?.tokens?.get(tokenId);\n if (token) {\n return doMystification(token, active);\n }\n}\n\nfunction rarityIndex(rarity: string): number {\n const rarityKeys = Object.keys(CONFIG.PF2E.rarityTraits);\n const idx = rarityKeys.indexOf(rarity);\n return idx >= 0 ? idx : 0;\n}\n\nfunction shouldUseFullTraitName(token: TokenDocumentPF2e): boolean {\n const includeRarity = getModuleSetting(\"npcMystifierIncludeCreaturesOfThisRarityOrGreater\");\n const creatureRarity = (token.actor?.system)?.traits?.rarity ?? \"common\";\n const eligibleForRarity = rarityIndex(creatureRarity) >= rarityIndex(includeRarity);\n\n let includeLevel = Number(getModuleSetting(\"npcMystifierIncludeCreaturesOfThisLevelOrGreater\"));\n if (getModuleSetting(\"npcMystifierIncludeCreaturesOfThisLevelOrGreaterUsingPartyLevel\")) {\n includeLevel = game?.actors?.party?.level ?? includeLevel;\n }\n const eligibleForLevel = includeLevel === -1 || (token.actor as CreaturePF2e).level >= includeLevel;\n\n return eligibleForRarity && eligibleForLevel;\n}\n\nexport async function doMystification(token: TokenDocumentPF2e | undefined, active: boolean): Promise {\n if (!token?.actor || !canvas.scene) {\n return;\n }\n\n if (\"party\" === token.actor.type) {\n return;\n }\n\n if (heroes().includes(token.actor)) {\n return;\n }\n\n if (\n getModuleSetting(\"npcMystifierExcludeActorTypes\")\n .split(\",\")\n .map((t) => t.trim())\n .includes(token.actor?.type)\n ) {\n return;\n }\n\n const useFullTraitName = shouldUseFullTraitName(token);\n\n const updates = [\n {\n _id: token.id,\n name: await buildTokenName(token, active, useFullTraitName),\n },\n ];\n\n const allOfActor = getModuleSetting(\"npcMystifierDemystifyAllTokensBasedOnTheSameActor\");\n if (active && game.user?.isGM && isTokenMystified(token) && allOfActor) {\n for (const t of canvas.scene.tokens) {\n if (t.id !== token.id && t.actor?.id === token.actor.id && isTokenMystified(t)) {\n updates.push({\n _id: t.id,\n name: await buildTokenName(t, active, useFullTraitName),\n });\n }\n }\n }\n await canvas.scene.updateEmbeddedDocuments(\"Token\", updates, { render: true });\n renameCombatants(token);\n}\n\nfunction renameCombatants(token: TokenDocumentPF2e): void {\n for (const combat of game.combats) {\n const ids = combat.combatants.filter((c) => c.actor?.id === token.actor?.id).map((c) => ({ _id: c.id }));\n if (ids.length > 0) {\n combat.updateEmbeddedDocuments(\"Combatant\", ids, { diff: false, render: true });\n }\n }\n}\n\nexport function renderNameHud(app: { object?: unknown }, html: HTMLElement): void {\n const tokenId =\n (app?.object as { id?: string })?.id ?? (app?.object as { document?: { id?: string } })?.document?.id;\n if (!tokenId || !canvas?.tokens) return;\n const token = canvas.tokens.get(tokenId);\n if (!token) return;\n\n const mystified = isTokenMystified(token);\n if (!canMystify() || token?.actor?.hasPlayerOwner) return;\n\n const toggle = createMystifyToggle(mystified, tokenId);\n const column = html.querySelector(\"div.col.left\");\n if (column) {\n column.appendChild(toggle);\n }\n}\n\nfunction createMystifyToggle(mystified: boolean, tokenId: string): HTMLDivElement {\n const title = mystified ? \"Unmystify\" : \"Mystify\";\n const toggle = document.createElement(\"div\");\n toggle.className = `control-icon toggle ${mystified ? \"active\" : \"\"}`;\n toggle.setAttribute(\"data-action\", \"mystify\");\n\n const icon = document.createElement(\"i\");\n icon.className = getModuleSetting(\"npcMystifierIcon\");\n icon.title = title;\n toggle.appendChild(icon);\n\n toggle.addEventListener(\"click\", createMystifyClickHandler(tokenId));\n return toggle;\n}\n\nfunction createMystifyClickHandler(tokenId: string): (e: MouseEvent) => Promise {\n return async (e: MouseEvent) => {\n const hudElement = e.currentTarget as HTMLElement;\n const active = hudElement.classList.contains(\"active\");\n const updatedToken = canvas?.tokens?.get(tokenId) ?? null;\n if (updatedToken && isTokenMystified(updatedToken) === active) {\n await doMystification(updatedToken.document, isTokenMystified(updatedToken));\n }\n hudElement.classList.toggle(\"active\");\n };\n}\n\nexport function canMystify(): any {\n return game.user?.isGM && canvas && canvas.tokens;\n}\n","// These usecases should be handled\n// * Show a new handle r, set timeout to 60, ignore on the first, none on the second\n// * Check on an existing timer, recalc timeout, ignore on the first, none on the second\n// * Timeout, recalc timeout, ignore on the first, random on the second\n\nimport type { ActorPF2e } from \"foundry-pf2e\";\nimport { MODULENAME } from \"../../constants.ts\";\nimport {\n fireAndForget,\n getModuleFlag,\n getModuleSetting,\n getModuleSettingAsNumber,\n heroes,\n pushNotification,\n} from \"../../utils.ts\";\nimport { logDebug } from \"../../utils/logging.ts\";\n\nexport enum HPHState {\n Start,\n Check,\n Timeout,\n}\n\nconst ONE_MINUTE_IN_MS = 60 * 1000;\nlet isHeroPointHandlerDialogOpen = false;\n\ntype HeroPointHandlerButton = \"timer\" | \"noTimer\";\ntype HeroPointRecipient = \"ALL\" | \"NONE\" | string;\n\ntype HeroPointHandlerResult = {\n button: HeroPointHandlerButton;\n remainingMinutes: number;\n reason: string;\n};\n\ntype HeroPointHandlerTemplateActor = {\n id: string;\n name: string;\n radioId: string;\n checked: boolean;\n};\n\ntype HeroPointHandlerTemplateData = {\n instructions: string;\n doWhat: string;\n resetTo: string;\n addLabel: string;\n ignore: string;\n thisMany: string;\n addOne: string;\n reasonLabel: string;\n reasonPlaceholder: string;\n actors: HeroPointHandlerTemplateActor[];\n timerValue: string;\n timerMinutes: number;\n maxMinutes: number;\n showAfter: string;\n submitShortLabel: string;\n stopShortLabel: string;\n};\n\nfunction getHeroPointHandlerTemplatePath(): string {\n return `modules/${MODULENAME}/templates/feature/heropoint-handler/index.hbs`;\n}\n\nasync function stopTimer(): Promise {\n await game.user?.unsetFlag(MODULENAME, \"heroPointHandler.startTime\");\n await game.user?.unsetFlag(MODULENAME, \"heroPointHandler.remainingMinutes\");\n await game.user?.unsetFlag(MODULENAME, \"heroPointHandler.timeout\");\n}\n\nexport async function startTimer(remainingMinutes: number): Promise {\n const oldTimeout = getModuleFlag(game.user, \"heroPointHandler.timeout\");\n if (oldTimeout) {\n clearTimeout(oldTimeout);\n }\n if (remainingMinutes > 0) {\n const ms = remainingMinutes * ONE_MINUTE_IN_MS;\n const timeout = setTimeout(async () => {\n await heroPointHandler(HPHState.Timeout);\n }, ms);\n\n const updateData = {\n flags: {\n \"xdy-pf2e-workbench\": {\n heroPointHandler: {\n startTime: game.time.serverTime,\n remainingMinutes: remainingMinutes,\n timeout: timeout,\n },\n },\n },\n };\n await game.user?.update(updateData);\n } else if (!remainingMinutes || remainingMinutes <= 0) {\n await stopTimer();\n }\n}\n\n/**\n * Calls the heroPointHandler function with the HPHState.Timeout parameter.\n *\n * @return {Promise} The result of the heroPointHandler function.\n */\nexport async function callHeroPointHandler(): Promise {\n return heroPointHandler(HPHState.Timeout);\n}\n\nexport function createRemainingTimeMessage(remainingMinutes: number): void {\n const message =\n remainingMinutes > 0\n ? game.i18n.format(`${MODULENAME}.SETTINGS.heroPointHandler.willBeResetIn`, {\n remainingMinutes: remainingMinutes,\n time: new Date(Date.now() + remainingMinutes * ONE_MINUTE_IN_MS).toLocaleTimeString([], {\n hour: \"2-digit\",\n minute: \"2-digit\",\n }),\n })\n : game.i18n.localize(`${MODULENAME}.SETTINGS.heroPointHandler.timerStopped`);\n sendMessage(message, [game.user.id]);\n}\n\nfunction buildDialogButtons() {\n return [\n {\n action: \"timer\",\n label: game.i18n.localize(`${MODULENAME}.SETTINGS.heroPointHandler.submitShortLabel`),\n default: true,\n callback: async (_event: PointerEvent | SubmitEvent, button: HTMLButtonElement, _dialog: unknown) => {\n const response = handleDialogResponse(button.form ?? button.closest(\"form\"));\n return {\n button: \"timer\",\n remainingMinutes: response.remainingMinutes,\n reason: response.reason,\n };\n },\n },\n {\n action: \"noTimer\",\n label: game.i18n.localize(`${MODULENAME}.SETTINGS.heroPointHandler.stopShortLabel`),\n callback: async (_event: PointerEvent | SubmitEvent, button: HTMLButtonElement, _dialog: unknown) => {\n handleDialogResponse(button.form ?? button.closest(\"form\"));\n return {\n button: \"noTimer\",\n remainingMinutes: 0,\n reason: \"\",\n };\n },\n },\n ];\n}\n\nexport async function heroPointHandler(state: HPHState): Promise {\n if (isHeroPointHandlerDialogOpen) {\n return;\n }\n\n isHeroPointHandlerDialogOpen = true;\n\n try {\n let remainingMinutes: number;\n switch (state) {\n case HPHState.Start:\n remainingMinutes = getModuleSettingAsNumber(\"heroPointHandlerDefaultTimeoutMinutes\");\n break;\n case HPHState.Check:\n remainingMinutes = calcRemainingMinutes(true);\n break;\n case HPHState.Timeout:\n remainingMinutes = getModuleSettingAsNumber(\"heroPointHandlerDefaultTimeoutMinutes\");\n break;\n }\n\n const title = `${game.i18n.localize(`${MODULENAME}.SETTINGS.heroPointHandler.title`)} (${\n remainingMinutes\n ? remainingMinutes + \" \" + game.i18n.localize(`${MODULENAME}.SETTINGS.heroPointHandler.minutesLeft`)\n : game.i18n.localize(`${MODULENAME}.SETTINGS.heroPointHandler.noRunningTimer`)\n })`;\n\n const content = await buildHtml(remainingMinutes, state);\n\n const submitTooltip = game.i18n.localize(`${MODULENAME}.SETTINGS.heroPointHandler.startTimerLabel`);\n const stopTooltip = game.i18n.localize(`${MODULENAME}.SETTINGS.heroPointHandler.noTimerLabel`);\n const dialogWidth = 375;\n\n const renderHookId = Hooks.on(\"renderDialogV2\", (app: foundry.applications.api.DialogV2) => {\n if (!app.options.window.contentClasses?.includes(\"hero-point-handler-window\")) {\n return;\n }\n Hooks.off(\"renderDialogV2\", renderHookId);\n\n const el: HTMLElement = app.element;\n const top = Math.round((window.innerHeight - el.offsetHeight) / 2);\n el.style.top = `${top}px`;\n app.position.top = top;\n el.style.left = `${Math.round((window.innerWidth - dialogWidth) / 2)}px`;\n el.style.width = `${dialogWidth}px`;\n\n const titleEl = el.querySelector(\".window-title\");\n if (titleEl) {\n titleEl.innerHTML = title;\n }\n\n const footerButtons = el.querySelectorAll(\"footer button[data-action]\");\n for (const footerButton of footerButtons) {\n switch (footerButton.dataset.action) {\n case \"timer\":\n footerButton.title = submitTooltip;\n footerButton.setAttribute(\"aria-label\", submitTooltip);\n break;\n case \"noTimer\":\n footerButton.title = stopTooltip;\n footerButton.setAttribute(\"aria-label\", stopTooltip);\n break;\n }\n }\n });\n\n const result = await foundry.applications.api.DialogV2.wait({\n position: {\n left: Math.round((window.innerWidth - dialogWidth) / 2),\n width: dialogWidth,\n height: \"auto\",\n },\n window: {\n title,\n resizable: true,\n positioned: true,\n contentClasses: [\"hero-point-handler-window\"],\n icon: \"fa-solid fa-hourglass\",\n },\n content,\n buttons: buildDialogButtons(),\n close: () => {\n Hooks.off(\"renderDialogV2\", renderHookId);\n },\n });\n\n if (!result) {\n return;\n }\n\n switch (result.button) {\n case \"timer\":\n await startTimer(result.remainingMinutes);\n break;\n case \"noTimer\":\n await stopTimer();\n break;\n }\n\n createRemainingTimeMessage(result.remainingMinutes);\n } finally {\n isHeroPointHandlerDialogOpen = false;\n }\n}\n\n// Constants\nconst PARTY_MEMBERS_FLAG_KEY = \"partymembersThatHaveGottenHeropoints\";\n\n/**\n * Selects a random party member index from the provided list of actors,\n * ensuring the same actor is not repeatedly selected until all have been selected.\n *\n * @param {ActorPF2e[]} actors - The list of party members to select from.\n * @return {Promise} The index of the selected actor in the input array, or -1 if the input array is empty.\n */\nasync function randomPartymemberThatHasNotReceivedAHeropoint(actors: ActorPF2e[]): Promise {\n if (actors.length === 0) {\n await game.actors?.party?.unsetFlag(MODULENAME, PARTY_MEMBERS_FLAG_KEY);\n return -1;\n }\n\n const existingFlagValue = getModuleFlag(game.actors?.party, PARTY_MEMBERS_FLAG_KEY, \"\");\n logDebug(\"Hero point handler existing party flag value\", existingFlagValue);\n const hasReceivedHP: Set = existingFlagValue ? new Set(existingFlagValue.split(\",\")) : new Set();\n const noHPYet = actors.filter((actor) => !hasReceivedHP.has(actor.id));\n\n if (noHPYet.length === 0) {\n hasReceivedHP.clear();\n noHPYet.push(...actors);\n }\n const randomIndex: number = Math.floor(Math.random() * noHPYet.length);\n const selectedActorId = noHPYet[randomIndex]?.id ?? \"\";\n hasReceivedHP.add(selectedActorId);\n await game.actors?.party?.setFlag(MODULENAME, PARTY_MEMBERS_FLAG_KEY, [...hasReceivedHP].join(\",\"));\n\n return actors.findIndex((actor) => actor.id === selectedActorId);\n}\n\nasync function buildHtml(remainingMinutes: number, state: HPHState): Promise {\n const actors = heroes();\n const checkedSet = new Set();\n switch (state) {\n case HPHState.Start:\n break;\n case HPHState.Timeout: {\n let selectedActor = -1;\n switch (getModuleSetting(\"heropointHandlerRandomization\")) {\n case \"none\":\n break;\n case \"random\":\n selectedActor = Math.floor(Math.random() * actors.length);\n break;\n case \"randomPartymemberThatHasNotReceivedAHeropoint\":\n selectedActor = await randomPartymemberThatHasNotReceivedAHeropoint(actors);\n }\n if (actors.length > 0 && selectedActor >= 0) {\n checkedSet.add(selectedActor);\n }\n break;\n }\n case HPHState.Check:\n break;\n }\n\n const maxMinutes = getModuleSettingAsNumber(\"heroPointHandlerDefaultTimeoutMinutes\");\n const templateData: HeroPointHandlerTemplateData = {\n instructions: game.i18n.localize(`${MODULENAME}.SETTINGS.heroPointHandler.instructions`),\n doWhat: game.i18n.localize(`${MODULENAME}.SETTINGS.heroPointHandler.doWhat`),\n resetTo: game.i18n.localize(`${MODULENAME}.SETTINGS.heroPointHandler.resetTo`),\n addLabel: game.i18n.localize(`${MODULENAME}.SETTINGS.heroPointHandler.add`),\n ignore: game.i18n.localize(`${MODULENAME}.SETTINGS.heroPointHandler.ignore`),\n thisMany: game.i18n.localize(`${MODULENAME}.SETTINGS.heroPointHandler.thisMany`),\n addOne: game.i18n.localize(`${MODULENAME}.SETTINGS.heroPointHandler.addOne`),\n actors: actors.map((actor, index) => {\n const currentHeroPoints = actor?.isOfType(\"character\") ? actor.system.resources.heroPoints.value : 0;\n const maxHeroPoints = actor?.isOfType(\"character\") ? actor.system.resources.heroPoints.max : 3;\n const ownerName =\n game.users?.find((u) => !u.isGM && actor?.ownership[u.id] === CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER)\n ?.name ?? \"\";\n const ownerSuffix = ownerName ? ` (${ownerName})` : \"\";\n return {\n id: actor.id,\n name: `${actor.name}${ownerSuffix} [${currentHeroPoints}/${maxHeroPoints}]`,\n radioId: `characters-${index}`,\n checked: checkedSet.has(index),\n };\n }),\n timerValue: game.i18n.format(`${MODULENAME}.SETTINGS.heroPointHandler.timerValue`, {\n maxMinutes,\n }),\n timerMinutes: remainingMinutes || maxMinutes,\n maxMinutes,\n reasonLabel: game.i18n.localize(`${MODULENAME}.SETTINGS.heroPointHandler.reasonLabel`),\n reasonPlaceholder: game.i18n.localize(`${MODULENAME}.SETTINGS.heroPointHandler.reasonPlaceholder`),\n showAfter: game.i18n.localize(`${MODULENAME}.SETTINGS.heroPointHandler.showAfter`),\n submitShortLabel: game.i18n.localize(`${MODULENAME}.SETTINGS.heroPointHandler.submitShortLabel`),\n stopShortLabel: game.i18n.localize(`${MODULENAME}.SETTINGS.heroPointHandler.stopShortLabel`),\n };\n\n return foundry.applications.handlebars.renderTemplate(getHeroPointHandlerTemplatePath(), templateData);\n}\n\nexport function calcRemainingMinutes(useDefault: boolean): number {\n const savedTime = getModuleFlag(game.user, \"heroPointHandler.startTime\");\n const savedMinutes = getModuleFlag(game.user, \"heroPointHandler.remainingMinutes\");\n const defaultMinutes = getModuleSettingAsNumber(\"heroPointHandlerDefaultTimeoutMinutes\");\n const remainingMinutes = Math.clamp(savedMinutes ?? (useDefault ? defaultMinutes : 0), 0, defaultMinutes);\n const passedMillis = game.time.serverTime - (savedTime ?? game.time.serverTime);\n return remainingMinutes - Math.floor(passedMillis / ONE_MINUTE_IN_MS);\n}\n\n/**\n * Resets the hero points for all heroes in the game.\n *\n * @param {number} heropoints - The number of hero points to set for each hero.\n * @return {Promise} - A promise that resolves when all hero points have been updated.\n */\nexport async function resetHeroPoints(heropoints: number): Promise {\n for (const actor of heroes()) {\n if (!actor.isOfType(\"character\")) {\n continue;\n }\n\n await actor.update({\n \"system.resources.heroPoints.value\": Math.min(heropoints, actor.system.resources.heroPoints.max),\n });\n }\n}\n\n/**\n * Adds hero points to the specified actor or all actors.\n *\n * @param {number} heropoints - The number of hero points to add.\n * @param {any} [actorId=\"ALL\"] - The ID of the actor to add hero points to. If \"ALL\" is specified, hero points will be added to all actors.\n * @return {Promise} - A promise that resolves when the hero points have been added.\n */\nexport async function addHeroPoints(heropoints: number, actorId: HeroPointRecipient = \"ALL\"): Promise {\n let actors: ActorPF2e[];\n switch (actorId) {\n case \"ALL\":\n actors = heroes();\n break;\n case \"NONE\":\n actors = [];\n break;\n default:\n actors = game.actors?.has(actorId) ? [game.actors.get(actorId, { strict: true })] : [];\n break;\n }\n\n for (const actor of actors) {\n if (!actor.isOfType(\"character\")) {\n continue;\n }\n\n const system = actor.system;\n const value = Math.min(system.resources.heroPoints.value + heropoints, actor.system.resources.heroPoints.max);\n await actor.update({\n \"system.resources.heroPoints.value\": value,\n });\n }\n}\n\nfunction addOneToSelectedCharactersIfAny(actorIds: string[], reason: string = \"\"): void {\n for (const actorId of actorIds) {\n addHeroPoints(1, actorId).then(() => {\n const name = game?.actors?.find((actor) => actor.id === actorId)?.name;\n if (name) {\n let message = game.i18n.format(`${MODULENAME}.SETTINGS.heroPointHandler.addedFor`, {\n name: name,\n });\n if (reason) {\n message += ` (${reason})`;\n }\n sendMessage(message);\n if (getModuleSetting(\"heropointHandlerNotification\")) {\n pushNotification(\"info\", message);\n }\n }\n });\n }\n}\n\nfunction sendMessage(message: string, whisper: string[] | undefined = undefined) {\n if (getModuleSetting(\"heropointHandlerNotificationChat\")) {\n fireAndForget(ChatMessage.create({ flavor: message, whisper }), \"heropointhandler#sendMessage\");\n } else {\n ui.notifications.info(message);\n }\n}\n\nfunction handleDialogResponse(element: ParentNode | null): { remainingMinutes: number; reason: string } {\n if (!element) {\n return { remainingMinutes: 0, reason: \"\" };\n }\n\n const sessionStartEl = element.querySelector('input[name=\"sessionStart\"]:checked');\n const sessionStart = sessionStartEl ? sessionStartEl.value : \"IGNORE\";\n\n const heroPointsEl = element.querySelector('input[name=\"heropoints\"]');\n const heroPoints = heroPointsEl ? Number.parseInt(heroPointsEl.value) : 1;\n\n const reasonEl = element.querySelector('input[name=\"reason\"]');\n const reason = reasonEl ? reasonEl.value : \"\";\n\n const actorIdEls = element.querySelectorAll('input[name=\"characters\"]:checked');\n const actorIds: string[] = Array.from(actorIdEls).map((el) => el.value);\n\n const remainingMinutesEl = element.querySelector('input[name=\"timerText\"]');\n const maxMinutes = getModuleSettingAsNumber(\"heroPointHandlerDefaultTimeoutMinutes\");\n const remainingMinutes = Math.clamp(\n remainingMinutesEl ? Number.parseInt(remainingMinutesEl.value) || 0 : 0,\n 0,\n maxMinutes,\n );\n\n if (sessionStart === \"RESET\") {\n resetHeroPoints(heroPoints).then(() => {\n const message = game.i18n.format(`${MODULENAME}.SETTINGS.heroPointHandler.resetToForAll`, {\n heroPoints: heroPoints,\n });\n sendMessage(message);\n addOneToSelectedCharactersIfAny(actorIds, reason);\n });\n } else if (sessionStart === \"ADD\") {\n addHeroPoints(heroPoints).then(() => {\n const message = game.i18n.format(`${MODULENAME}.SETTINGS.heroPointHandler.addedToForAll`, {\n heroPoints: heroPoints,\n });\n\n sendMessage(message);\n addOneToSelectedCharactersIfAny(actorIds, reason);\n });\n } else if (sessionStart === \"IGNORE\") {\n addOneToSelectedCharactersIfAny(actorIds, reason);\n }\n\n return { remainingMinutes, reason };\n}\n","import { ActorPF2e } from \"foundry-pf2e\";\nimport { fireAndForget, shouldIHandleThis } from \"../../utils.ts\";\n\n/**\n * Moves the selected combatant ahead of the current combatant.\n *\n * @param {type} selectedCombatantId - The ID of the selected combatant.\n * @return {Promise} A promise that resolves when the selected combatant has been moved.\n */\nexport async function moveSelectedAheadOfCurrent(selectedCombatantId: string): Promise {\n // TODO Ugly hack, might want to do a PR to expose the code in encounter-tracker#setInitiativeFromDrop?\n // TODO Handle moving several tokens at once? For now, just take the first selected token.\n const combat = game?.combat;\n if (combat && selectedCombatantId && selectedCombatantId !== combat?.combatant?.id) {\n const previous = combat?.combatants\n .map((c) => ({\n initiative: c.initiative || 0,\n }))\n .sort((a, b) => a.initiative - b.initiative)\n .find((c) => {\n return c.initiative > combat?.combatant?.initiative;\n })?.initiative;\n const current = combat?.combatant?.initiative;\n const initiative = !previous || previous < current ? current + 2 : ((previous + current) / 2) || 0;\n await combat?.setInitiative(selectedCombatantId, initiative);\n }\n}\n\nexport function moveOnZeroHP(actor: ActorPF2e): void {\n const combatant = game.combat?.getCombatantByToken(\n actor.isToken\n ? actor.token?.id\n : canvas?.scene?.tokens?.find((t) => t.actor?.id === actor.id)?.id,\n );\n if (shouldIHandleThis(actor) && combatant && combatant.id !== game.combat?.combatant?.id) {\n fireAndForget(moveSelectedAheadOfCurrent(combatant.id), \"moveSelectedAheadOfCurrent\");\n }\n}\n","export const OP_SYNC = \"canvasPointerSync\" as const;\nexport const OP_STOP = \"canvasPointerStop\" as const;\nexport const OP_PING = \"canvasPointerPing\" as const;\n\nexport interface PointerSyncPayload {\n operation: typeof OP_SYNC;\n userId: string;\n wx: number;\n wy: number;\n iconClass: string;\n color: string;\n}\n\nexport interface PointerStopPayload {\n operation: typeof OP_STOP;\n userId: string;\n}\n\nexport interface PointerPingPayload {\n operation: typeof OP_PING;\n userId: string;\n wx: number;\n wy: number;\n soundSrc: string;\n volume: number;\n}\n\nexport type PointerPayload = PointerSyncPayload | PointerStopPayload | PointerPingPayload;\n\nexport const REMOTE_CLASS = \"xdy-pf2e-workbench-pointer-remote\";\nexport const DEFAULT_POINTER_COLOR = \"#ffffff\";\nexport const DEFAULT_POINTER_ICON = \"fa-regular fa-hand-point-down\";\n\nexport const SOCKET_NAME = `module.xdy-pf2e-workbench`;\n","import type { PointerPingPayload, PointerStopPayload, PointerSyncPayload } from \"./constants.ts\";\nimport { OP_PING, OP_STOP, OP_SYNC, REMOTE_CLASS, SOCKET_NAME } from \"./constants.ts\";\n\nexport function worldToScreen(wx: number, wy: number): { screenX: number; screenY: number } {\n if (!canvas?.ready) return { screenX: 0, screenY: 0 };\n const { x, y } = canvas.stage.worldTransform.apply({ x: wx, y: wy });\n return { screenX: x, screenY: y };\n}\n\nexport function sendPosition(iconClass: string, userColor: string): void {\n if (!canvas?.ready) return;\n const mp = canvas.mousePosition;\n const payload = {\n operation: OP_SYNC,\n userId: game.user?.id,\n wx: Math.round(mp.x),\n wy: Math.round(mp.y),\n iconClass,\n color: userColor,\n } satisfies PointerSyncPayload;\n game.socket.emit(SOCKET_NAME, payload);\n}\n\nexport function sendPing(soundSrc: string, volume: number): void {\n if (!canvas?.ready) return;\n const mp = canvas.mousePosition;\n game.socket.emit(SOCKET_NAME, {\n operation: OP_PING,\n userId: game.user?.id,\n wx: Math.round(mp.x),\n wy: Math.round(mp.y),\n soundSrc,\n volume,\n } satisfies PointerPingPayload);\n}\n\nexport function sendStop(userId: string): void {\n game.socket.emit(SOCKET_NAME, {\n operation: OP_STOP,\n userId,\n } satisfies PointerStopPayload);\n}\n\nexport function getOrCreateRemoteElement(remotes: Map, userId: string): HTMLElement {\n let el = remotes.get(userId);\n if (!el) {\n el = document.createElement(\"i\");\n el.classList.add(REMOTE_CLASS);\n el.setAttribute(\"aria-hidden\", \"true\");\n document.body.appendChild(el);\n remotes.set(userId, el);\n }\n return el;\n}\n\nexport function updateRemoteElement(el: HTMLElement, iconClass: string, color: string): void {\n el.className = `${REMOTE_CLASS} ${iconClass}`;\n el.style.color = color;\n}\n\nexport function removeRemoteElement(remotes: Map, userId: string): void {\n const el = remotes.get(userId);\n if (el) {\n el.remove();\n remotes.delete(userId);\n }\n}\n","import { getModuleSetting } from \"../../utils.ts\";\nimport type { PointerPayload, PointerPingPayload, PointerSyncPayload } from \"./constants.ts\";\nimport { DEFAULT_POINTER_COLOR, OP_PING, OP_SYNC, SOCKET_NAME } from \"./constants.ts\";\nimport {\n getOrCreateRemoteElement,\n removeRemoteElement,\n sendPing,\n sendPosition,\n sendStop,\n updateRemoteElement,\n worldToScreen,\n} from \"./network.ts\";\n\nlet initialized = false;\nlet active = false;\nlet overlay: HTMLElement | null = null;\nlet iconClass: string = \"\";\nlet userColor: string = \"\";\nlet broadcastTimer: string | number | NodeJS.Timeout | null | undefined = null;\n\nconst remotes = new Map();\n\nexport function initCanvasPointer(): void {\n if (initialized) return;\n initialized = true;\n\n game.socket.on(SOCKET_NAME, (payload: PointerPayload) => {\n if (payload.operation === OP_SYNC) {\n handleRemoteSync(payload);\n } else if (payload.operation === OP_PING) {\n handleRemotePing(payload);\n } else {\n handleRemoteStop(payload);\n }\n });\n\n Hooks.on(\"userConnected\", onUserConnected);\n}\n\nexport function activateCanvasPointer(faIconClass: string): boolean {\n if (active) return false;\n if (!canvas?.ready) return false;\n\n active = true;\n iconClass = faIconClass;\n userColor = game.user?.color?.css ?? DEFAULT_POINTER_COLOR;\n\n setupLocalOverlay();\n startBroadcast();\n\n document.body.classList.add(\"xdy-pf2e-workbench-pointer-active\");\n document.addEventListener(\"mousemove\", onMouseMove, { passive: true });\n document.addEventListener(\"visibilitychange\", onVisibilityChange);\n document.addEventListener(\"mousedown\", onMouseDown);\n return true;\n}\n\nexport function deactivateCanvasPointer(): boolean {\n if (!active) return false;\n active = false;\n\n stopBroadcast();\n\n document.body.classList.remove(\"xdy-pf2e-workbench-pointer-active\");\n document.removeEventListener(\"mousemove\", onMouseMove);\n document.removeEventListener(\"visibilitychange\", onVisibilityChange);\n document.removeEventListener(\"mousedown\", onMouseDown);\n\n if (overlay) {\n overlay.style.display = \"none\";\n }\n return true;\n}\n\nfunction startBroadcast(): void {\n sendPosition(iconClass, userColor);\n const interval = getModuleSetting(\"canvasPointerBroadcastInterval\") ?? 10;\n broadcastTimer = setInterval(() => sendPosition(iconClass, userColor), interval);\n}\n\nfunction stopBroadcast(): void {\n if (broadcastTimer !== null) {\n clearInterval(broadcastTimer);\n broadcastTimer = null;\n }\n sendStop(game.user?.id ?? \"\");\n}\n\nfunction setupLocalOverlay(): void {\n if (!overlay) {\n overlay = document.createElement(\"i\");\n overlay.id = \"xdy-pf2e-workbench-pointer-overlay\";\n overlay.setAttribute(\"aria-hidden\", \"true\");\n document.body.appendChild(overlay);\n }\n overlay.className = iconClass;\n overlay.style.display = \"block\";\n overlay.style.color = userColor;\n}\n\nfunction handleRemoteSync(payload: PointerSyncPayload): void {\n if (!canvas?.ready) return;\n if (payload.userId === game.user?.id) return;\n\n const { screenX, screenY } = worldToScreen(payload.wx, payload.wy);\n\n const el = getOrCreateRemoteElement(remotes, payload.userId);\n updateRemoteElement(el, payload.iconClass, payload.color);\n el.style.left = `${Math.round(screenX)}px`;\n el.style.top = `${Math.round(screenY)}px`;\n}\n\nfunction handleRemoteStop({ userId }: { userId: string }): void {\n removeRemoteElement(remotes, userId);\n}\n\nfunction onUserConnected(user: foundry.documents.BaseUser, connected: boolean): void {\n if (!connected) {\n removeRemoteElement(remotes, user.id);\n }\n}\n\nfunction onVisibilityChange(): void {\n if (document.visibilityState === \"hidden\") {\n deactivateCanvasPointer();\n }\n}\n\nfunction onMouseMove(event: MouseEvent): void {\n if (!overlay) return;\n overlay.style.left = `${event.clientX}px`;\n overlay.style.top = `${event.clientY}px`;\n}\n\nfunction onMouseDown(_event: MouseEvent): void {\n if (!canvas?.ready) return;\n const pingMode = getModuleSetting(\"canvasPointerPingMode\");\n if (pingMode === \"sound\" || pingMode === \"visualAndSound\") {\n const src = getModuleSetting(\"canvasPointerPingSound\");\n const volume = getModuleSetting(\"canvasPointerPingVolume\");\n if (src) {\n game.audio.play(src, { volume } as Record);\n sendPing(src, volume);\n }\n }\n if (pingMode === \"visual\" || pingMode === \"visualAndSound\") {\n canvas.ping(canvas.mousePosition);\n }\n}\n\nfunction handleRemotePing(payload: PointerPingPayload): void {\n if (!canvas?.ready) return;\n if (payload.userId === game.user?.id) return;\n if (payload.soundSrc) {\n game.audio.play(payload.soundSrc, { volume: payload.volume } as Record);\n }\n}\n","import { fireAndForget, getModuleSetting } from \"./utils.ts\";\nimport { logInfo } from \"./utils/logging.ts\";\nimport { MODULENAME } from \"./constants.ts\";\nimport { canMystify, doMystification, isTokenMystified } from \"./feature/tokenMystificationHandler/index.ts\";\nimport { calcRemainingMinutes, heroPointHandler, HPHState } from \"./feature/heroPointHandler/index.ts\";\nimport { moveSelectedAheadOfCurrent } from \"./feature/initiativeHandler/index.ts\";\nimport { activateCanvasPointer, deactivateCanvasPointer } from \"./feature/canvas-pointer/index.ts\";\nimport { DEFAULT_POINTER_ICON } from \"./feature/canvas-pointer/constants.ts\";\n\nexport function registerWorkbenchKeybindings(): void {\n logInfo(`${MODULENAME} | registerKeybindings`);\n\n const keybindings = game.keybindings;\n\n keybindings.register(MODULENAME, \"addUserTargets\", {\n name: `${MODULENAME}.SETTINGS.addUserTargets.name`,\n hint: `${MODULENAME}.SETTINGS.addUserTargets.hint`,\n restricted: true,\n editable: [],\n onDown: () => {\n const map = game.users\n .filter((user) => !user.isGM)\n .map((user) => {\n return { label: user.name, key: user.id };\n });\n\n let content = `
\n \n `;\n\n foundry.applications.api.DialogV2.wait({\n window: { title: game.i18n.localize(`${MODULENAME}.SETTINGS.addUserTargets.title`) },\n content,\n buttons: [\n {\n icon: '',\n label: game.i18n.localize(`${MODULENAME}.SETTINGS.addUserTargets.addFor`),\n action: \"addFor\",\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n callback: async (_event: Event, _button: HTMLButtonElement, dialog: any) => {\n const targets = Array.from(canvas.tokens?.controlled ?? []).concat(\n canvas.tokens?.placeables.filter((it) => it.mouseInteractionManager.state === 1) ?? [],\n );\n const user: User | undefined = game.users?.find(\n (u) =>\n u.id ===\n // @ts-expect-error TODO Fix typing\n (dialog.element.querySelector(\"#dialogUserId\")?.value ?? \"\"),\n );\n if (game.user?.isGM && targets && user) {\n for (const t of targets) {\n t.setTarget(true, { user: user, releaseOthers: false });\n user.targets.add(t);\n }\n }\n },\n },\n {\n icon: '',\n label: game.i18n.localize(`${MODULENAME}.SETTINGS.addUserTargets.clearFor`),\n action: \"clearFor\",\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n callback: async (_event: Event, _button: HTMLButtonElement, dialog: any) => {\n const user: User | undefined = game.users?.find(\n (u) =>\n u.id ===\n // @ts-expect-error TODO Fix typing\n (dialog.element.querySelector(\"#dialogUserId\")?.value ?? \"\"),\n );\n if (game.user?.isGM && user) {\n const targets = user.targets;\n for (const t of targets) {\n t.setTarget(false, { user: user, releaseOthers: false });\n }\n }\n },\n },\n ],\n // @ts-expect-error TODO Fix typing\n default: \"addFor\",\n rejectClose: false,\n });\n return true;\n },\n });\n\n keybindings.register(MODULENAME, \"heroPointHandler\", {\n name: game.i18n.localize(`${MODULENAME}.SETTINGS.heroPointHandlerKey.name`),\n hint: game.i18n.localize(`${MODULENAME}.SETTINGS.heroPointHandlerKey.hint`),\n restricted: true,\n onDown: () => {\n if (game.user?.isGM && getModuleSetting(\"heroPointHandler\")) {\n fireAndForget(\n heroPointHandler(calcRemainingMinutes(false) > 0 ? HPHState.Check : HPHState.Start),\n \"heroPointHandler\",\n );\n }\n return true;\n },\n });\n\n // Move combatant\n keybindings.register(MODULENAME, \"moveBeforeCurrentCombatantKey\", {\n name: game.i18n.localize(`${MODULENAME}.SETTINGS.moveBeforeCurrentCombatantKey.name`),\n hint: game.i18n.localize(`${MODULENAME}.SETTINGS.moveBeforeCurrentCombatantKey.hint`),\n restricted: true,\n onDown: () => {\n if (game.user?.isGM) {\n // @ts-expect-error getCombatantsByToken exists according to https://foundryvtt.com/api/classes/foundry.documents.Combat.html\n const combatantByToken: Combatant | undefined = game?.combat?.getCombatantsByToken(\n canvas?.tokens?.controlled[0].id,\n )[0];\n if (combatantByToken) {\n fireAndForget(moveSelectedAheadOfCurrent(combatantByToken.id), \"moveSelectedAheadOfCurrent\");\n }\n }\n return true;\n },\n });\n\n // Mystification\n keybindings.register(MODULENAME, \"npcMystifierMystifyKey\", {\n name: game.i18n.localize(`${MODULENAME}.SETTINGS.npcMystifierMystifyKey.name`),\n hint: game.i18n.localize(`${MODULENAME}.SETTINGS.npcMystifierMystifyKey.hint`),\n restricted: true,\n editable: [{ key: \"KeyM\", modifiers: [\"Shift\"] }],\n onDown: () => {\n if (getModuleSetting(\"npcMystifier\")) {\n if (canMystify()) {\n for (const token of canvas?.tokens?.controlled ?? []) {\n fireAndForget(doMystification(token?.document, isTokenMystified(token)), \"doMystification\");\n }\n } else {\n ui.notifications?.warn(game.i18n.localize(`${MODULENAME}.SETTINGS.notifications.cantMystify`));\n }\n return true;\n }\n return false;\n },\n reservedModifiers: [],\n precedence: CONST.KEYBINDING_PRECEDENCE.NORMAL,\n });\n\n // Canvas pointer\n keybindings.register(MODULENAME, \"canvasPointer\", {\n name: game.i18n.localize(`${MODULENAME}.SETTINGS.canvasPointerKey.name`),\n hint: game.i18n.localize(`${MODULENAME}.SETTINGS.canvasPointerKey.hint`),\n restricted: false,\n editable: [{ key: \"KeyX\", modifiers: [] }],\n onDown: () => {\n if (!getModuleSetting(\"canvasPointer\")) return false;\n const iconClass = getModuleSetting(\"canvasPointerIcon\");\n return activateCanvasPointer(iconClass || DEFAULT_POINTER_ICON);\n },\n onUp: () => {\n return deactivateCanvasPointer();\n },\n reservedModifiers: [],\n precedence: CONST.KEYBINDING_PRECEDENCE.NORMAL,\n });\n\n // Macro keybinds\n for (let page = 1; page <= 5; page++) {\n for (let column = 1; column <= 10; column++) {\n keybindings.register(MODULENAME, `callHotbarPage${page}Macro${column}`, {\n name: `Call hotbar macro on page ${page} position ${column}`,\n hint: `Call hotbar macro on page ${page} position ${column}`,\n restricted: false,\n onDown: () => {\n (game.user?.getHotbarMacros(page)?.[column - 1] as Record)[\"macro\"].execute();\n return true;\n },\n });\n }\n }\n}\n","{\n \"hitPoints\": [\n {\n \"level\": -1,\n \"high\": {\n \"minimum\": 9,\n \"maximum\": 10,\n \"die\": 2\n },\n \"moderate\": {\n \"minimum\": 7,\n \"maximum\": 8,\n \"die\": 2\n },\n \"low\": {\n \"minimum\": 5,\n \"maximum\": 6,\n \"die\": 2\n }\n },\n {\n \"level\": 0,\n \"high\": {\n \"minimum\": 17,\n \"maximum\": 20,\n \"die\": 4\n },\n \"moderate\": {\n \"minimum\": 14,\n \"maximum\": 16,\n \"die\": 3\n },\n \"low\": {\n \"minimum\": 11,\n \"maximum\": 13,\n \"die\": 3\n }\n },\n {\n \"level\": 1,\n \"high\": {\n \"minimum\": 24,\n \"maximum\": 26,\n \"die\": 3\n },\n \"moderate\": {\n \"minimum\": 19,\n \"maximum\": 21,\n \"die\": 3\n },\n \"low\": {\n \"minimum\": 14,\n \"maximum\": 16,\n \"die\": 3\n }\n },\n {\n \"level\": 2,\n \"high\": {\n \"minimum\": 36,\n \"maximum\": 40,\n \"die\": 5\n },\n \"moderate\": {\n \"minimum\": 28,\n \"maximum\": 32,\n \"die\": 5\n },\n \"low\": {\n \"minimum\": 21,\n \"maximum\": 25,\n \"die\": 5\n }\n },\n {\n \"level\": 3,\n \"high\": {\n \"minimum\": 53,\n \"maximum\": 59,\n \"die\": 7\n },\n \"moderate\": {\n \"minimum\": 42,\n \"maximum\": 48,\n \"die\": 7\n },\n \"low\": {\n \"minimum\": 31,\n \"maximum\": 37,\n \"die\": 7\n }\n },\n {\n \"level\": 4,\n \"high\": {\n \"minimum\": 72,\n \"maximum\": 78,\n \"die\": 7\n },\n \"moderate\": {\n \"minimum\": 57,\n \"maximum\": 63,\n \"die\": 7\n },\n \"low\": {\n \"minimum\": 42,\n \"maximum\": 48,\n \"die\": 7\n }\n },\n {\n \"level\": 5,\n \"high\": {\n \"minimum\": 91,\n \"maximum\": 97,\n \"die\": 7\n },\n \"moderate\": {\n \"minimum\": 72,\n \"maximum\": 78,\n \"die\": 7\n },\n \"low\": {\n \"minimum\": 53,\n \"maximum\": 59,\n \"die\": 7\n }\n },\n {\n \"level\": 6,\n \"high\": {\n \"minimum\": 115,\n \"maximum\": 123,\n \"die\": 9\n },\n \"moderate\": {\n \"minimum\": 91,\n \"maximum\": 99,\n \"die\": 9\n },\n \"low\": {\n \"minimum\": 67,\n \"maximum\": 75,\n \"die\": 9\n }\n },\n {\n \"level\": 7,\n \"high\": {\n \"minimum\": 140,\n \"maximum\": 148,\n \"die\": 9\n },\n \"moderate\": {\n \"minimum\": 111,\n \"maximum\": 119,\n \"die\": 9\n },\n \"low\": {\n \"minimum\": 82,\n \"maximum\": 90,\n \"die\": 9\n }\n },\n {\n \"level\": 8,\n \"high\": {\n \"minimum\": 165,\n \"maximum\": 173,\n \"die\": 9\n },\n \"moderate\": {\n \"minimum\": 131,\n \"maximum\": 139,\n \"die\": 9\n },\n \"low\": {\n \"minimum\": 97,\n \"maximum\": 105,\n \"die\": 9\n }\n },\n {\n \"level\": 9,\n \"high\": {\n \"minimum\": 190,\n \"maximum\": 198,\n \"die\": 9\n },\n \"moderate\": {\n \"minimum\": 151,\n \"maximum\": 159,\n \"die\": 9\n },\n \"low\": {\n \"minimum\": 112,\n \"maximum\": 120,\n \"die\": 9\n }\n },\n {\n \"level\": 10,\n \"high\": {\n \"minimum\": 215,\n \"maximum\": 223,\n \"die\": 9\n },\n \"moderate\": {\n \"minimum\": 171,\n \"maximum\": 179,\n \"die\": 9\n },\n \"low\": {\n \"minimum\": 127,\n \"maximum\": 135,\n \"die\": 9\n }\n },\n {\n \"level\": 11,\n \"high\": {\n \"minimum\": 240,\n \"maximum\": 248,\n \"die\": 9\n },\n \"moderate\": {\n \"minimum\": 191,\n \"maximum\": 199,\n \"die\": 9\n },\n \"low\": {\n \"minimum\": 142,\n \"maximum\": 150,\n \"die\": 9\n }\n },\n {\n \"level\": 12,\n \"high\": {\n \"minimum\": 265,\n \"maximum\": 273,\n \"die\": 9\n },\n \"moderate\": {\n \"minimum\": 211,\n \"maximum\": 219,\n \"die\": 9\n },\n \"low\": {\n \"minimum\": 157,\n \"maximum\": 165,\n \"die\": 9\n }\n },\n {\n \"level\": 13,\n \"high\": {\n \"minimum\": 290,\n \"maximum\": 298,\n \"die\": 9\n },\n \"moderate\": {\n \"minimum\": 231,\n \"maximum\": 239,\n \"die\": 9\n },\n \"low\": {\n \"minimum\": 172,\n \"maximum\": 180,\n \"die\": 9\n }\n },\n {\n \"level\": 14,\n \"high\": {\n \"minimum\": 315,\n \"maximum\": 323,\n \"die\": 9\n },\n \"moderate\": {\n \"minimum\": 251,\n \"maximum\": 259,\n \"die\": 9\n },\n \"low\": {\n \"minimum\": 187,\n \"maximum\": 195,\n \"die\": 9\n }\n },\n {\n \"level\": 15,\n \"high\": {\n \"minimum\": 340,\n \"maximum\": 348,\n \"die\": 9\n },\n \"moderate\": {\n \"minimum\": 271,\n \"maximum\": 279,\n \"die\": 9\n },\n \"low\": {\n \"minimum\": 202,\n \"maximum\": 210,\n \"die\": 9\n }\n },\n {\n \"level\": 16,\n \"high\": {\n \"minimum\": 365,\n \"maximum\": 373,\n \"die\": 9\n },\n \"moderate\": {\n \"minimum\": 291,\n \"maximum\": 299,\n \"die\": 9\n },\n \"low\": {\n \"minimum\": 217,\n \"maximum\": 225,\n \"die\": 9\n }\n },\n {\n \"level\": 17,\n \"high\": {\n \"minimum\": 390,\n \"maximum\": 398,\n \"die\": 9\n },\n \"moderate\": {\n \"minimum\": 311,\n \"maximum\": 319,\n \"die\": 9\n },\n \"low\": {\n \"minimum\": 232,\n \"maximum\": 240,\n \"die\": 9\n }\n },\n {\n \"level\": 18,\n \"high\": {\n \"minimum\": 415,\n \"maximum\": 423,\n \"die\": 9\n },\n \"moderate\": {\n \"minimum\": 331,\n \"maximum\": 339,\n \"die\": 9\n },\n \"low\": {\n \"minimum\": 247,\n \"maximum\": 255,\n \"die\": 9\n }\n },\n {\n \"level\": 19,\n \"high\": {\n \"minimum\": 440,\n \"maximum\": 448,\n \"die\": 9\n },\n \"moderate\": {\n \"minimum\": 351,\n \"maximum\": 359,\n \"die\": 9\n },\n \"low\": {\n \"minimum\": 262,\n \"maximum\": 270,\n \"die\": 9\n }\n },\n {\n \"level\": 20,\n \"high\": {\n \"minimum\": 465,\n \"maximum\": 473,\n \"die\": 9\n },\n \"moderate\": {\n \"minimum\": 371,\n \"maximum\": 379,\n \"die\": 9\n },\n \"low\": {\n \"minimum\": 277,\n \"maximum\": 285,\n \"die\": 9\n }\n },\n {\n \"level\": 21,\n \"high\": {\n \"minimum\": 495,\n \"maximum\": 505,\n \"die\": 11\n },\n \"moderate\": {\n \"minimum\": 395,\n \"maximum\": 405,\n \"die\": 11\n },\n \"low\": {\n \"minimum\": 295,\n \"maximum\": 305,\n \"die\": 11\n }\n },\n {\n \"level\": 22,\n \"high\": {\n \"minimum\": 532,\n \"maximum\": 544,\n \"die\": 13\n },\n \"moderate\": {\n \"minimum\": 424,\n \"maximum\": 436,\n \"die\": 13\n },\n \"low\": {\n \"minimum\": 317,\n \"maximum\": 329,\n \"die\": 13\n }\n },\n {\n \"level\": 23,\n \"high\": {\n \"minimum\": 569,\n \"maximum\": 581,\n \"die\": 13\n },\n \"moderate\": {\n \"minimum\": 454,\n \"maximum\": 466,\n \"die\": 13\n },\n \"low\": {\n \"minimum\": 339,\n \"maximum\": 351,\n \"die\": 13\n }\n },\n {\n \"level\": 24,\n \"high\": {\n \"minimum\": 617,\n \"maximum\": 633,\n \"die\": 17\n },\n \"moderate\": {\n \"minimum\": 492,\n \"maximum\": 508,\n \"die\": 17\n },\n \"low\": {\n \"minimum\": 367,\n \"maximum\": 383,\n \"die\": 17\n }\n }\n ],\n \"abilityScore\": [\n {\n \"level\": -1,\n \"extreme\": 3,\n \"high\": 3,\n \"moderate\": 2,\n \"low\": 0,\n \"terrible\": -4,\n \"abysmal\": -5\n },\n {\n \"level\": 0,\n \"extreme\": 3,\n \"high\": 3,\n \"moderate\": 2,\n \"low\": 0,\n \"terrible\": -4,\n \"abysmal\": -5\n },\n {\n \"level\": 1,\n \"extreme\": 5,\n \"high\": 4,\n \"moderate\": 3,\n \"low\": 1,\n \"terrible\": -4,\n \"abysmal\": -5\n },\n {\n \"level\": 2,\n \"extreme\": 5,\n \"high\": 4,\n \"moderate\": 3,\n \"low\": 1,\n \"terrible\": -4,\n \"abysmal\": -5\n },\n {\n \"level\": 3,\n \"extreme\": 5,\n \"high\": 4,\n \"moderate\": 3,\n \"low\": 1,\n \"terrible\": -4,\n \"abysmal\": -5\n },\n {\n \"level\": 4,\n \"extreme\": 6,\n \"high\": 5,\n \"moderate\": 3,\n \"low\": 2,\n \"terrible\": -4,\n \"abysmal\": -5\n },\n {\n \"level\": 5,\n \"extreme\": 6,\n \"high\": 5,\n \"moderate\": 4,\n \"low\": 2,\n \"terrible\": -4,\n \"abysmal\": -5\n },\n {\n \"level\": 6,\n \"extreme\": 7,\n \"high\": 5,\n \"moderate\": 4,\n \"low\": 2,\n \"terrible\": -4,\n \"abysmal\": -5\n },\n {\n \"level\": 7,\n \"extreme\": 7,\n \"high\": 6,\n \"moderate\": 4,\n \"low\": 2,\n \"terrible\": -4,\n \"abysmal\": -5\n },\n {\n \"level\": 8,\n \"extreme\": 7,\n \"high\": 6,\n \"moderate\": 4,\n \"low\": 3,\n \"terrible\": -4,\n \"abysmal\": -5\n },\n {\n \"level\": 9,\n \"extreme\": 7,\n \"high\": 6,\n \"moderate\": 4,\n \"low\": 3,\n \"terrible\": -4,\n \"abysmal\": -5\n },\n {\n \"level\": 10,\n \"extreme\": 8,\n \"high\": 7,\n \"moderate\": 5,\n \"low\": 3,\n \"terrible\": -4,\n \"abysmal\": -5\n },\n {\n \"level\": 11,\n \"extreme\": 8,\n \"high\": 7,\n \"moderate\": 5,\n \"low\": 3,\n \"terrible\": -4,\n \"abysmal\": -5\n },\n {\n \"level\": 12,\n \"extreme\": 8,\n \"high\": 7,\n \"moderate\": 5,\n \"low\": 4,\n \"terrible\": -4,\n \"abysmal\": -5\n },\n {\n \"level\": 13,\n \"extreme\": 9,\n \"high\": 8,\n \"moderate\": 5,\n \"low\": 4,\n \"terrible\": -4,\n \"abysmal\": -5\n },\n {\n \"level\": 14,\n \"extreme\": 9,\n \"high\": 8,\n \"moderate\": 5,\n \"low\": 4,\n \"terrible\": -4,\n \"abysmal\": -5\n },\n {\n \"level\": 15,\n \"extreme\": 9,\n \"high\": 8,\n \"moderate\": 6,\n \"low\": 4,\n \"terrible\": -4,\n \"abysmal\": -5\n },\n {\n \"level\": 16,\n \"extreme\": 10,\n \"high\": 9,\n \"moderate\": 6,\n \"low\": 5,\n \"terrible\": -4,\n \"abysmal\": -5\n },\n {\n \"level\": 17,\n \"extreme\": 10,\n \"high\": 9,\n \"moderate\": 6,\n \"low\": 5,\n \"terrible\": -4,\n \"abysmal\": -5\n },\n {\n \"level\": 18,\n \"extreme\": 10,\n \"high\": 9,\n \"moderate\": 6,\n \"low\": 5,\n \"terrible\": -4,\n \"abysmal\": -5\n },\n {\n \"level\": 19,\n \"extreme\": 11,\n \"high\": 10,\n \"moderate\": 6,\n \"low\": 5,\n \"terrible\": -4,\n \"abysmal\": -5\n },\n {\n \"level\": 20,\n \"extreme\": 11,\n \"high\": 10,\n \"moderate\": 7,\n \"low\": 6,\n \"terrible\": -4,\n \"abysmal\": -5\n },\n {\n \"level\": 21,\n \"extreme\": 11,\n \"high\": 10,\n \"moderate\": 7,\n \"low\": 6,\n \"terrible\": -4,\n \"abysmal\": -5\n },\n {\n \"level\": 22,\n \"extreme\": 11,\n \"high\": 10,\n \"moderate\": 8,\n \"low\": 6,\n \"terrible\": -4,\n \"abysmal\": -5\n },\n {\n \"level\": 23,\n \"extreme\": 11,\n \"high\": 10,\n \"moderate\": 8,\n \"low\": 6,\n \"terrible\": -4,\n \"abysmal\": -5\n },\n {\n \"level\": 24,\n \"extreme\": 13,\n \"high\": 12,\n \"moderate\": 9,\n \"low\": 7,\n \"terrible\": -4,\n \"abysmal\": -5\n }\n ],\n \"savingThrow\": [\n {\n \"level\": -1,\n \"extreme\": 9,\n \"high\": 8,\n \"moderate\": 5,\n \"low\": 2,\n \"terrible\": 0\n },\n {\n \"level\": 0,\n \"extreme\": 10,\n \"high\": 9,\n \"moderate\": 6,\n \"low\": 3,\n \"terrible\": 1\n },\n {\n \"level\": 1,\n \"extreme\": 11,\n \"high\": 10,\n \"moderate\": 7,\n \"low\": 4,\n \"terrible\": 2\n },\n {\n \"level\": 2,\n \"extreme\": 12,\n \"high\": 11,\n \"moderate\": 8,\n \"low\": 5,\n \"terrible\": 3\n },\n {\n \"level\": 3,\n \"extreme\": 14,\n \"high\": 12,\n \"moderate\": 9,\n \"low\": 6,\n \"terrible\": 4\n },\n {\n \"level\": 4,\n \"extreme\": 15,\n \"high\": 14,\n \"moderate\": 11,\n \"low\": 8,\n \"terrible\": 6\n },\n {\n \"level\": 5,\n \"extreme\": 17,\n \"high\": 15,\n \"moderate\": 12,\n \"low\": 9,\n \"terrible\": 7\n },\n {\n \"level\": 6,\n \"extreme\": 18,\n \"high\": 17,\n \"moderate\": 14,\n \"low\": 11,\n \"terrible\": 8\n },\n {\n \"level\": 7,\n \"extreme\": 20,\n \"high\": 18,\n \"moderate\": 15,\n \"low\": 12,\n \"terrible\": 10\n },\n {\n \"level\": 8,\n \"extreme\": 21,\n \"high\": 19,\n \"moderate\": 16,\n \"low\": 13,\n \"terrible\": 11\n },\n {\n \"level\": 9,\n \"extreme\": 23,\n \"high\": 21,\n \"moderate\": 18,\n \"low\": 15,\n \"terrible\": 12\n },\n {\n \"level\": 10,\n \"extreme\": 24,\n \"high\": 22,\n \"moderate\": 19,\n \"low\": 16,\n \"terrible\": 14\n },\n {\n \"level\": 11,\n \"extreme\": 26,\n \"high\": 24,\n \"moderate\": 21,\n \"low\": 18,\n \"terrible\": 15\n },\n {\n \"level\": 12,\n \"extreme\": 27,\n \"high\": 25,\n \"moderate\": 22,\n \"low\": 19,\n \"terrible\": 16\n },\n {\n \"level\": 13,\n \"extreme\": 29,\n \"high\": 26,\n \"moderate\": 23,\n \"low\": 20,\n \"terrible\": 18\n },\n {\n \"level\": 14,\n \"extreme\": 30,\n \"high\": 28,\n \"moderate\": 25,\n \"low\": 22,\n \"terrible\": 19\n },\n {\n \"level\": 15,\n \"extreme\": 32,\n \"high\": 29,\n \"moderate\": 26,\n \"low\": 23,\n \"terrible\": 20\n },\n {\n \"level\": 16,\n \"extreme\": 33,\n \"high\": 30,\n \"moderate\": 28,\n \"low\": 25,\n \"terrible\": 22\n },\n {\n \"level\": 17,\n \"extreme\": 35,\n \"high\": 32,\n \"moderate\": 29,\n \"low\": 26,\n \"terrible\": 23\n },\n {\n \"level\": 18,\n \"extreme\": 36,\n \"high\": 33,\n \"moderate\": 30,\n \"low\": 27,\n \"terrible\": 24\n },\n {\n \"level\": 19,\n \"extreme\": 38,\n \"high\": 35,\n \"moderate\": 32,\n \"low\": 29,\n \"terrible\": 26\n },\n {\n \"level\": 20,\n \"extreme\": 39,\n \"high\": 36,\n \"moderate\": 33,\n \"low\": 30,\n \"terrible\": 27\n },\n {\n \"level\": 21,\n \"extreme\": 41,\n \"high\": 38,\n \"moderate\": 35,\n \"low\": 32,\n \"terrible\": 28\n },\n {\n \"level\": 22,\n \"extreme\": 43,\n \"high\": 39,\n \"moderate\": 36,\n \"low\": 33,\n \"terrible\": 30\n },\n {\n \"level\": 23,\n \"extreme\": 44,\n \"high\": 40,\n \"moderate\": 37,\n \"low\": 34,\n \"terrible\": 31\n },\n {\n \"level\": 24,\n \"extreme\": 46,\n \"high\": 42,\n \"moderate\": 38,\n \"low\": 36,\n \"terrible\": 32\n }\n ],\n \"armorClass\": [\n {\n \"level\": -1,\n \"extreme\": 18,\n \"high\": 15,\n \"moderate\": 14,\n \"low\": 12\n },\n {\n \"level\": 0,\n \"extreme\": 19,\n \"high\": 16,\n \"moderate\": 15,\n \"low\": 13\n },\n {\n \"level\": 1,\n \"extreme\": 19,\n \"high\": 16,\n \"moderate\": 15,\n \"low\": 13\n },\n {\n \"level\": 2,\n \"extreme\": 21,\n \"high\": 18,\n \"moderate\": 17,\n \"low\": 15\n },\n {\n \"level\": 3,\n \"extreme\": 22,\n \"high\": 19,\n \"moderate\": 18,\n \"low\": 16\n },\n {\n \"level\": 4,\n \"extreme\": 24,\n \"high\": 21,\n \"moderate\": 20,\n \"low\": 18\n },\n {\n \"level\": 5,\n \"extreme\": 25,\n \"high\": 22,\n \"moderate\": 21,\n \"low\": 19\n },\n {\n \"level\": 6,\n \"extreme\": 27,\n \"high\": 24,\n \"moderate\": 23,\n \"low\": 21\n },\n {\n \"level\": 7,\n \"extreme\": 28,\n \"high\": 25,\n \"moderate\": 24,\n \"low\": 22\n },\n {\n \"level\": 8,\n \"extreme\": 30,\n \"high\": 27,\n \"moderate\": 26,\n \"low\": 24\n },\n {\n \"level\": 9,\n \"extreme\": 31,\n \"high\": 28,\n \"moderate\": 27,\n \"low\": 25\n },\n {\n \"level\": 10,\n \"extreme\": 33,\n \"high\": 30,\n \"moderate\": 29,\n \"low\": 27\n },\n {\n \"level\": 11,\n \"extreme\": 34,\n \"high\": 31,\n \"moderate\": 30,\n \"low\": 28\n },\n {\n \"level\": 12,\n \"extreme\": 36,\n \"high\": 33,\n \"moderate\": 32,\n \"low\": 30\n },\n {\n \"level\": 13,\n \"extreme\": 37,\n \"high\": 34,\n \"moderate\": 33,\n \"low\": 31\n },\n {\n \"level\": 14,\n \"extreme\": 39,\n \"high\": 36,\n \"moderate\": 35,\n \"low\": 33\n },\n {\n \"level\": 15,\n \"extreme\": 40,\n \"high\": 37,\n \"moderate\": 36,\n \"low\": 34\n },\n {\n \"level\": 16,\n \"extreme\": 42,\n \"high\": 39,\n \"moderate\": 38,\n \"low\": 36\n },\n {\n \"level\": 17,\n \"extreme\": 43,\n \"high\": 40,\n \"moderate\": 39,\n \"low\": 37\n },\n {\n \"level\": 18,\n \"extreme\": 45,\n \"high\": 42,\n \"moderate\": 41,\n \"low\": 39\n },\n {\n \"level\": 19,\n \"extreme\": 46,\n \"high\": 43,\n \"moderate\": 42,\n \"low\": 40\n },\n {\n \"level\": 20,\n \"extreme\": 48,\n \"high\": 45,\n \"moderate\": 44,\n \"low\": 42\n },\n {\n \"level\": 21,\n \"extreme\": 49,\n \"high\": 46,\n \"moderate\": 45,\n \"low\": 43\n },\n {\n \"level\": 22,\n \"extreme\": 51,\n \"high\": 48,\n \"moderate\": 47,\n \"low\": 45\n },\n {\n \"level\": 23,\n \"extreme\": 52,\n \"high\": 49,\n \"moderate\": 48,\n \"low\": 46\n },\n {\n \"level\": 24,\n \"extreme\": 54,\n \"high\": 51,\n \"moderate\": 50,\n \"low\": 48\n }\n ],\n \"perception\": [\n {\n \"level\": -1,\n \"extreme\": 9,\n \"high\": 8,\n \"moderate\": 5,\n \"low\": 2,\n \"terrible\": 0\n },\n {\n \"level\": 0,\n \"extreme\": 10,\n \"high\": 9,\n \"moderate\": 6,\n \"low\": 3,\n \"terrible\": 1\n },\n {\n \"level\": 1,\n \"extreme\": 11,\n \"high\": 10,\n \"moderate\": 7,\n \"low\": 4,\n \"terrible\": 2\n },\n {\n \"level\": 2,\n \"extreme\": 12,\n \"high\": 11,\n \"moderate\": 8,\n \"low\": 5,\n \"terrible\": 3\n },\n {\n \"level\": 3,\n \"extreme\": 14,\n \"high\": 12,\n \"moderate\": 9,\n \"low\": 6,\n \"terrible\": 4\n },\n {\n \"level\": 4,\n \"extreme\": 15,\n \"high\": 14,\n \"moderate\": 11,\n \"low\": 8,\n \"terrible\": 6\n },\n {\n \"level\": 5,\n \"extreme\": 17,\n \"high\": 15,\n \"moderate\": 12,\n \"low\": 9,\n \"terrible\": 7\n },\n {\n \"level\": 6,\n \"extreme\": 18,\n \"high\": 17,\n \"moderate\": 14,\n \"low\": 11,\n \"terrible\": 8\n },\n {\n \"level\": 7,\n \"extreme\": 20,\n \"high\": 18,\n \"moderate\": 15,\n \"low\": 12,\n \"terrible\": 10\n },\n {\n \"level\": 8,\n \"extreme\": 21,\n \"high\": 19,\n \"moderate\": 16,\n \"low\": 13,\n \"terrible\": 11\n },\n {\n \"level\": 9,\n \"extreme\": 23,\n \"high\": 21,\n \"moderate\": 18,\n \"low\": 15,\n \"terrible\": 12\n },\n {\n \"level\": 10,\n \"extreme\": 24,\n \"high\": 22,\n \"moderate\": 19,\n \"low\": 16,\n \"terrible\": 14\n },\n {\n \"level\": 11,\n \"extreme\": 26,\n \"high\": 24,\n \"moderate\": 21,\n \"low\": 18,\n \"terrible\": 15\n },\n {\n \"level\": 12,\n \"extreme\": 27,\n \"high\": 25,\n \"moderate\": 22,\n \"low\": 19,\n \"terrible\": 16\n },\n {\n \"level\": 13,\n \"extreme\": 29,\n \"high\": 26,\n \"moderate\": 23,\n \"low\": 20,\n \"terrible\": 18\n },\n {\n \"level\": 14,\n \"extreme\": 30,\n \"high\": 28,\n \"moderate\": 25,\n \"low\": 22,\n \"terrible\": 19\n },\n {\n \"level\": 15,\n \"extreme\": 32,\n \"high\": 29,\n \"moderate\": 26,\n \"low\": 23,\n \"terrible\": 20\n },\n {\n \"level\": 16,\n \"extreme\": 33,\n \"high\": 30,\n \"moderate\": 28,\n \"low\": 25,\n \"terrible\": 22\n },\n {\n \"level\": 17,\n \"extreme\": 35,\n \"high\": 32,\n \"moderate\": 29,\n \"low\": 26,\n \"terrible\": 23\n },\n {\n \"level\": 18,\n \"extreme\": 36,\n \"high\": 33,\n \"moderate\": 30,\n \"low\": 27,\n \"terrible\": 24\n },\n {\n \"level\": 19,\n \"extreme\": 38,\n \"high\": 35,\n \"moderate\": 32,\n \"low\": 29,\n \"terrible\": 26\n },\n {\n \"level\": 20,\n \"extreme\": 39,\n \"high\": 36,\n \"moderate\": 33,\n \"low\": 30,\n \"terrible\": 27\n },\n {\n \"level\": 21,\n \"extreme\": 41,\n \"high\": 38,\n \"moderate\": 35,\n \"low\": 32,\n \"terrible\": 28\n },\n {\n \"level\": 22,\n \"extreme\": 43,\n \"high\": 39,\n \"moderate\": 36,\n \"low\": 33,\n \"terrible\": 30\n },\n {\n \"level\": 23,\n \"extreme\": 44,\n \"high\": 40,\n \"moderate\": 37,\n \"low\": 34,\n \"terrible\": 31\n },\n {\n \"level\": 24,\n \"extreme\": 46,\n \"high\": 42,\n \"moderate\": 38,\n \"low\": 36,\n \"terrible\": 32\n }\n ],\n \"skill\": [\n {\n \"level\": -1,\n \"extreme\": 8,\n \"high\": 5,\n \"moderate\": 4,\n \"low\": 2,\n \"terrible\": 1\n },\n {\n \"level\": 0,\n \"extreme\": 9,\n \"high\": 6,\n \"moderate\": 5,\n \"low\": 3,\n \"terrible\": 2\n },\n {\n \"level\": 1,\n \"extreme\": 10,\n \"high\": 7,\n \"moderate\": 6,\n \"low\": 4,\n \"terrible\": 3\n },\n {\n \"level\": 2,\n \"extreme\": 11,\n \"high\": 8,\n \"moderate\": 7,\n \"low\": 5,\n \"terrible\": 4\n },\n {\n \"level\": 3,\n \"extreme\": 13,\n \"high\": 10,\n \"moderate\": 9,\n \"low\": 7,\n \"terrible\": 5\n },\n {\n \"level\": 4,\n \"extreme\": 15,\n \"high\": 12,\n \"moderate\": 10,\n \"low\": 8,\n \"terrible\": 7\n },\n {\n \"level\": 5,\n \"extreme\": 16,\n \"high\": 13,\n \"moderate\": 12,\n \"low\": 10,\n \"terrible\": 8\n },\n {\n \"level\": 6,\n \"extreme\": 18,\n \"high\": 15,\n \"moderate\": 13,\n \"low\": 11,\n \"terrible\": 9\n },\n {\n \"level\": 7,\n \"extreme\": 20,\n \"high\": 17,\n \"moderate\": 15,\n \"low\": 13,\n \"terrible\": 11\n },\n {\n \"level\": 8,\n \"extreme\": 21,\n \"high\": 18,\n \"moderate\": 16,\n \"low\": 14,\n \"terrible\": 12\n },\n {\n \"level\": 9,\n \"extreme\": 23,\n \"high\": 20,\n \"moderate\": 18,\n \"low\": 16,\n \"terrible\": 13\n },\n {\n \"level\": 10,\n \"extreme\": 25,\n \"high\": 22,\n \"moderate\": 19,\n \"low\": 17,\n \"terrible\": 15\n },\n {\n \"level\": 11,\n \"extreme\": 26,\n \"high\": 23,\n \"moderate\": 21,\n \"low\": 19,\n \"terrible\": 16\n },\n {\n \"level\": 12,\n \"extreme\": 28,\n \"high\": 25,\n \"moderate\": 22,\n \"low\": 20,\n \"terrible\": 17\n },\n {\n \"level\": 13,\n \"extreme\": 30,\n \"high\": 27,\n \"moderate\": 24,\n \"low\": 22,\n \"terrible\": 19\n },\n {\n \"level\": 14,\n \"extreme\": 31,\n \"high\": 28,\n \"moderate\": 25,\n \"low\": 23,\n \"terrible\": 20\n },\n {\n \"level\": 15,\n \"extreme\": 33,\n \"high\": 30,\n \"moderate\": 27,\n \"low\": 25,\n \"terrible\": 21\n },\n {\n \"level\": 16,\n \"extreme\": 35,\n \"high\": 32,\n \"moderate\": 28,\n \"low\": 26,\n \"terrible\": 23\n },\n {\n \"level\": 17,\n \"extreme\": 36,\n \"high\": 33,\n \"moderate\": 30,\n \"low\": 28,\n \"terrible\": 24\n },\n {\n \"level\": 18,\n \"extreme\": 38,\n \"high\": 35,\n \"moderate\": 31,\n \"low\": 29,\n \"terrible\": 25\n },\n {\n \"level\": 19,\n \"extreme\": 40,\n \"high\": 37,\n \"moderate\": 33,\n \"low\": 31,\n \"terrible\": 27\n },\n {\n \"level\": 20,\n \"extreme\": 41,\n \"high\": 38,\n \"moderate\": 34,\n \"low\": 32,\n \"terrible\": 28\n },\n {\n \"level\": 21,\n \"extreme\": 43,\n \"high\": 40,\n \"moderate\": 36,\n \"low\": 34,\n \"terrible\": 29\n },\n {\n \"level\": 22,\n \"extreme\": 45,\n \"high\": 42,\n \"moderate\": 37,\n \"low\": 35,\n \"terrible\": 31\n },\n {\n \"level\": 23,\n \"extreme\": 46,\n \"high\": 43,\n \"moderate\": 38,\n \"low\": 36,\n \"terrible\": 32\n },\n {\n \"level\": 24,\n \"extreme\": 48,\n \"high\": 45,\n \"moderate\": 40,\n \"low\": 38,\n \"terrible\": 33\n }\n ],\n \"strikeAttack\": [\n {\n \"level\": -1,\n \"extreme\": 10,\n \"high\": 8,\n \"moderate\": 6,\n \"low\": 4\n },\n {\n \"level\": 0,\n \"extreme\": 10,\n \"high\": 8,\n \"moderate\": 6,\n \"low\": 4\n },\n {\n \"level\": 1,\n \"extreme\": 11,\n \"high\": 9,\n \"moderate\": 7,\n \"low\": 5\n },\n {\n \"level\": 2,\n \"extreme\": 13,\n \"high\": 11,\n \"moderate\": 9,\n \"low\": 7\n },\n {\n \"level\": 3,\n \"extreme\": 14,\n \"high\": 12,\n \"moderate\": 10,\n \"low\": 8\n },\n {\n \"level\": 4,\n \"extreme\": 16,\n \"high\": 14,\n \"moderate\": 12,\n \"low\": 9\n },\n {\n \"level\": 5,\n \"extreme\": 17,\n \"high\": 15,\n \"moderate\": 13,\n \"low\": 11\n },\n {\n \"level\": 6,\n \"extreme\": 19,\n \"high\": 17,\n \"moderate\": 15,\n \"low\": 12\n },\n {\n \"level\": 7,\n \"extreme\": 20,\n \"high\": 18,\n \"moderate\": 16,\n \"low\": 13\n },\n {\n \"level\": 8,\n \"extreme\": 22,\n \"high\": 20,\n \"moderate\": 18,\n \"low\": 15\n },\n {\n \"level\": 9,\n \"extreme\": 23,\n \"high\": 21,\n \"moderate\": 19,\n \"low\": 16\n },\n {\n \"level\": 10,\n \"extreme\": 25,\n \"high\": 23,\n \"moderate\": 21,\n \"low\": 17\n },\n {\n \"level\": 11,\n \"extreme\": 27,\n \"high\": 24,\n \"moderate\": 22,\n \"low\": 19\n },\n {\n \"level\": 12,\n \"extreme\": 28,\n \"high\": 26,\n \"moderate\": 24,\n \"low\": 20\n },\n {\n \"level\": 13,\n \"extreme\": 29,\n \"high\": 27,\n \"moderate\": 25,\n \"low\": 21\n },\n {\n \"level\": 14,\n \"extreme\": 31,\n \"high\": 29,\n \"moderate\": 27,\n \"low\": 23\n },\n {\n \"level\": 15,\n \"extreme\": 32,\n \"high\": 30,\n \"moderate\": 28,\n \"low\": 24\n },\n {\n \"level\": 16,\n \"extreme\": 34,\n \"high\": 32,\n \"moderate\": 30,\n \"low\": 25\n },\n {\n \"level\": 17,\n \"extreme\": 35,\n \"high\": 33,\n \"moderate\": 31,\n \"low\": 27\n },\n {\n \"level\": 18,\n \"extreme\": 37,\n \"high\": 35,\n \"moderate\": 33,\n \"low\": 28\n },\n {\n \"level\": 19,\n \"extreme\": 38,\n \"high\": 36,\n \"moderate\": 34,\n \"low\": 29\n },\n {\n \"level\": 20,\n \"extreme\": 40,\n \"high\": 38,\n \"moderate\": 36,\n \"low\": 31\n },\n {\n \"level\": 21,\n \"extreme\": 41,\n \"high\": 39,\n \"moderate\": 37,\n \"low\": 32\n },\n {\n \"level\": 22,\n \"extreme\": 43,\n \"high\": 41,\n \"moderate\": 39,\n \"low\": 33\n },\n {\n \"level\": 23,\n \"extreme\": 44,\n \"high\": 42,\n \"moderate\": 40,\n \"low\": 35\n },\n {\n \"level\": 24,\n \"extreme\": 46,\n \"high\": 44,\n \"moderate\": 42,\n \"low\": 36\n }\n ],\n \"strikeDamage\": [\n {\n \"level\": -1,\n \"extreme\": {\n \"diceCount\": 1,\n \"diceSize\": 6,\n \"original\": \"1d6+1\",\n \"average\": 4.5,\n \"bonus\": 1\n },\n \"high\": {\n \"diceCount\": 1,\n \"diceSize\": 4,\n \"original\": \"1d4+1\",\n \"average\": 3.5,\n \"bonus\": 1\n },\n \"moderate\": {\n \"diceCount\": 1,\n \"diceSize\": 4,\n \"original\": \"1d4\",\n \"average\": 2.5,\n \"bonus\": 0\n },\n \"low\": {\n \"diceCount\": 1,\n \"diceSize\": 4,\n \"original\": \"1d4\",\n \"average\": 2.5,\n \"bonus\": 0\n }\n },\n {\n \"level\": 0,\n \"extreme\": {\n \"diceCount\": 1,\n \"diceSize\": 6,\n \"original\": \"1d6+3\",\n \"average\": 6.5,\n \"bonus\": 3\n },\n \"high\": {\n \"diceCount\": 1,\n \"diceSize\": 6,\n \"original\": \"1d6+2\",\n \"average\": 5.5,\n \"bonus\": 2\n },\n \"moderate\": {\n \"diceCount\": 1,\n \"diceSize\": 4,\n \"original\": \"1d4+2\",\n \"average\": 4.5,\n \"bonus\": 2\n },\n \"low\": {\n \"diceCount\": 1,\n \"diceSize\": 4,\n \"original\": \"1d4+1\",\n \"average\": 3.5,\n \"bonus\": 1\n }\n },\n {\n \"level\": 1,\n \"extreme\": {\n \"diceCount\": 1,\n \"diceSize\": 8,\n \"original\": \"1d8+4\",\n \"average\": 8.5,\n \"bonus\": 4\n },\n \"high\": {\n \"diceCount\": 1,\n \"diceSize\": 6,\n \"original\": \"1d6+3\",\n \"average\": 6.5,\n \"bonus\": 3\n },\n \"moderate\": {\n \"diceCount\": 1,\n \"diceSize\": 6,\n \"original\": \"1d6+2\",\n \"average\": 5.5,\n \"bonus\": 2\n },\n \"low\": {\n \"diceCount\": 1,\n \"diceSize\": 4,\n \"original\": \"1d4+2\",\n \"average\": 4.5,\n \"bonus\": 2\n }\n },\n {\n \"level\": 2,\n \"extreme\": {\n \"diceCount\": 1,\n \"diceSize\": 12,\n \"original\": \"1d12+4\",\n \"average\": 10.5,\n \"bonus\": 4\n },\n \"high\": {\n \"diceCount\": 1,\n \"diceSize\": 10,\n \"original\": \"1d10+4\",\n \"average\": 9.5,\n \"bonus\": 4\n },\n \"moderate\": {\n \"diceCount\": 1,\n \"diceSize\": 8,\n \"original\": \"1d8+4\",\n \"average\": 8.5,\n \"bonus\": 4\n },\n \"low\": {\n \"diceCount\": 1,\n \"diceSize\": 6,\n \"original\": \"1d6+3\",\n \"average\": 6.5,\n \"bonus\": 3\n }\n },\n {\n \"level\": 3,\n \"extreme\": {\n \"diceCount\": 1,\n \"diceSize\": 12,\n \"original\": \"1d12+8\",\n \"average\": 14.5,\n \"bonus\": 8\n },\n \"high\": {\n \"diceCount\": 1,\n \"diceSize\": 10,\n \"original\": \"1d10+6\",\n \"average\": 11.5,\n \"bonus\": 6\n },\n \"moderate\": {\n \"diceCount\": 1,\n \"diceSize\": 8,\n \"original\": \"1d8+6\",\n \"average\": 10.5,\n \"bonus\": 6\n },\n \"low\": {\n \"diceCount\": 1,\n \"diceSize\": 6,\n \"original\": \"1d6+5\",\n \"average\": 8.5,\n \"bonus\": 5\n }\n },\n {\n \"level\": 4,\n \"extreme\": {\n \"diceCount\": 2,\n \"diceSize\": 10,\n \"original\": \"2d10+7\",\n \"average\": 18,\n \"bonus\": 7\n },\n \"high\": {\n \"diceCount\": 2,\n \"diceSize\": 8,\n \"original\": \"2d8+5\",\n \"average\": 14,\n \"bonus\": 5\n },\n \"moderate\": {\n \"diceCount\": 2,\n \"diceSize\": 6,\n \"original\": \"2d6+5\",\n \"average\": 12,\n \"bonus\": 5\n },\n \"low\": {\n \"diceCount\": 2,\n \"diceSize\": 4,\n \"original\": \"2d4+4\",\n \"average\": 9,\n \"bonus\": 4\n }\n },\n {\n \"level\": 5,\n \"extreme\": {\n \"diceCount\": 2,\n \"diceSize\": 12,\n \"original\": \"2d12+7\",\n \"average\": 20,\n \"bonus\": 7\n },\n \"high\": {\n \"diceCount\": 2,\n \"diceSize\": 8,\n \"original\": \"2d8+7\",\n \"average\": 16,\n \"bonus\": 7\n },\n \"moderate\": {\n \"diceCount\": 2,\n \"diceSize\": 6,\n \"original\": \"2d6+6\",\n \"average\": 13,\n \"bonus\": 6\n },\n \"low\": {\n \"diceCount\": 2,\n \"diceSize\": 4,\n \"original\": \"2d4+6\",\n \"average\": 11,\n \"bonus\": 6\n }\n },\n {\n \"level\": 6,\n \"extreme\": {\n \"diceCount\": 2,\n \"diceSize\": 12,\n \"original\": \"2d12+10\",\n \"average\": 23,\n \"bonus\": 10\n },\n \"high\": {\n \"diceCount\": 2,\n \"diceSize\": 8,\n \"original\": \"2d8+9\",\n \"average\": 18,\n \"bonus\": 9\n },\n \"moderate\": {\n \"diceCount\": 2,\n \"diceSize\": 6,\n \"original\": \"2d6+8\",\n \"average\": 15,\n \"bonus\": 8\n },\n \"low\": {\n \"diceCount\": 2,\n \"diceSize\": 4,\n \"original\": \"2d4+7\",\n \"average\": 12,\n \"bonus\": 7\n }\n },\n {\n \"level\": 7,\n \"extreme\": {\n \"diceCount\": 2,\n \"diceSize\": 12,\n \"original\": \"2d12+12\",\n \"average\": 25,\n \"bonus\": 12\n },\n \"high\": {\n \"diceCount\": 2,\n \"diceSize\": 10,\n \"original\": \"2d10+9\",\n \"average\": 20,\n \"bonus\": 9\n },\n \"moderate\": {\n \"diceCount\": 2,\n \"diceSize\": 8,\n \"original\": \"2d8+8\",\n \"average\": 17,\n \"bonus\": 8\n },\n \"low\": {\n \"diceCount\": 2,\n \"diceSize\": 6,\n \"original\": \"2d6+6\",\n \"average\": 13,\n \"bonus\": 6\n }\n },\n {\n \"level\": 8,\n \"extreme\": {\n \"diceCount\": 2,\n \"diceSize\": 12,\n \"original\": \"2d12+15\",\n \"average\": 28,\n \"bonus\": 15\n },\n \"high\": {\n \"diceCount\": 2,\n \"diceSize\": 10,\n \"original\": \"2d10+11\",\n \"average\": 22,\n \"bonus\": 11\n },\n \"moderate\": {\n \"diceCount\": 2,\n \"diceSize\": 8,\n \"original\": \"2d8+9\",\n \"average\": 18,\n \"bonus\": 9\n },\n \"low\": {\n \"diceCount\": 2,\n \"diceSize\": 6,\n \"original\": \"2d6+8\",\n \"average\": 15,\n \"bonus\": 8\n }\n },\n {\n \"level\": 9,\n \"extreme\": {\n \"diceCount\": 2,\n \"diceSize\": 12,\n \"original\": \"2d12+17\",\n \"average\": 30,\n \"bonus\": 17\n },\n \"high\": {\n \"diceCount\": 2,\n \"diceSize\": 10,\n \"original\": \"2d10+13\",\n \"average\": 24,\n \"bonus\": 13\n },\n \"moderate\": {\n \"diceCount\": 2,\n \"diceSize\": 8,\n \"original\": \"2d8+11\",\n \"average\": 20,\n \"bonus\": 11\n },\n \"low\": {\n \"diceCount\": 2,\n \"diceSize\": 6,\n \"original\": \"2d6+9\",\n \"average\": 16,\n \"bonus\": 9\n }\n },\n {\n \"level\": 10,\n \"extreme\": {\n \"diceCount\": 2,\n \"diceSize\": 12,\n \"original\": \"2d12+20\",\n \"average\": 33,\n \"bonus\": 20\n },\n \"high\": {\n \"diceCount\": 2,\n \"diceSize\": 12,\n \"original\": \"2d12+13\",\n \"average\": 26,\n \"bonus\": 13\n },\n \"moderate\": {\n \"diceCount\": 2,\n \"diceSize\": 10,\n \"original\": \"2d10+11\",\n \"average\": 22,\n \"bonus\": 11\n },\n \"low\": {\n \"diceCount\": 2,\n \"diceSize\": 6,\n \"original\": \"2d6+10\",\n \"average\": 17,\n \"bonus\": 10\n }\n },\n {\n \"level\": 11,\n \"extreme\": {\n \"diceCount\": 2,\n \"diceSize\": 12,\n \"original\": \"2d12+22\",\n \"average\": 35,\n \"bonus\": 22\n },\n \"high\": {\n \"diceCount\": 2,\n \"diceSize\": 12,\n \"original\": \"2d12+15\",\n \"average\": 28,\n \"bonus\": 15\n },\n \"moderate\": {\n \"diceCount\": 2,\n \"diceSize\": 10,\n \"original\": \"2d10+12\",\n \"average\": 23,\n \"bonus\": 12\n },\n \"low\": {\n \"diceCount\": 2,\n \"diceSize\": 8,\n \"original\": \"2d8+10\",\n \"average\": 19,\n \"bonus\": 10\n }\n },\n {\n \"level\": 12,\n \"extreme\": {\n \"diceCount\": 3,\n \"diceSize\": 12,\n \"original\": \"3d12+19\",\n \"average\": 38.5,\n \"bonus\": 19\n },\n \"high\": {\n \"diceCount\": 3,\n \"diceSize\": 10,\n \"original\": \"3d10+14\",\n \"average\": 30.5,\n \"bonus\": 14\n },\n \"moderate\": {\n \"diceCount\": 3,\n \"diceSize\": 8,\n \"original\": \"3d8+12\",\n \"average\": 25.5,\n \"bonus\": 12\n },\n \"low\": {\n \"diceCount\": 3,\n \"diceSize\": 6,\n \"original\": \"3d6+10\",\n \"average\": 20.5,\n \"bonus\": 10\n }\n },\n {\n \"level\": 13,\n \"extreme\": {\n \"diceCount\": 3,\n \"diceSize\": 12,\n \"original\": \"3d12+21\",\n \"average\": 40.5,\n \"bonus\": 21\n },\n \"high\": {\n \"diceCount\": 3,\n \"diceSize\": 10,\n \"original\": \"3d10+16\",\n \"average\": 32.5,\n \"bonus\": 16\n },\n \"moderate\": {\n \"diceCount\": 3,\n \"diceSize\": 8,\n \"original\": \"3d8+14\",\n \"average\": 27.5,\n \"bonus\": 14\n },\n \"low\": {\n \"diceCount\": 3,\n \"diceSize\": 6,\n \"original\": \"3d6+11\",\n \"average\": 21.5,\n \"bonus\": 11\n }\n },\n {\n \"level\": 14,\n \"extreme\": {\n \"diceCount\": 3,\n \"diceSize\": 12,\n \"original\": \"3d12+24\",\n \"average\": 43.5,\n \"bonus\": 24\n },\n \"high\": {\n \"diceCount\": 3,\n \"diceSize\": 10,\n \"original\": \"3d10+18\",\n \"average\": 34.5,\n \"bonus\": 18\n },\n \"moderate\": {\n \"diceCount\": 3,\n \"diceSize\": 8,\n \"original\": \"3d8+15\",\n \"average\": 28.5,\n \"bonus\": 15\n },\n \"low\": {\n \"diceCount\": 3,\n \"diceSize\": 6,\n \"original\": \"3d6+13\",\n \"average\": 23.5,\n \"bonus\": 13\n }\n },\n {\n \"level\": 15,\n \"extreme\": {\n \"diceCount\": 3,\n \"diceSize\": 12,\n \"original\": \"3d12+26\",\n \"average\": 45.5,\n \"bonus\": 26\n },\n \"high\": {\n \"diceCount\": 3,\n \"diceSize\": 12,\n \"original\": \"3d12+17\",\n \"average\": 36.5,\n \"bonus\": 17\n },\n \"moderate\": {\n \"diceCount\": 3,\n \"diceSize\": 10,\n \"original\": \"3d10+14\",\n \"average\": 30.5,\n \"bonus\": 14\n },\n \"low\": {\n \"diceCount\": 3,\n \"diceSize\": 6,\n \"original\": \"3d6+14\",\n \"average\": 24.5,\n \"bonus\": 14\n }\n },\n {\n \"level\": 16,\n \"extreme\": {\n \"diceCount\": 3,\n \"diceSize\": 12,\n \"original\": \"3d12+29\",\n \"average\": 48.5,\n \"bonus\": 29\n },\n \"high\": {\n \"diceCount\": 3,\n \"diceSize\": 12,\n \"original\": \"3d12+18\",\n \"average\": 37.5,\n \"bonus\": 18\n },\n \"moderate\": {\n \"diceCount\": 3,\n \"diceSize\": 10,\n \"original\": \"3d10+15\",\n \"average\": 31.5,\n \"bonus\": 15\n },\n \"low\": {\n \"diceCount\": 3,\n \"diceSize\": 6,\n \"original\": \"3d6+15\",\n \"average\": 25.5,\n \"bonus\": 15\n }\n },\n {\n \"level\": 17,\n \"extreme\": {\n \"diceCount\": 3,\n \"diceSize\": 12,\n \"original\": \"3d12+31\",\n \"average\": 50.5,\n \"bonus\": 31\n },\n \"high\": {\n \"diceCount\": 3,\n \"diceSize\": 12,\n \"original\": \"3d12+19\",\n \"average\": 38.5,\n \"bonus\": 19\n },\n \"moderate\": {\n \"diceCount\": 3,\n \"diceSize\": 10,\n \"original\": \"3d10+16\",\n \"average\": 32.5,\n \"bonus\": 16\n },\n \"low\": {\n \"diceCount\": 3,\n \"diceSize\": 6,\n \"original\": \"3d6+16\",\n \"average\": 26.5,\n \"bonus\": 16\n }\n },\n {\n \"level\": 18,\n \"extreme\": {\n \"diceCount\": 3,\n \"diceSize\": 12,\n \"original\": \"3d12+34\",\n \"average\": 53.5,\n \"bonus\": 34\n },\n \"high\": {\n \"diceCount\": 3,\n \"diceSize\": 12,\n \"original\": \"3d12+20\",\n \"average\": 39.5,\n \"bonus\": 20\n },\n \"moderate\": {\n \"diceCount\": 3,\n \"diceSize\": 10,\n \"original\": \"3d10+17\",\n \"average\": 33.5,\n \"bonus\": 17\n },\n \"low\": {\n \"diceCount\": 3,\n \"diceSize\": 6,\n \"original\": \"3d6+17\",\n \"average\": 27.5,\n \"bonus\": 17\n }\n },\n {\n \"level\": 19,\n \"extreme\": {\n \"diceCount\": 4,\n \"diceSize\": 12,\n \"original\": \"4d12+29\",\n \"average\": 55,\n \"bonus\": 29\n },\n \"high\": {\n \"diceCount\": 4,\n \"diceSize\": 10,\n \"original\": \"4d10+20\",\n \"average\": 42,\n \"bonus\": 20\n },\n \"moderate\": {\n \"diceCount\": 4,\n \"diceSize\": 8,\n \"original\": \"4d8+17\",\n \"average\": 35,\n \"bonus\": 17\n },\n \"low\": {\n \"diceCount\": 4,\n \"diceSize\": 6,\n \"original\": \"4d6+14\",\n \"average\": 28,\n \"bonus\": 14\n }\n },\n {\n \"level\": 20,\n \"extreme\": {\n \"diceCount\": 4,\n \"diceSize\": 12,\n \"original\": \"4d12+32\",\n \"average\": 58,\n \"bonus\": 32\n },\n \"high\": {\n \"diceCount\": 4,\n \"diceSize\": 10,\n \"original\": \"4d10+22\",\n \"average\": 44,\n \"bonus\": 22\n },\n \"moderate\": {\n \"diceCount\": 4,\n \"diceSize\": 8,\n \"original\": \"4d8+19\",\n \"average\": 37,\n \"bonus\": 19\n },\n \"low\": {\n \"diceCount\": 4,\n \"diceSize\": 6,\n \"original\": \"4d6+15\",\n \"average\": 29,\n \"bonus\": 15\n }\n },\n {\n \"level\": 21,\n \"extreme\": {\n \"diceCount\": 4,\n \"diceSize\": 12,\n \"original\": \"4d12+34\",\n \"average\": 60,\n \"bonus\": 34\n },\n \"high\": {\n \"diceCount\": 4,\n \"diceSize\": 10,\n \"original\": \"4d10+24\",\n \"average\": 46,\n \"bonus\": 24\n },\n \"moderate\": {\n \"diceCount\": 4,\n \"diceSize\": 8,\n \"original\": \"4d8+20\",\n \"average\": 38,\n \"bonus\": 20\n },\n \"low\": {\n \"diceCount\": 4,\n \"diceSize\": 6,\n \"original\": \"4d6+17\",\n \"average\": 31,\n \"bonus\": 17\n }\n },\n {\n \"level\": 22,\n \"extreme\": {\n \"diceCount\": 4,\n \"diceSize\": 12,\n \"original\": \"4d12+37\",\n \"average\": 63,\n \"bonus\": 37\n },\n \"high\": {\n \"diceCount\": 4,\n \"diceSize\": 10,\n \"original\": \"4d10+26\",\n \"average\": 48,\n \"bonus\": 26\n },\n \"moderate\": {\n \"diceCount\": 4,\n \"diceSize\": 8,\n \"original\": \"4d8+22\",\n \"average\": 40,\n \"bonus\": 22\n },\n \"low\": {\n \"diceCount\": 4,\n \"diceSize\": 6,\n \"original\": \"4d6+18\",\n \"average\": 32,\n \"bonus\": 18\n }\n },\n {\n \"level\": 23,\n \"extreme\": {\n \"diceCount\": 4,\n \"diceSize\": 12,\n \"original\": \"4d12+39\",\n \"average\": 65,\n \"bonus\": 39\n },\n \"high\": {\n \"diceCount\": 4,\n \"diceSize\": 12,\n \"original\": \"4d12+24\",\n \"average\": 50,\n \"bonus\": 24\n },\n \"moderate\": {\n \"diceCount\": 4,\n \"diceSize\": 10,\n \"original\": \"4d10+20\",\n \"average\": 42,\n \"bonus\": 20\n },\n \"low\": {\n \"diceCount\": 4,\n \"diceSize\": 6,\n \"original\": \"4d6+19\",\n \"average\": 33,\n \"bonus\": 19\n }\n },\n {\n \"level\": 24,\n \"extreme\": {\n \"diceCount\": 4,\n \"diceSize\": 12,\n \"original\": \"4d12+42\",\n \"average\": 68,\n \"bonus\": 42\n },\n \"high\": {\n \"diceCount\": 4,\n \"diceSize\": 12,\n \"original\": \"4d12+26\",\n \"average\": 52,\n \"bonus\": 26\n },\n \"moderate\": {\n \"diceCount\": 4,\n \"diceSize\": 10,\n \"original\": \"4d10+22\",\n \"average\": 44,\n \"bonus\": 22\n },\n \"low\": {\n \"diceCount\": 4,\n \"diceSize\": 6,\n \"original\": \"4d6+21\",\n \"average\": 35,\n \"bonus\": 21\n }\n }\n ],\n \"areaDamage\": [\n {\n \"limited\": {\n \"diceCount\": 1,\n \"diceSize\": 6,\n \"original\": \"1d6\",\n \"average\": 3.5,\n \"bonus\": 0\n },\n \"unlimited\": {\n \"diceCount\": 1,\n \"diceSize\": 4,\n \"original\": \"1d4\",\n \"average\": 2.5,\n \"bonus\": 0\n },\n \"level\": -1\n },\n {\n \"limited\": {\n \"diceCount\": 1,\n \"diceSize\": 10,\n \"original\": \"1d10\",\n \"average\": 5.5,\n \"bonus\": 0\n },\n \"unlimited\": {\n \"diceCount\": 1,\n \"diceSize\": 6,\n \"original\": \"1d6\",\n \"average\": 3.5,\n \"bonus\": 0\n },\n \"level\": 0\n },\n {\n \"limited\": {\n \"diceCount\": 2,\n \"diceSize\": 6,\n \"original\": \"2d6\",\n \"average\": 7,\n \"bonus\": 0\n },\n \"unlimited\": {\n \"diceCount\": 2,\n \"diceSize\": 4,\n \"original\": \"2d4\",\n \"average\": 5,\n \"bonus\": 0\n },\n \"level\": 1\n },\n {\n \"limited\": {\n \"diceCount\": 3,\n \"diceSize\": 6,\n \"original\": \"3d6\",\n \"average\": 10.5,\n \"bonus\": 0\n },\n \"unlimited\": {\n \"diceCount\": 2,\n \"diceSize\": 6,\n \"original\": \"2d6\",\n \"average\": 7,\n \"bonus\": 0\n },\n \"level\": 2\n },\n {\n \"limited\": {\n \"diceCount\": 4,\n \"diceSize\": 6,\n \"original\": \"4d6\",\n \"average\": 14,\n \"bonus\": 0\n },\n \"unlimited\": {\n \"diceCount\": 2,\n \"diceSize\": 8,\n \"original\": \"2d8\",\n \"average\": 9,\n \"bonus\": 0\n },\n \"level\": 3\n },\n {\n \"limited\": {\n \"diceCount\": 5,\n \"diceSize\": 6,\n \"original\": \"5d6\",\n \"average\": 17.5,\n \"bonus\": 0\n },\n \"unlimited\": {\n \"diceCount\": 3,\n \"diceSize\": 6,\n \"original\": \"3d6\",\n \"average\": 10.5,\n \"bonus\": 0\n },\n \"level\": 4\n },\n {\n \"limited\": {\n \"diceCount\": 6,\n \"diceSize\": 6,\n \"original\": \"6d6\",\n \"average\": 21,\n \"bonus\": 0\n },\n \"unlimited\": {\n \"diceCount\": 2,\n \"diceSize\": 10,\n \"original\": \"2d10\",\n \"average\": 11,\n \"bonus\": 0\n },\n \"level\": 5\n },\n {\n \"limited\": {\n \"diceCount\": 7,\n \"diceSize\": 6,\n \"original\": \"7d6\",\n \"average\": 24.5,\n \"bonus\": 0\n },\n \"unlimited\": {\n \"diceCount\": 4,\n \"diceSize\": 6,\n \"original\": \"4d6\",\n \"average\": 14,\n \"bonus\": 0\n },\n \"level\": 6\n },\n {\n \"limited\": {\n \"diceCount\": 8,\n \"diceSize\": 6,\n \"original\": \"8d6\",\n \"average\": 28,\n \"bonus\": 0\n },\n \"unlimited\": {\n \"diceCount\": 4,\n \"diceSize\": 6,\n \"original\": \"4d6\",\n \"average\": 14,\n \"bonus\": 0\n },\n \"level\": 7\n },\n {\n \"limited\": {\n \"diceCount\": 9,\n \"diceSize\": 6,\n \"original\": \"9d6\",\n \"average\": 31.5,\n \"bonus\": 0\n },\n \"unlimited\": {\n \"diceCount\": 5,\n \"diceSize\": 6,\n \"original\": \"5d6\",\n \"average\": 17.5,\n \"bonus\": 0\n },\n \"level\": 8\n },\n {\n \"limited\": {\n \"diceCount\": 10,\n \"diceSize\": 6,\n \"original\": \"10d6\",\n \"average\": 35,\n \"bonus\": 0\n },\n \"unlimited\": {\n \"diceCount\": 5,\n \"diceSize\": 6,\n \"original\": \"5d6\",\n \"average\": 17.5,\n \"bonus\": 0\n },\n \"level\": 9\n },\n {\n \"limited\": {\n \"diceCount\": 11,\n \"diceSize\": 6,\n \"original\": \"11d6\",\n \"average\": 38.5,\n \"bonus\": 0\n },\n \"unlimited\": {\n \"diceCount\": 6,\n \"diceSize\": 6,\n \"original\": \"6d6\",\n \"average\": 21,\n \"bonus\": 0\n },\n \"level\": 10\n },\n {\n \"limited\": {\n \"diceCount\": 12,\n \"diceSize\": 6,\n \"original\": \"12d6\",\n \"average\": 42,\n \"bonus\": 0\n },\n \"unlimited\": {\n \"diceCount\": 6,\n \"diceSize\": 6,\n \"original\": \"6d6\",\n \"average\": 21,\n \"bonus\": 0\n },\n \"level\": 11\n },\n {\n \"limited\": {\n \"diceCount\": 13,\n \"diceSize\": 6,\n \"original\": \"13d6\",\n \"average\": 45.5,\n \"bonus\": 0\n },\n \"unlimited\": {\n \"diceCount\": 5,\n \"diceSize\": 8,\n \"original\": \"5d8\",\n \"average\": 22.5,\n \"bonus\": 0\n },\n \"level\": 12\n },\n {\n \"limited\": {\n \"diceCount\": 14,\n \"diceSize\": 6,\n \"original\": \"14d6\",\n \"average\": 49,\n \"bonus\": 0\n },\n \"unlimited\": {\n \"diceCount\": 7,\n \"diceSize\": 6,\n \"original\": \"7d6\",\n \"average\": 24.5,\n \"bonus\": 0\n },\n \"level\": 13\n },\n {\n \"limited\": {\n \"diceCount\": 15,\n \"diceSize\": 6,\n \"original\": \"15d6\",\n \"average\": 52.5,\n \"bonus\": 0\n },\n \"unlimited\": {\n \"diceCount\": 4,\n \"diceSize\": 12,\n \"original\": \"4d12\",\n \"average\": 26,\n \"bonus\": 0\n },\n \"level\": 14\n },\n {\n \"limited\": {\n \"diceCount\": 16,\n \"diceSize\": 6,\n \"original\": \"16d6\",\n \"average\": 56,\n \"bonus\": 0\n },\n \"unlimited\": {\n \"diceCount\": 8,\n \"diceSize\": 6,\n \"original\": \"8d6\",\n \"average\": 28,\n \"bonus\": 0\n },\n \"level\": 15\n },\n {\n \"limited\": {\n \"diceCount\": 17,\n \"diceSize\": 6,\n \"original\": \"17d6\",\n \"average\": 59.5,\n \"bonus\": 0\n },\n \"unlimited\": {\n \"diceCount\": 8,\n \"diceSize\": 6,\n \"original\": \"8d6\",\n \"average\": 28,\n \"bonus\": 0\n },\n \"level\": 16\n },\n {\n \"limited\": {\n \"diceCount\": 18,\n \"diceSize\": 6,\n \"original\": \"18d6\",\n \"average\": 63,\n \"bonus\": 0\n },\n \"unlimited\": {\n \"diceCount\": 8,\n \"diceSize\": 6,\n \"original\": \"8d6\",\n \"average\": 28,\n \"bonus\": 0\n },\n \"level\": 17\n },\n {\n \"limited\": {\n \"diceCount\": 19,\n \"diceSize\": 6,\n \"original\": \"19d6\",\n \"average\": 66.5,\n \"bonus\": 0\n },\n \"unlimited\": {\n \"diceCount\": 9,\n \"diceSize\": 6,\n \"original\": \"9d6\",\n \"average\": 31.5,\n \"bonus\": 0\n },\n \"level\": 18\n },\n {\n \"limited\": {\n \"diceCount\": 20,\n \"diceSize\": 6,\n \"original\": \"20d6\",\n \"average\": 70,\n \"bonus\": 0\n },\n \"unlimited\": {\n \"diceCount\": 9,\n \"diceSize\": 6,\n \"original\": \"9d6\",\n \"average\": 31.5,\n \"bonus\": 0\n },\n \"level\": 19\n },\n {\n \"limited\": {\n \"diceCount\": 21,\n \"diceSize\": 6,\n \"original\": \"21d6\",\n \"average\": 73.5,\n \"bonus\": 0\n },\n \"unlimited\": {\n \"diceCount\": 6,\n \"diceSize\": 10,\n \"original\": \"6d10\",\n \"average\": 33,\n \"bonus\": 0\n },\n \"level\": 20\n },\n {\n \"limited\": {\n \"diceCount\": 22,\n \"diceSize\": 6,\n \"original\": \"22d6\",\n \"average\": 77,\n \"bonus\": 0\n },\n \"unlimited\": {\n \"diceCount\": 10,\n \"diceSize\": 6,\n \"original\": \"10d6\",\n \"average\": 35,\n \"bonus\": 0\n },\n \"level\": 21\n },\n {\n \"limited\": {\n \"diceCount\": 23,\n \"diceSize\": 6,\n \"original\": \"23d6\",\n \"average\": 80.5,\n \"bonus\": 0\n },\n \"unlimited\": {\n \"diceCount\": 8,\n \"diceSize\": 8,\n \"original\": \"8d8\",\n \"average\": 36,\n \"bonus\": 0\n },\n \"level\": 22\n },\n {\n \"limited\": {\n \"diceCount\": 24,\n \"diceSize\": 6,\n \"original\": \"24d6\",\n \"average\": 84,\n \"bonus\": 0\n },\n \"unlimited\": {\n \"diceCount\": 11,\n \"diceSize\": 6,\n \"original\": \"11d6\",\n \"average\": 38.5,\n \"bonus\": 0\n },\n \"level\": 23\n },\n {\n \"limited\": {\n \"diceCount\": 25,\n \"diceSize\": 6,\n \"original\": \"25d6\",\n \"average\": 87.5,\n \"bonus\": 0\n },\n \"unlimited\": {\n \"diceCount\": 11,\n \"diceSize\": 6,\n \"original\": \"11d6\",\n \"average\": 38.5,\n \"bonus\": 0\n },\n \"level\": 24\n }\n ],\n \"difficultyClass\": [\n {\n \"level\": -1,\n \"extreme\": 19,\n \"high\": 16,\n \"moderate\": 13\n },\n {\n \"level\": 0,\n \"extreme\": 19,\n \"high\": 16,\n \"moderate\": 13\n },\n {\n \"level\": 1,\n \"extreme\": 20,\n \"high\": 17,\n \"moderate\": 14\n },\n {\n \"level\": 2,\n \"extreme\": 22,\n \"high\": 18,\n \"moderate\": 15\n },\n {\n \"level\": 3,\n \"extreme\": 23,\n \"high\": 20,\n \"moderate\": 17\n },\n {\n \"level\": 4,\n \"extreme\": 25,\n \"high\": 21,\n \"moderate\": 18\n },\n {\n \"level\": 5,\n \"extreme\": 26,\n \"high\": 22,\n \"moderate\": 19\n },\n {\n \"level\": 6,\n \"extreme\": 27,\n \"high\": 24,\n \"moderate\": 21\n },\n {\n \"level\": 7,\n \"extreme\": 29,\n \"high\": 25,\n \"moderate\": 22\n },\n {\n \"level\": 8,\n \"extreme\": 30,\n \"high\": 26,\n \"moderate\": 23\n },\n {\n \"level\": 9,\n \"extreme\": 32,\n \"high\": 28,\n \"moderate\": 25\n },\n {\n \"level\": 10,\n \"extreme\": 33,\n \"high\": 29,\n \"moderate\": 26\n },\n {\n \"level\": 11,\n \"extreme\": 34,\n \"high\": 30,\n \"moderate\": 27\n },\n {\n \"level\": 12,\n \"extreme\": 36,\n \"high\": 32,\n \"moderate\": 29\n },\n {\n \"level\": 13,\n \"extreme\": 37,\n \"high\": 33,\n \"moderate\": 30\n },\n {\n \"level\": 14,\n \"extreme\": 39,\n \"high\": 34,\n \"moderate\": 31\n },\n {\n \"level\": 15,\n \"extreme\": 40,\n \"high\": 36,\n \"moderate\": 33\n },\n {\n \"level\": 16,\n \"extreme\": 41,\n \"high\": 37,\n \"moderate\": 34\n },\n {\n \"level\": 17,\n \"extreme\": 43,\n \"high\": 38,\n \"moderate\": 35\n },\n {\n \"level\": 18,\n \"extreme\": 44,\n \"high\": 40,\n \"moderate\": 37\n },\n {\n \"level\": 19,\n \"extreme\": 46,\n \"high\": 41,\n \"moderate\": 38\n },\n {\n \"level\": 20,\n \"extreme\": 47,\n \"high\": 42,\n \"moderate\": 39\n },\n {\n \"level\": 21,\n \"extreme\": 48,\n \"high\": 44,\n \"moderate\": 41\n },\n {\n \"level\": 22,\n \"extreme\": 50,\n \"high\": 45,\n \"moderate\": 42\n },\n {\n \"level\": 23,\n \"extreme\": 51,\n \"high\": 46,\n \"moderate\": 43\n },\n {\n \"level\": 24,\n \"extreme\": 52,\n \"high\": 48,\n \"moderate\": 45\n }\n ],\n \"spell\": [\n {\n \"level\": -1,\n \"extreme\": 11,\n \"high\": 8,\n \"moderate\": 5\n },\n {\n \"level\": 0,\n \"extreme\": 11,\n \"high\": 8,\n \"moderate\": 5\n },\n {\n \"level\": 1,\n \"extreme\": 12,\n \"high\": 9,\n \"moderate\": 6\n },\n {\n \"level\": 2,\n \"extreme\": 14,\n \"high\": 10,\n \"moderate\": 7\n },\n {\n \"level\": 3,\n \"extreme\": 15,\n \"high\": 12,\n \"moderate\": 9\n },\n {\n \"level\": 4,\n \"extreme\": 17,\n \"high\": 13,\n \"moderate\": 10\n },\n {\n \"level\": 5,\n \"extreme\": 18,\n \"high\": 14,\n \"moderate\": 11\n },\n {\n \"level\": 6,\n \"extreme\": 19,\n \"high\": 16,\n \"moderate\": 13\n },\n {\n \"level\": 7,\n \"extreme\": 21,\n \"high\": 17,\n \"moderate\": 14\n },\n {\n \"level\": 8,\n \"extreme\": 22,\n \"high\": 18,\n \"moderate\": 15\n },\n {\n \"level\": 9,\n \"extreme\": 24,\n \"high\": 20,\n \"moderate\": 17\n },\n {\n \"level\": 10,\n \"extreme\": 25,\n \"high\": 21,\n \"moderate\": 18\n },\n {\n \"level\": 11,\n \"extreme\": 26,\n \"high\": 22,\n \"moderate\": 19\n },\n {\n \"level\": 12,\n \"extreme\": 28,\n \"high\": 24,\n \"moderate\": 21\n },\n {\n \"level\": 13,\n \"extreme\": 29,\n \"high\": 25,\n \"moderate\": 22\n },\n {\n \"level\": 14,\n \"extreme\": 31,\n \"high\": 26,\n \"moderate\": 23\n },\n {\n \"level\": 15,\n \"extreme\": 32,\n \"high\": 28,\n \"moderate\": 25\n },\n {\n \"level\": 16,\n \"extreme\": 33,\n \"high\": 29,\n \"moderate\": 26\n },\n {\n \"level\": 17,\n \"extreme\": 35,\n \"high\": 30,\n \"moderate\": 27\n },\n {\n \"level\": 18,\n \"extreme\": 36,\n \"high\": 32,\n \"moderate\": 29\n },\n {\n \"level\": 19,\n \"extreme\": 38,\n \"high\": 33,\n \"moderate\": 30\n },\n {\n \"level\": 20,\n \"extreme\": 39,\n \"high\": 34,\n \"moderate\": 31\n },\n {\n \"level\": 21,\n \"extreme\": 40,\n \"high\": 36,\n \"moderate\": 33\n },\n {\n \"level\": 22,\n \"extreme\": 42,\n \"high\": 37,\n \"moderate\": 34\n },\n {\n \"level\": 23,\n \"extreme\": 43,\n \"high\": 38,\n \"moderate\": 35\n },\n {\n \"level\": 24,\n \"extreme\": 44,\n \"high\": 40,\n \"moderate\": 37\n }\n ],\n \"resistance\": [\n {\n \"level\": -1,\n \"maximum\": 1,\n \"minimum\": 1\n },\n {\n \"level\": 0,\n \"maximum\": 3,\n \"minimum\": 1\n },\n {\n \"level\": 1,\n \"maximum\": 3,\n \"minimum\": 2\n },\n {\n \"level\": 2,\n \"maximum\": 5,\n \"minimum\": 2\n },\n {\n \"level\": 3,\n \"maximum\": 6,\n \"minimum\": 3\n },\n {\n \"level\": 4,\n \"maximum\": 7,\n \"minimum\": 4\n },\n {\n \"level\": 5,\n \"maximum\": 8,\n \"minimum\": 4\n },\n {\n \"level\": 6,\n \"maximum\": 9,\n \"minimum\": 5\n },\n {\n \"level\": 7,\n \"maximum\": 10,\n \"minimum\": 5\n },\n {\n \"level\": 8,\n \"maximum\": 11,\n \"minimum\": 6\n },\n {\n \"level\": 9,\n \"maximum\": 12,\n \"minimum\": 6\n },\n {\n \"level\": 10,\n \"maximum\": 13,\n \"minimum\": 7\n },\n {\n \"level\": 11,\n \"maximum\": 14,\n \"minimum\": 7\n },\n {\n \"level\": 12,\n \"maximum\": 15,\n \"minimum\": 8\n },\n {\n \"level\": 13,\n \"maximum\": 16,\n \"minimum\": 8\n },\n {\n \"level\": 14,\n \"maximum\": 17,\n \"minimum\": 9\n },\n {\n \"level\": 15,\n \"maximum\": 18,\n \"minimum\": 9\n },\n {\n \"level\": 16,\n \"maximum\": 19,\n \"minimum\": 9\n },\n {\n \"level\": 17,\n \"maximum\": 19,\n \"minimum\": 10\n },\n {\n \"level\": 18,\n \"maximum\": 20,\n \"minimum\": 10\n },\n {\n \"level\": 19,\n \"maximum\": 21,\n \"minimum\": 11\n },\n {\n \"level\": 20,\n \"maximum\": 22,\n \"minimum\": 11\n },\n {\n \"level\": 21,\n \"maximum\": 23,\n \"minimum\": 12\n },\n {\n \"level\": 22,\n \"maximum\": 24,\n \"minimum\": 12\n },\n {\n \"level\": 23,\n \"maximum\": 25,\n \"minimum\": 13\n },\n {\n \"level\": 24,\n \"maximum\": 26,\n \"minimum\": 13\n }\n ],\n \"weakness\": [\n {\n \"level\": -1,\n \"maximum\": 1,\n \"minimum\": 1\n },\n {\n \"level\": 0,\n \"maximum\": 3,\n \"minimum\": 1\n },\n {\n \"level\": 1,\n \"maximum\": 3,\n \"minimum\": 2\n },\n {\n \"level\": 2,\n \"maximum\": 5,\n \"minimum\": 2\n },\n {\n \"level\": 3,\n \"maximum\": 6,\n \"minimum\": 3\n },\n {\n \"level\": 4,\n \"maximum\": 7,\n \"minimum\": 4\n },\n {\n \"level\": 5,\n \"maximum\": 8,\n \"minimum\": 4\n },\n {\n \"level\": 6,\n \"maximum\": 9,\n \"minimum\": 5\n },\n {\n \"level\": 7,\n \"maximum\": 10,\n \"minimum\": 5\n },\n {\n \"level\": 8,\n \"maximum\": 11,\n \"minimum\": 6\n },\n {\n \"level\": 9,\n \"maximum\": 12,\n \"minimum\": 6\n },\n {\n \"level\": 10,\n \"maximum\": 13,\n \"minimum\": 7\n },\n {\n \"level\": 11,\n \"maximum\": 14,\n \"minimum\": 7\n },\n {\n \"level\": 12,\n \"maximum\": 15,\n \"minimum\": 8\n },\n {\n \"level\": 13,\n \"maximum\": 16,\n \"minimum\": 8\n },\n {\n \"level\": 14,\n \"maximum\": 17,\n \"minimum\": 9\n },\n {\n \"level\": 15,\n \"maximum\": 18,\n \"minimum\": 9\n },\n {\n \"level\": 16,\n \"maximum\": 19,\n \"minimum\": 9\n },\n {\n \"level\": 17,\n \"maximum\": 19,\n \"minimum\": 10\n },\n {\n \"level\": 18,\n \"maximum\": 20,\n \"minimum\": 10\n },\n {\n \"level\": 19,\n \"maximum\": 21,\n \"minimum\": 11\n },\n {\n \"level\": 20,\n \"maximum\": 22,\n \"minimum\": 11\n },\n {\n \"level\": 21,\n \"maximum\": 23,\n \"minimum\": 12\n },\n {\n \"level\": 22,\n \"maximum\": 24,\n \"minimum\": 12\n },\n {\n \"level\": 23,\n \"maximum\": 25,\n \"minimum\": 13\n },\n {\n \"level\": 24,\n \"maximum\": 26,\n \"minimum\": 13\n }\n ],\n \"hazarddefense\": [\n {\n \"level\": -1,\n \"eac\": 18,\n \"hac\": 15,\n \"lac\": 12,\n \"esave\": 9,\n \"hsave\": 8,\n \"lsave\": 2,\n \"hardness\": \"2-4\",\n \"hpmin\": 11\n },\n {\n \"level\": 0,\n \"eac\": 19,\n \"hac\": 16,\n \"lac\": 13,\n \"esave\": 10,\n \"hsave\": 9,\n \"lsave\": 3,\n \"hardness\": \"3-5\",\n \"hitPoints\": \"15-17\"\n },\n {\n \"level\": 1,\n \"eac\": 19,\n \"hac\": 16,\n \"lac\": 13,\n \"esave\": 11,\n \"hsave\": 10,\n \"lsave\": 4,\n \"hardness\": \"5-7\",\n \"hitPoints\": \"23-25\"\n },\n {\n \"level\": 2,\n \"eac\": 21,\n \"hac\": 18,\n \"lac\": 15,\n \"esave\": 12,\n \"hsave\": 11,\n \"lsave\": 5,\n \"hardness\": \"7-9\",\n \"hitPoints\": \"30-34\"\n },\n {\n \"level\": 3,\n \"eac\": 22,\n \"hac\": 19,\n \"lac\": 16,\n \"esave\": 14,\n \"hsave\": 12,\n \"lsave\": 6,\n \"hardness\": \"10-12\",\n \"hitPoints\": \"42-46\"\n },\n {\n \"level\": 4,\n \"eac\": 24,\n \"hac\": 21,\n \"lac\": 18,\n \"esave\": 15,\n \"hsave\": 14,\n \"lsave\": 8,\n \"hardness\": \"11-13\",\n \"hitPoints\": \"46-50\"\n },\n {\n \"level\": 5,\n \"eac\": 25,\n \"hac\": 22,\n \"lac\": 19,\n \"esave\": 17,\n \"hsave\": 15,\n \"lsave\": 9,\n \"hardness\": \"12-14\",\n \"hitPoints\": \"50-54\"\n },\n {\n \"level\": 6,\n \"eac\": 27,\n \"hac\": 24,\n \"lac\": 21,\n \"esave\": 18,\n \"hsave\": 17,\n \"lsave\": 11,\n \"hardness\": \"13-15\",\n \"hitPoints\": \"54-58\"\n },\n {\n \"level\": 7,\n \"eac\": 28,\n \"hac\": 25,\n \"lac\": 22,\n \"esave\": 20,\n \"hsave\": 18,\n \"lsave\": 12,\n \"hardness\": \"14-16\",\n \"hitPoints\": \"58-62\"\n },\n {\n \"level\": 8,\n \"eac\": 30,\n \"hac\": 27,\n \"lac\": 24,\n \"esave\": 21,\n \"hsave\": 19,\n \"lsave\": 13,\n \"hardness\": \"15-17\",\n \"hitPoints\": \"62-66\"\n },\n {\n \"level\": 9,\n \"eac\": 31,\n \"hac\": 28,\n \"lac\": 25,\n \"esave\": 23,\n \"hsave\": 21,\n \"lsave\": 15,\n \"hardness\": \"16-18\",\n \"hitPoints\": \"66-70\"\n },\n {\n \"level\": 10,\n \"eac\": 33,\n \"hac\": 30,\n \"lac\": 27,\n \"esave\": 24,\n \"hsave\": 22,\n \"lsave\": 16,\n \"hardness\": \"17-19\",\n \"hitPoints\": \"70-74\"\n },\n {\n \"level\": 11,\n \"eac\": 34,\n \"hac\": 31,\n \"lac\": 28,\n \"esave\": 26,\n \"hsave\": 24,\n \"lsave\": 18,\n \"hardness\": \"19-21\",\n \"hitPoints\": \"78-82\"\n },\n {\n \"level\": 12,\n \"eac\": 36,\n \"hac\": 33,\n \"lac\": 30,\n \"esave\": 27,\n \"hsave\": 25,\n \"lsave\": 19,\n \"hardness\": \"20-22\",\n \"hitPoints\": \"82-86\"\n },\n {\n \"level\": 13,\n \"eac\": 37,\n \"hac\": 34,\n \"lac\": 31,\n \"esave\": 29,\n \"hsave\": 26,\n \"lsave\": 20,\n \"hardness\": \"21-23\",\n \"hitPoints\": \"86-90\"\n },\n {\n \"level\": 14,\n \"eac\": 39,\n \"hac\": 36,\n \"lac\": 33,\n \"esave\": 30,\n \"hsave\": 28,\n \"lsave\": 22,\n \"hardness\": \"22-24\",\n \"hitPoints\": \"90-94\"\n },\n {\n \"level\": 15,\n \"eac\": 40,\n \"hac\": 37,\n \"lac\": 34,\n \"esave\": 32,\n \"hsave\": 29,\n \"lsave\": 23,\n \"hardness\": \"23-25\",\n \"hitPoints\": \"94-98\"\n },\n {\n \"level\": 16,\n \"eac\": 42,\n \"hac\": 39,\n \"lac\": 36,\n \"esave\": 33,\n \"hsave\": 30,\n \"lsave\": 25,\n \"hardness\": \"25-27\",\n \"hitPoints\": \"101-107\"\n },\n {\n \"level\": 17,\n \"eac\": 43,\n \"hac\": 40,\n \"lac\": 37,\n \"esave\": 35,\n \"hsave\": 32,\n \"lsave\": 26,\n \"hardness\": \"27-29\",\n \"hitPoints\": \"109-115\"\n },\n {\n \"level\": 18,\n \"eac\": 45,\n \"hac\": 42,\n \"lac\": 39,\n \"esave\": 36,\n \"hsave\": 33,\n \"lsave\": 27,\n \"hardness\": \"29-31\",\n \"hitPoints\": \"117-123\"\n },\n {\n \"level\": 19,\n \"eac\": 46,\n \"hac\": 43,\n \"lac\": 40,\n \"esave\": 38,\n \"hsave\": 35,\n \"lsave\": 29,\n \"hardness\": \"31-33\",\n \"hitPoints\": \"125-131\"\n },\n {\n \"level\": 20,\n \"eac\": 48,\n \"hac\": 45,\n \"lac\": 42,\n \"esave\": 39,\n \"hsave\": 36,\n \"lsave\": 30,\n \"hardness\": \"33-35\",\n \"hitPoints\": \"133-139\"\n },\n {\n \"level\": 21,\n \"eac\": 49,\n \"hac\": 46,\n \"lac\": 43,\n \"esave\": 41,\n \"hsave\": 38,\n \"lsave\": 32,\n \"hardness\": \"36-38\",\n \"hitPoints\": \"144-152\"\n },\n {\n \"level\": 22,\n \"eac\": 51,\n \"hac\": 48,\n \"lac\": 45,\n \"esave\": 43,\n \"hsave\": 39,\n \"lsave\": 33,\n \"hardness\": \"39-41\",\n \"hitPoints\": \"156-164\"\n },\n {\n \"level\": 23,\n \"eac\": 52,\n \"hac\": 49,\n \"lac\": 46,\n \"esave\": 44,\n \"hsave\": 40,\n \"lsave\": 34,\n \"hardness\": \"44-46\",\n \"hitPoints\": \"168-176\"\n },\n {\n \"level\": 24,\n \"eac\": 54,\n \"hac\": 51,\n \"lac\": 48,\n \"esave\": 46,\n \"hsave\": 42,\n \"lsave\": 36,\n \"hardness\": \"46-50\",\n \"hitPoints\": \"180-188\"\n }\n ],\n \"hazardoffense\": [\n {\n \"level\": -1,\n \"satk\": 10,\n \"catk\": 8,\n \"simpledmg\": \"2d4+1\",\n \"complexdmg\": \"1d4+1\",\n \"edc\": 19,\n \"hdc\": 16\n },\n {\n \"level\": 0,\n \"satk\": 11,\n \"catk\": 8,\n \"simpledmg\": \"2d6+3\",\n \"complexdmg\": \"1d6+2\",\n \"edc\": 19,\n \"hdc\": 16\n },\n {\n \"level\": 1,\n \"satk\": 13,\n \"catk\": 9,\n \"simpledmg\": \"2d6+5\",\n \"complexdmg\": \"1d6+3\",\n \"edc\": 20,\n \"hdc\": 17\n },\n {\n \"level\": 2,\n \"satk\": 14,\n \"catk\": 11,\n \"simpledmg\": \"2d10+7\",\n \"complexdmg\": \"1d10+4\",\n \"edc\": 22,\n \"hdc\": 18\n },\n {\n \"level\": 3,\n \"satk\": 16,\n \"catk\": 12,\n \"simpledmg\": \"2d10+13\",\n \"complexdmg\": \"1d10+6\",\n \"edc\": 23,\n \"hdc\": 20\n },\n {\n \"level\": 4,\n \"satk\": 17,\n \"catk\": 14,\n \"simpledmg\": \"4d8+10\",\n \"complexdmg\": \"2d8+5\",\n \"edc\": 25,\n \"hdc\": 21\n },\n {\n \"level\": 5,\n \"satk\": 19,\n \"catk\": 15,\n \"simpledmg\": \"4d8+14\",\n \"complexdmg\": \"2d8+7\",\n \"edc\": 26,\n \"hdc\": 22\n },\n {\n \"level\": 6,\n \"satk\": 20,\n \"catk\": 17,\n \"simpledmg\": \"4d8+18\",\n \"complexdmg\": \"2d8+9\",\n \"edc\": 27,\n \"hdc\": 24\n },\n {\n \"level\": 7,\n \"satk\": 22,\n \"catk\": 18,\n \"simpledmg\": \"4d10+18\",\n \"complexdmg\": \"2d10+9\",\n \"edc\": 29,\n \"hdc\": 25\n },\n {\n \"level\": 8,\n \"satk\": 23,\n \"catk\": 20,\n \"simpledmg\": \"4d10+22\",\n \"complexdmg\": \"2d10+11\",\n \"edc\": 30,\n \"hdc\": 26\n },\n {\n \"level\": 9,\n \"satk\": 25,\n \"catk\": 21,\n \"simpledmg\": \"4d10+26\",\n \"complexdmg\": \"2d10+13\",\n \"edc\": 32,\n \"hdc\": 28\n },\n {\n \"level\": 10,\n \"satk\": 26,\n \"catk\": 23,\n \"simpledmg\": \"4d12+26\",\n \"complexdmg\": \"2d12+13\",\n \"edc\": 33,\n \"hdc\": 29\n },\n {\n \"level\": 11,\n \"satk\": 28,\n \"catk\": 24,\n \"simpledmg\": \"4d12+30\",\n \"complexdmg\": \"2d12+15\",\n \"edc\": 34,\n \"hdc\": 30\n },\n {\n \"level\": 12,\n \"satk\": 29,\n \"catk\": 26,\n \"simpledmg\": \"6d10+27\",\n \"complexdmg\": \"3d10+14\",\n \"edc\": 36,\n \"hdc\": 32\n },\n {\n \"level\": 13,\n \"satk\": 31,\n \"catk\": 27,\n \"simpledmg\": \"6d10+31\",\n \"complexdmg\": \"3d10+16\",\n \"edc\": 37,\n \"hdc\": 33\n },\n {\n \"level\": 14,\n \"satk\": 32,\n \"catk\": 29,\n \"simpledmg\": \"6d10+35\",\n \"complexdmg\": \"3d10+18\",\n \"edc\": 39,\n \"hdc\": 34\n },\n {\n \"level\": 15,\n \"satk\": 34,\n \"catk\": 30,\n \"simpledmg\": \"6d12+33\",\n \"complexdmg\": \"3d12+17\",\n \"edc\": 40,\n \"hdc\": 36\n },\n {\n \"level\": 16,\n \"satk\": 35,\n \"catk\": 32,\n \"simpledmg\": \"6d12+35\",\n \"complexdmg\": \"3d12+18\",\n \"edc\": 41,\n \"hdc\": 37\n },\n {\n \"level\": 17,\n \"satk\": 37,\n \"catk\": 33,\n \"simpledmg\": \"6d12+37\",\n \"complexdmg\": \"3d12+19\",\n \"edc\": 43,\n \"hdc\": 38\n },\n {\n \"level\": 18,\n \"satk\": 38,\n \"catk\": 35,\n \"simpledmg\": \"6d12+41\",\n \"complexdmg\": \"3d12+20\",\n \"edc\": 44,\n \"hdc\": 40\n },\n {\n \"level\": 19,\n \"satk\": 40,\n \"catk\": 36,\n \"simpledmg\": \"8d10+40\",\n \"complexdmg\": \"4d10+20\",\n \"edc\": 46,\n \"hdc\": 41\n },\n {\n \"level\": 20,\n \"satk\": 41,\n \"catk\": 38,\n \"simpledmg\": \"8d10+44\",\n \"complexdmg\": \"4d10+22\",\n \"edc\": 47,\n \"hdc\": 42\n },\n {\n \"level\": 21,\n \"satk\": 43,\n \"catk\": 39,\n \"simpledmg\": \"8d10+48\",\n \"complexdmg\": \"4d10+24\",\n \"edc\": 48,\n \"hdc\": 44\n },\n {\n \"level\": 22,\n \"satk\": 44,\n \"catk\": 41,\n \"simpledmg\": \"8d10+52\",\n \"complexdmg\": \"4d10+26\",\n \"edc\": 50,\n \"hdc\": 45\n },\n {\n \"level\": 23,\n \"satk\": 46,\n \"catk\": 42,\n \"simpledmg\": \"8d12+48\",\n \"complexdmg\": \"4d12+24\",\n \"edc\": 51,\n \"hdc\": 46\n },\n {\n \"level\": 24,\n \"satk\": 47,\n \"catk\": 44,\n \"simpledmg\": \"8d12+52\",\n \"complexdmg\": \"4d12+26\",\n \"edc\": 52,\n \"hdc\": 48\n }\n ],\n \"level\": [-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24]\n}\n","import { MODULENAME } from \"../../constants.ts\";\nimport { logWarn } from \"../../utils/logging.ts\";\nimport SCALE_APP_DATA from \"../npc-scale-data.json\" with { type: \"json\" };\nimport type { RollMode } from \"foundry-pf2e/foundry/common/constants.d.mts\";\n\nexport async function registerNpcRollerHandlebarsTemplates(): Promise {\n await foundry.applications.handlebars.loadTemplates([\n `modules/${MODULENAME}/templates/feature/npc-roller/index.hbs`,\n `modules/${MODULENAME}/templates/feature/npc-roller/table.hbs`,\n `modules/${MODULENAME}/templates/feature/npc-roller/cell.hbs`,\n ]);\n\n Handlebars.registerPartial(\"rollAppTable\", `{{> \"modules/${MODULENAME}/templates/feature/npc-roller/table.hbs\"}}`);\n Handlebars.registerPartial(\"rollAppCell\", `{{> \"modules/${MODULENAME}/templates/feature/npc-roller/cell.hbs\"}}`);\n}\n\nexport async function setupNpcRoller(): Promise {\n Hooks.on(\"renderJournalDirectory\", enableNpcRollerButton);\n\n await registerNpcRollerHandlebarsTemplates();\n}\n\nexport function enableNpcRollerButton(_app: unknown, html: HTMLElement): void {\n // Create the button element\n const button = document.createElement(\"button\");\n button.innerHTML = ` ${game.i18n.localize(`${MODULENAME}.npcRoller.button-label`)}`;\n button.addEventListener(\"click\", () => {\n new NpcRoller().render({ force: true }); // Handle button click\n });\n\n // Locate the footer using querySelector\n const footer = html.querySelector(\".directory-footer.action-buttons\");\n if (footer) {\n footer.appendChild(button); // Append the button to the footer\n } else {\n logWarn(\"enableNpcRollerButton: Footer element not found.\");\n }\n}\n\nexport class NpcRoller extends foundry.applications.api.HandlebarsApplicationMixin(\n foundry.applications.api.ApplicationV2,\n) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n static override DEFAULT_OPTIONS: Record = {\n id: \"xdy-pf2e-workbench-npc-roller\",\n window: {\n resizable: true,\n },\n position: { width: 800, height: \"auto\" },\n };\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n static override TABS: Record = {\n primary: {\n tabs: [\n { id: \"roll-app-strike\" },\n { id: \"roll-app-damage\" },\n { id: \"roll-app-ac\" },\n { id: \"roll-app-save\" },\n { id: \"roll-app-hp\" },\n { id: \"roll-app-spell\" },\n { id: \"roll-app-dc\" },\n { id: \"roll-app-areaDamage\" },\n { id: \"roll-app-perception\" },\n { id: \"roll-app-skill\" },\n { id: \"roll-app-abilityScore\" },\n ],\n initial: \"roll-app-strike\",\n },\n };\n\n public constructor(options?: any) {\n super(options);\n }\n\n static override get PARTS(): { index: { template: string } } {\n return {\n index: { template: `modules/${MODULENAME}/templates/feature/npc-roller/index.hbs` },\n };\n }\n\n override get title(): string {\n return game.i18n.localize(`${MODULENAME}.npcRoller.title`);\n }\n\n static onControlToken(): void {\n // @ts-expect-error TODO fix\n const roller = Object.values(ui.windows).find((w) => w.id === \"xdy-pf2e-workbench-npc-roller\") as NpcRoller;\n if (roller) {\n roller.render({ force: true });\n }\n }\n\n override async _prepareContext(options?: object): Promise {\n // @ts-expect-error TODO fix\n const context = await super._prepareContext(options);\n return foundry.utils.mergeObject(context, {\n data: {\n levels: fu.deepClone(SCALE_APP_DATA),\n selected: canvas.tokens?.controlled.map((token) => token.actor?.system[\"details\"].level.value),\n },\n });\n }\n\n override async _preparePartContext(partId: string, context: object, options?: object): Promise {\n // @ts-expect-error TODO fix\n context = await super._preparePartContext(partId, context, options);\n if (partId === \"index\") {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (context as any).tabs = this._prepareTabs(\"primary\");\n }\n return context;\n }\n\n // @ts-expect-error TODO fix\n override _onRender(_context: object, _options: object): void {\n const tabButtons = Array.from(this.element.querySelectorAll(\"[role='tab'][data-tab]\"));\n const tabPanels = Array.from(this.element.querySelectorAll(\".tab[data-tab]:not([role='tab'])\"));\n tabButtons.forEach((btn) => {\n btn.addEventListener(\"click\", () => {\n const tabId = btn.dataset.tab!;\n const group = btn.dataset.group ?? \"primary\";\n this.tabGroups[group] = tabId;\n tabButtons\n .filter((b) => b.dataset.group === group)\n .forEach((b) => b.classList.toggle(\"active\", b.dataset.tab === tabId));\n tabPanels\n .filter((p) => p.dataset.group === group)\n .forEach((p) => p.classList.toggle(\"active\", p.dataset.tab === tabId));\n });\n });\n\n this.element\n .querySelectorAll(\"button.rollable\")\n .forEach((btn) => btn.addEventListener(\"click\", (event) => this.#handleRollButtonClick(event)));\n }\n\n async #handleRollButtonClick(event: Event): Promise {\n const target = event.currentTarget as HTMLButtonElement;\n const rollName = target.dataset.rollname as string;\n const token = canvas.tokens?.controlled[0];\n const formula = target.dataset.formula as string | number | undefined;\n const keyboardManager = foundry.helpers.interaction.KeyboardManager;\n const secret = game.keyboard.isModifierActive(keyboardManager.MODIFIER_KEYS.CONTROL);\n\n if (formula) {\n let roll: ConstructorOf | undefined;\n const formulaString = formula.toString();\n const lowerCase = rollName.toLowerCase();\n if (lowerCase.includes(\"damage\")) {\n roll = CONFIG.Dice.rolls.find((r) => r.name === \"DamageRoll\");\n if (!roll) throw new Error(\"DamageRoll doesn't exist‽\");\n } else {\n roll = Roll;\n }\n await new roll(formulaString).toMessage(\n {\n speaker: ChatMessage.getSpeaker({ token: token?.document }),\n flavor: rollName,\n whisper: ChatMessage.getWhisperRecipients(\"GM\").map((u) => u.id),\n },\n {\n rollMode: secret\n ? CONST.DICE_ROLL_MODES.PRIVATE\n : (game.settings.get(\"core\", \"messageMode\") as RollMode),\n create: true,\n },\n );\n }\n }\n}\n","/*\n * Copyright 2021 Andrew Cuccinello, 2022 Jonas Karlsson\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ActorPF2e } from \"foundry-pf2e\";\n\nexport function getFolder(name: string) {\n return game.folders?.getName(name);\n}\n\nexport function getFolderInFolder(name: string, parentName?: string) {\n let parent: any;\n if (parentName) {\n parent = game.folders?.getName(parentName);\n return parent.getSubfolders().find((f: Folder) => f.name === name);\n } else {\n return getFolder(name);\n }\n}\n\nexport function getActor(name: string, folder: string): ActorPF2e | undefined {\n return game.actors?.find((a) => a.name === name && a.folder?.name === folder);\n}\n","/* Copyright 2020 Andrew Cuccinello, 2022 Jonas Karlsson\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { IDicePool } from \"./NPCScalerTypes.ts\";\nimport SCALE_APP_DATA from \"../npc-scale-data.json\" with { type: \"json\" };\n\ninterface ScaleEntry {\n level: number;\n [key: string]: number | IDicePool | { minimum: number; maximum: number } | undefined;\n}\n\ntype ScaleTable = ScaleEntry[];\n\nexport function parseDamage(value: string): IDicePool {\n const [diceString, bonusString] = value.split(\"+\");\n let bonus = 0;\n if (bonusString !== undefined) {\n bonus = parseInt(bonusString);\n }\n\n const [diceCountString, diceSizeString] = diceString.split(\"d\");\n const result = {\n diceCount: parseInt(diceCountString),\n diceSize: parseInt(diceSizeString),\n original: value,\n average: 0,\n bonus,\n };\n\n result.average = ((result.diceSize + 1) / 2) * result.diceCount + result.bonus;\n\n return result;\n}\n\nexport function constructFormula({\n diceCount,\n diceSize,\n bonus,\n}: {\n diceCount: number;\n diceSize: number;\n bonus: number;\n}) {\n let formula = `${diceCount}d${diceSize}`;\n if (bonus > 0) {\n formula = `${formula}+${bonus}`;\n }\n return formula;\n}\n\nexport function getLeveledData(key: keyof typeof SCALE_APP_DATA, oldValue: number, oldLevel: number, newLevel: number) {\n const data = SCALE_APP_DATA[key] as ScaleTable;\n const oldLevelData = data[oldLevel + 1];\n const newLevelData = data[newLevel + 1];\n\n let bestMatch: { key: string; delta: number } = { key: \"undefined\", delta: Number.MAX_SAFE_INTEGER };\n for (const entry of Object.entries(oldLevelData)) {\n const entryKey = entry[0];\n if (entryKey === \"level\") {\n continue;\n }\n\n const value = Number(entry[1]);\n const delta = Math.abs(value - oldValue);\n\n if (delta < bestMatch.delta) {\n bestMatch = {\n key: entryKey,\n delta,\n };\n }\n }\n\n const result = {\n value: newLevelData[bestMatch.key] as number,\n delta: oldValue - (oldLevelData[bestMatch.key] as number),\n total: 0,\n };\n result.total = result.value + result.delta;\n\n return result;\n}\n\nexport function getHPData(oldValue: number, oldLevel: number, newLevel: number): number {\n const data = SCALE_APP_DATA[\"hitPoints\"] as ScaleTable;\n const oldLevelData = data[oldLevel + 1];\n const newLevelData = data[newLevel + 1];\n\n // try to find an exact match\n let bestMatch: { key: string; percentile: number; delta: number } = {\n key: \"undefined\",\n percentile: 0,\n delta: Number.MAX_SAFE_INTEGER,\n };\n for (const entry of Object.entries(oldLevelData)) {\n const key = entry[0];\n if (key === \"level\") {\n continue;\n }\n\n const entryValue = entry[1] as { die: number; maximum: number; minimum: number };\n const { minimum, maximum } = entryValue;\n const range = maximum - minimum;\n const percentile = (oldValue - minimum) / range;\n const dMin = Math.abs(oldValue - minimum);\n const dMax = Math.abs(oldValue - maximum);\n const delta = Math.min(dMin, dMax);\n\n if (oldValue > minimum && oldValue < maximum) {\n bestMatch = {\n key,\n percentile,\n delta,\n };\n break;\n } else {\n if (delta < bestMatch.delta) {\n bestMatch = {\n key,\n percentile,\n delta,\n };\n }\n }\n }\n\n const newValue = newLevelData[bestMatch.key] as { minimum: number; maximum: number };\n return Math.round(newValue.minimum + (newValue.maximum - newValue.minimum) * bestMatch.percentile);\n}\n\nexport function getMinMaxData(\n key: \"resistance\" | \"weakness\",\n oldValue: number,\n oldLevel: number,\n newLevel: number,\n): number {\n const data = SCALE_APP_DATA[key] as { level: number; maximum: number; minimum: number }[];\n const oldLevelData = data[oldLevel + 1];\n const newLevelData = data[newLevel + 1];\n\n const oldRange = Math.abs(oldLevelData.maximum - oldLevelData.minimum);\n const oldPercentile = (oldValue - oldLevelData.minimum) / oldRange;\n\n const newRange = Math.abs(newLevelData.maximum - newLevelData.minimum);\n return Math.round(newLevelData.minimum + newRange * oldPercentile);\n}\n\nexport function constructRelativeDamage(oldDmg: IDicePool, stdDmg: IDicePool, newDmg: IDicePool): IDicePool {\n const count = newDmg.diceCount;\n const size = newDmg.diceSize;\n const bonus = newDmg.bonus + oldDmg.bonus - stdDmg.bonus;\n\n return parseDamage(\n constructFormula({\n diceCount: count,\n diceSize: size,\n bonus,\n }),\n );\n}\n\nexport function getDamageData(oldValue: string, oldLevel: number, newLevel: number): string {\n const data = SCALE_APP_DATA[\"strikeDamage\"] as ScaleTable;\n const oldLevelData = data[oldLevel + 1];\n const newLevelData = data[newLevel + 1];\n const parsedOldValue = parseDamage(oldValue);\n\n let bestMatch: { key: string; delta: number } = { key: \"undefined\", delta: Number.MAX_SAFE_INTEGER };\n for (const entry of Object.entries(oldLevelData)) {\n const key = entry[0];\n if (key === \"level\") {\n continue;\n }\n\n const value = entry[1] as IDicePool;\n const delta = Math.abs(value.average - parsedOldValue.average);\n\n if (delta < bestMatch.delta) {\n bestMatch = {\n key,\n delta,\n };\n }\n }\n\n if (bestMatch.delta < parsedOldValue.average * 0.5) {\n return constructRelativeDamage(\n parsedOldValue,\n oldLevelData[bestMatch.key] as IDicePool,\n newLevelData[bestMatch.key] as IDicePool,\n ).original;\n } else {\n return oldValue;\n }\n}\n\nexport function getAreaDamageData(oldValue: string, oldLevel: number, newLevel: number): string {\n const data = SCALE_APP_DATA[\"areaDamage\"] as ScaleTable;\n const oldLevelData = data[oldLevel + 1];\n const newLevelData = data[newLevel + 1];\n const parsedOldValue = parseDamage(oldValue);\n\n let bestMatch: { key: string; delta: number } = { key: \"undefined\", delta: Number.MAX_SAFE_INTEGER };\n for (const entry of Object.entries(oldLevelData)) {\n const key = entry[0];\n if (key === \"level\") {\n continue;\n }\n\n const value = entry[1] as IDicePool;\n const delta = Math.abs(value.average - parsedOldValue.average);\n\n if (delta < bestMatch.delta) {\n bestMatch = {\n key,\n delta,\n };\n }\n }\n\n if (bestMatch.delta < parsedOldValue.average * 0.5) {\n return constructRelativeDamage(\n parsedOldValue,\n oldLevelData[bestMatch.key] as IDicePool,\n newLevelData[bestMatch.key] as IDicePool,\n ).original;\n } else {\n return oldValue;\n }\n}\n","/*\n * Copyright 2021 Andrew Cuccinello, 2022 Jonas Karlsson\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { IDataUpdates, IHandledItemType } from \"./NPCScalerTypes.ts\";\nimport { getActor, getFolder, getFolderInFolder } from \"./Utilities.ts\";\nimport { getAreaDamageData, getDamageData, getHPData, getLeveledData, getMinMaxData } from \"./NPCScalerUtil.ts\";\nimport { ItemPF2e, NPCPF2e, NPCSystemData } from \"foundry-pf2e\";\nimport { logDebug } from \"../../utils/logging.ts\";\n\n/**\n * Scales an NPC to a specified level based on an actor ID.\n *\n * @param {string} actorId - The ID of the actor.\n * @param {number} newLevel - The new level to scale the NPC to.\n * @return {Promise} A promise that resolves when the scaling is complete.\n */\nexport async function scaleNPCToLevelFromActor(actorId: string, newLevel: number): Promise {\n const actor = (game.actors.get(actorId));\n if (actor) {\n await scaleNPCToLevel(actor, newLevel);\n }\n}\n\nfunction extractLabel(label: string) {\n const match = label.match(/^(.*?)(?:\\s+\\d+)?$/);\n return match ? match[1] : label;\n}\n\nexport async function scaleNPCToLevel(actor: NPCPF2e, newLevel: number): Promise {\n const rootFolder = getFolder(\"cr-scaler\");\n\n const folderName = `Level ${newLevel}`;\n const folder =\n getFolderInFolder(folderName, rootFolder?.name as string) ??\n ((await Folder.create({\n name: folderName,\n type: \"Actor\",\n parent: rootFolder ? rootFolder.id : \"\",\n })) as Folder);\n\n const system: NPCSystemData = actor.system;\n const oldLevel = system.details.level.value;\n const updateData: Record = {\n folder: folder.id,\n [\"system.details.level.value\"]: newLevel,\n };\n\n // parse attribute modifiers\n for (const [key, attr] of Object.entries(system.abilities)) {\n const skillAttr = attr as unknown as { mod: string };\n const mod = getLeveledData(\"abilityScore\", parseInt(skillAttr.mod), oldLevel, newLevel).total;\n const value = 10 + mod * 2;\n const min = 3;\n\n updateData[`system.abilities.${key}`] = { value, min, mod };\n }\n\n // parse resistances\n const drData: unknown[] = [];\n const resistances = (system.attributes as unknown as { resistances: unknown[] }).resistances;\n for (let i = 0; i < resistances.length; i++) {\n const resistance = resistances[i] as unknown as {\n label: string;\n type: string;\n exceptions?: string;\n value: number;\n doubleVs?: string;\n };\n\n drData.push({\n label: extractLabel(resistance.label),\n type: resistance.type,\n exceptions: resistance.exceptions ?? \"\",\n value: getMinMaxData(\"resistance\", resistance.value, oldLevel, newLevel),\n doubleVs: resistance.doubleVs ?? \"\",\n });\n }\n updateData[\"system.attributes.resistances\"] = drData;\n\n // parse weaknesses\n const dvData: unknown[] = [];\n const weaknesses = system.attributes.weaknesses;\n for (let i = 0; i < weaknesses.length; i++) {\n const weakness = weaknesses[i] as unknown as {\n label: string;\n type: string;\n exceptions?: string[];\n value: number;\n };\n\n dvData.push({\n label: extractLabel(weakness.label),\n type: weakness.type,\n exceptions: weakness.exceptions ?? [],\n value: getMinMaxData(\"weakness\", weakness.value, oldLevel, newLevel),\n });\n }\n updateData[\"system.attributes.weaknesses\"] = dvData;\n\n // parse simple modifiers\n updateData[\"system.attributes.ac.value\"] = getLeveledData(\n \"armorClass\",\n system.attributes.ac?.value ?? 0,\n oldLevel,\n newLevel,\n ).total;\n updateData[\"system.perception.mod\"] = getLeveledData(\n \"perception\",\n system.perception.mod ?? 0,\n oldLevel,\n newLevel,\n ).total;\n updateData[\"system.saves.fortitude.value\"] = getLeveledData(\n \"savingThrow\",\n system.saves.fortitude.value ?? 0,\n oldLevel,\n newLevel,\n ).total;\n updateData[\"system.saves.reflex.value\"] = getLeveledData(\n \"savingThrow\",\n system.saves.reflex.value ?? 0,\n oldLevel,\n newLevel,\n ).total;\n updateData[\"system.saves.will.value\"] = getLeveledData(\n \"savingThrow\",\n system.saves.will.value ?? 0,\n oldLevel,\n newLevel,\n ).total;\n\n const hp = getHPData(system.attributes.hp?.value ?? 0, oldLevel, newLevel);\n updateData[\"system.attributes.hp.max\"] = hp;\n updateData[\"system.attributes.hp.value\"] = hp;\n\n for (const [key, attr] of Object.entries(system.skills).filter(([, attr]) => attr.base > 0)) {\n const skillAttr = attr as unknown as { mod: string; value: string; base: string };\n const mod = getLeveledData(\"skill\", parseInt(skillAttr.mod), oldLevel, newLevel).total;\n const value = getLeveledData(\"skill\", parseInt(skillAttr.value), oldLevel, newLevel).total;\n const base = getLeveledData(\"skill\", parseInt(skillAttr.base), oldLevel, newLevel).total;\n\n updateData[`system.skills.${key}`] = { ...{ ...attr, mod: mod, value: value, base: base } };\n }\n\n let itemUpdates: IDataUpdates[] = [];\n const items = actor.items as Collection;\n for (const itemId of items.keys()) {\n const item = items.get(itemId) as ItemPF2e;\n\n if ((item.type as IHandledItemType) === \"spellcastingEntry\") {\n const oldAttack = parseInt((item.system as unknown as { spelldc: { value: string } }).spelldc.value);\n const newAttack = getLeveledData(\"spell\", oldAttack, oldLevel, newLevel).total;\n\n const oldDC = parseInt((item.system as unknown as { spelldc: { dc: string } }).spelldc.dc);\n const newDC = getLeveledData(\"difficultyClass\", oldDC, oldLevel, newLevel).total;\n\n itemUpdates.push({\n _id: item.id,\n [\"system.spelldc.value\"]: newAttack,\n [\"system.spelldc.dc\"]: newDC,\n });\n } else if ((item.type as IHandledItemType) === \"melee\") {\n const oldAttack = parseInt((item.system as unknown as { bonus: { value: string } }).bonus.value);\n const newAttack = getLeveledData(\"spell\", oldAttack, oldLevel, newLevel).total;\n\n const attackUpdate: IDataUpdates = {\n _id: item.id,\n [\"system.bonus.value\"]: newAttack,\n [\"system.bonus.total\"]: newAttack,\n };\n\n const damage = (item.system as unknown as { damageRolls: unknown }).damageRolls as\n { damage: string; damageType: string }[] | Record;\n\n if (Array.isArray(damage)) {\n for (let i = 0; i < damage.length; i++) {\n attackUpdate[`system.damageRolls.${i}.damage`] = getDamageData(\n damage[i].damage,\n oldLevel,\n newLevel,\n );\n attackUpdate[`system.damageRolls.${i}.damageType`] = damage[i].damageType;\n }\n } else {\n // Fix for #2 - some actors contain key/value pairs instead of array elements\n for (const key in damage) {\n attackUpdate[`system.damageRolls.${key}.damage`] = getDamageData(\n damage[key].damage,\n oldLevel,\n newLevel,\n );\n attackUpdate[`system.damageRolls.${key}.damageType`] = damage[key].damageType;\n }\n }\n\n itemUpdates.push(attackUpdate);\n }\n }\n logDebug(itemUpdates);\n\n let newActor = getActor(actor.name, folder.name);\n if (newActor !== undefined) {\n await newActor.update(updateData);\n } else {\n newActor = (await Actor.create(actor.clone(updateData)._source)) as typeof actor;\n }\n\n await newActor.updateEmbeddedDocuments(\"Item\", itemUpdates);\n\n itemUpdates = [];\n const DC_REGEXES = [/(data-pf2-dc=\")(\\d+)(\")/g, /(@Check\\[.*?type:.*?|dc:)(\\d+)(.*?])/g];\n for (let regexNo = 0; regexNo < DC_REGEXES.length; regexNo++) {\n const regex = DC_REGEXES[regexNo];\n for (const item of items\n .filter(\n (item) => item.system.description.value.includes(\"DC\") || item.system.description.value.includes(\"dc:\"),\n )\n .filter(\n (item) =>\n !((\n Array.of(\"consumable\", \"armor\", \"backpack\", \"book\", \"equipment\", \"treasure\", \"weapon\")\n )).includes(item.type),\n ) //\n .filter((item) => !item.system.description.value.includes(\"type:flat\"))) {\n const description = item.system.description.value;\n let newDescription = description;\n let match: RegExpExecArray | null = regex.exec(description);\n\n let indexOffset = 0;\n while (match !== null) {\n const fullMatch = match[0];\n let value: string;\n if (regexNo === 0) {\n value = match[1];\n } else {\n value = match[2];\n }\n const index = match.index + indexOffset;\n const newDCValue = getLeveledData(\"difficultyClass\", parseInt(value), oldLevel, newLevel).total;\n const newDCString = `${match[1]}${newDCValue}${match[3]}`;\n\n newDescription =\n newDescription.substring(0, index) +\n newDCString +\n newDescription.substring(index + fullMatch.length);\n\n indexOffset += newDescription.length - description.length - indexOffset;\n\n match = regex.exec(description);\n }\n\n itemUpdates.push({\n _id: item.id,\n [\"system.description.value\"]: newDescription,\n });\n }\n }\n\n await newActor.updateEmbeddedDocuments(\"Item\", itemUpdates);\n\n itemUpdates = [];\n // Ignore spell damage, that will have to be handled manually\n for (const item of newActor.items.filter((item) => !item.isOfType(\"spell\")).values()) {\n const DMG_REGEX = /\\d+d\\d+(\\+\\d*)?/g;\n const description = item.system[\"description\"].value as string;\n let newDescription = description;\n let match: RegExpExecArray | null = DMG_REGEX.exec(description);\n let indexOffset = 0;\n while (match !== null) {\n const [fullMatch] = match;\n const index = match.index + indexOffset;\n const newDamageFormula = getAreaDamageData(fullMatch, oldLevel, newLevel);\n\n newDescription =\n newDescription.substring(0, index) +\n newDamageFormula +\n newDescription.substring(index + fullMatch.length);\n\n indexOffset += newDescription.length - description.length - indexOffset;\n\n match = DMG_REGEX.exec(description);\n }\n\n itemUpdates.push({\n _id: item.id as string,\n [\"system.description.value\"]: newDescription,\n });\n }\n\n await newActor.updateEmbeddedDocuments(\"Item\", itemUpdates);\n}\n","function e(e,t,n){let r=n=>e(n,...t);return n===void 0?r:Object.assign(r,{lazy:n,lazyArgs:t})}export{e as t};\n//# sourceMappingURL=lazyDataLastImpl--3B10z3s.js.map","import{t as e}from\"./lazyDataLastImpl--3B10z3s.js\";function t(t,n,r){let i=t.length-n.length;if(i===0)return t(...n);if(i===1)return e(t,n,r);throw Error(`Wrong number of arguments`)}export{t as purry};\n//# sourceMappingURL=purry.js.map","import{purry as e}from\"./purry.js\";function t(...t){return e(n,t)}function n(e,t){let n={};for(let r of t)r in e&&(n[r]=e[r]);return n}export{t as pick};\n//# sourceMappingURL=pick.js.map","import type {\n AbilityTrait,\n Action,\n ActionMessageOptions,\n ActionUseOptions,\n ActionVariant,\n ActorPF2e,\n ChatMessagePF2e,\n ChoiceSetSource,\n EffectPF2e,\n EffectSource,\n PickableThing,\n RawPredicate,\n RuleElementSource,\n} from \"foundry-pf2e\";\nimport { ItemUUID } from \"foundry/common/documents/_module.mts\";\nimport { MODULENAME } from \"../../constants.ts\";\nimport * as systems from \"../../utils/systems.ts\";\n\n// IDK why choices isn't in ChoiceSetSource\ninterface ChoiceSetSourceWithChoices extends ChoiceSetSource {\n // Maybe this should have been UninflatedChoiceSet as the type, but that has issues,\n // see below.\n choices: PickableThingSource[];\n}\n\n// UninflatedChoiceSet can be PickableThing[], but PickableThing contains a Predicate.\n// We don't have a Predciate in the rule source, we have a RawPredicate. There doesn't\n// seem to be an existing type for the source of a choice.\ntype PickableThingSource = Omit & { predicate?: RawPredicate; sort?: number };\n\ninterface FTEFlags {\n minimum?: number;\n bonus?: {\n untrained?: number;\n trained?: number;\n expert?: number;\n master?: number;\n legendary?: number;\n };\n}\n\nclass FollowTheExpertAction implements Action {\n readonly img: string;\n readonly name: string;\n readonly slug: string;\n readonly traits: AbilityTrait[];\n // variants is required for the interface, but this action has no variants.\n // Since nothing in this module uses them, an empty collection satifies the\n // requirements with the least code.\n readonly variants: Collection;\n\n readonly effect: ItemUUID;\n\n public constructor() {\n this.img = `systems/${game.system.id}/icons/spells/favorable-review.webp`;\n this.name = `${MODULENAME}.macros.basicActionMacros.actions.FollowTheExpertToggle`;\n this.slug = \"follow-the-expert\";\n this.traits = [\"exploration\"];\n this.variants = new Collection();\n this.effect = \"Compendium.pf2e.other-effects.VCSpuc3Tf3XWMkd3\" as ItemUUID; // Effect: Follow The Expert\n }\n\n async use(_options?: Partial): Promise {\n const source = (await fromUuid(this.effect)) as EffectPF2e | null;\n if (!source) throw new Error(`Effect ${this.effect} not found!`);\n const effect = source.toObject();\n (effect.flags.core ??= {}).sourceId = this.effect;\n\n const actors = canvas.tokens.controlled.flatMap((token) => token.actor ?? []);\n if (actors.length === 0 && game.user.character) actors.push(game.user.character);\n if (actors.length === 0) {\n return ui.notifications.error(\"PF2E.ErrorMessage.NoTokenSelected\", { localize: true });\n }\n\n const target = game.user.targets.first();\n if (target?.actor) {\n this.fixupRules(effect, target.actor);\n }\n\n for (const actor of actors) {\n const existing = actor.itemTypes.effect.find((e) => e.flags.core?.sourceId === this.effect);\n if (existing) {\n await existing.delete();\n } else {\n await actor.createEmbeddedDocuments(\"Item\", [effect]);\n }\n }\n\n // SimpleAction would return a list of [actor, effect, message] tuples,\n // but nothing will use it, so it's not done here.\n return true;\n }\n\n async toMessage(_options?: Partial): Promise {\n // There isn't a message for toggling an effect. Could be added.\n return undefined;\n }\n\n private fixupRules(effect: EffectSource, expert: ActorPF2e) {\n const expertSkills = expert.skills;\n // Skilless expert? Don't follow them! Typescript complains.\n if (!expertSkills) return;\n\n const flags = systems.getFlag(expert, \"followTheExpert\") as FTEFlags | undefined;\n // List of Lores that meet FTE minimum proficiency\n const minLevel = flags?.minimum ?? 2;\n const lores = Object.values(expertSkills)\n .filter((s) => s.lore && (s.rank ?? 0) >= minLevel)\n .map((s) => ({ label: s.label, value: s.slug }));\n\n const skillRule = effect.system.rules.find(\n (e: ChoiceSetSource) => e.key === \"ChoiceSet\" && e.flag === \"followTheExpertSkill\",\n ) as ChoiceSetSourceWithChoices | null;\n const profRule = effect.system.rules.find(\n (e: ChoiceSetSource) => e.key === \"ChoiceSet\" && e.flag === \"followTheExpertProficiency\",\n ) as ChoiceSetSourceWithChoices | null;\n if (!skillRule || !profRule) throw new Error(\"Effect: FTE did not have expected rules\");\n\n // Add choice for trained if necessary\n if (minLevel <= 1) profRule.choices.push({ label: \"PF2E.ProficiencyLevel1\", sort: 0, value: 1 });\n\n // Filter skill choices that don't meet FTE minimum proficiency, default 2 (expert), and add lores\n skillRule.choices = skillRule.choices\n .filter((c) => (expertSkills[c.value as string]?.rank ?? 0) >= minLevel)\n .concat(lores);\n\n // Make proficiency choices predicate on having chosen a skill with that proficiency.\n // This should result in only one choice being allowed, thus skipping the dialog.\n const skills = skillRule.choices.map((c) => c.value) as string[];\n for (const choice of profRule.choices) {\n const skillsAtLevel = skills.filter((s) => expertSkills[s].rank === choice.value);\n if (skillsAtLevel.length > 0) {\n choice.predicate = [\n {\n or: skillsAtLevel.map((s) => ({\n eq: [\"{item|flags.pf2e.rulesSelections.followTheExpertSkill}\", s],\n })),\n },\n ];\n } else {\n choice.predicate = [\"disabled\"];\n }\n }\n\n // Adjust the modifier if the target has something that changes it\n if (flags?.bonus) {\n const rankSlugs = Object.keys(CONFIG.PF2E.proficiencyRanks);\n effect.system.rules.push({\n key: \"AdjustModifier\",\n mode: \"upgrade\",\n slug: \"follow-the-expert-circumstance\",\n selector: \"{item|flags.pf2e.rulesSelections.followTheExpertSkill}\",\n value: {\n brackets: rankSlugs\n .map((r, i) => ({\n start: i,\n end: i,\n value: (flags.bonus as Record)?.[r],\n }))\n .filter((b) => b.value !== undefined),\n field: \"item|flags.pf2e.rulesSelections.followTheExpertProficiency\",\n },\n } as RuleElementSource);\n }\n }\n}\n\nlet followTheExpert: FollowTheExpertAction;\n// Break module initialization order issue w.r.t. MODULENAME from xdy-pf2e-workbench.js\nHooks.once(\"setup\", () => {\n followTheExpert = new FollowTheExpertAction();\n});\n\nexport { followTheExpert };\n","// Originally from ApoApostolov#4622, modified by me. Included with permission.\n// noinspection CssUnresolvedCustomProperty,CssUnknownTarget\n\nimport * as R from \"remeda\";\nimport { MODULENAME } from \"../../constants.ts\";\nimport type { MacroPF2e, SkillSlug } from \"foundry-pf2e\";\nimport {\n AbilityTrait,\n Action,\n ActionUseOptions,\n ActionVariant,\n ActorPF2e,\n SingleCheckAction,\n Statistic,\n} from \"foundry-pf2e\";\nimport { followTheExpert } from \"./follow-the-expert.ts\";\nimport * as systems from \"../../utils/systems.ts\";\nimport { actorHasItemBySlug, getModuleSetting } from \"../../utils.ts\";\n\ntype DialogV2 = foundry.applications.api.DialogV2;\n\ndeclare global {\n interface Window {\n actionDialog: DialogV2;\n }\n}\n\n// PF2e system uses this for statistic slugs but doesn't make it a type\ntype StatisticSlug = SkillSlug | \"perception\";\n\n// Since SingleCheckAction is only exported as a type we can't just use instanceof\n// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\nfunction isSingleCheckAction(action: Action | Function | ActionVariant): action is SingleCheckAction {\n return foundry.utils.hasProperty(action, \"preview\");\n}\n\nexport async function registerBasicActionMacrosHandlebarsTemplates(): Promise {\n await foundry.applications.handlebars.loadTemplates([\n `modules/${MODULENAME}/templates/macros/bam/index.hbs`,\n `modules/${MODULENAME}/templates/macros/bam/actionButton.hbs`,\n ]);\n\n Handlebars.registerPartial(\"actionButton\", `{{> \"modules/${MODULENAME}/templates/macros/bam/actionButton.hbs\"}}`);\n}\n\nfunction getBestBonuses(\n actorSkills: Map>>,\n party: string[],\n actionList: MacroAction[],\n) {\n for (const actorId of party) {\n const skills = actorSkills.get(actorId);\n for (const action of actionList) {\n const skill = skills?.[action.skill as StatisticSlug];\n if (!skill) continue;\n const bonus = skill.check?.mod ?? skill.mod;\n if (bonus > (action.best ?? -1)) {\n action.best = bonus;\n action.whoIsBest = actorId;\n }\n }\n }\n}\n\nfunction createMapOfSkillsPerActor(actors: ActorPF2e[]): Map>> {\n const map = new Map>>();\n for (const actor of actors) {\n const skills = fetchSkills(actor);\n if (skills) {\n map.set(actor.id, skills);\n }\n }\n return map;\n}\n\nfunction fetchSkills(actor: ActorPF2e): Partial> {\n return { perception: actor.perception, ...actor.skills };\n}\n\ntype ButtonData = {\n action: MacroAction;\n rank: number;\n bonus?: number;\n best: boolean;\n idx: number;\n};\n\nfunction createButtonData(\n action: MacroAction,\n idx: number,\n actor: ActorPF2e,\n party: string[],\n actorSkills: Partial>,\n): ButtonData {\n const skill: Statistic | undefined = actorSkills[action.skill as StatisticSlug];\n const rank: number = skill?.rank ?? (skill?.proficient ? 1 : 0);\n const bonus = action.bonus ?? skill?.mod;\n const best =\n getModuleSetting(\"basicActionMacroShowBestBonus\") &&\n party.includes(actor.id) &&\n (bonus ?? -100) >= (action.best ?? 0);\n return { best, idx, action, rank, bonus };\n}\n\ntype MacroAction = {\n // These are supplied for each supported action\n actionType: \"basic\" | \"skill_untrained\" | \"skill_trained\" | \"other\";\n // Skill name or blank for non-skill actions\n skill: StatisticSlug | \"\";\n // The altSkillAndFeat stuff should really be more flexible. Maybe look at what SkillActions did for prereqs?\n altSkillAndFeat?: { skill: StatisticSlug; feat: string }[];\n // Localized name to appear in menu\n name: string;\n // Path to icon\n icon: string;\n // Object to use when action is selected\n // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\n action: Function | Action | ActionVariant | undefined;\n // Optional parameters for an Action.use() call for Action or ActionVariant type actions\n options?: Partial;\n // Module needed for action to be present (external macros)\n module?: string;\n // Feat needed to for action to be present\n feat?: string;\n\n // These are all filled in based on the action and actor data\n best?: number;\n whoIsBest?: string;\n showMAP?: boolean;\n showExploration?: boolean;\n showDowntime?: boolean;\n MAP?: [number, number];\n bonus?: number;\n};\n\n/**\n * Generates the filtered list of actions to use based on the given bamActions.\n *\n * @param {ActorPF2e} selectedActor The selected actor.\n * @param {MacroAction[]} bamActions - The list of MacroActions to filter.\n * @return {MacroAction[]} The filtered list of actions to use.\n */\nfunction prepareActions(selectedActor: ActorPF2e, bamActions: MacroAction[]): MacroAction[] {\n const showUnusable = getModuleSetting(\"bamShowUnusable\");\n const cleverImproviser = actorHasItemBySlug(selectedActor, \"clever-improviser\");\n const getSkill = (skill: StatisticSlug): Statistic | undefined =>\n skill === \"perception\" ? selectedActor.perception : selectedActor.skills?.[skill];\n const proficient = (skill: StatisticSlug | \"\"): boolean =>\n skill === \"\" ? true : (getSkill(skill)?.proficient ?? false);\n\n const actionsToUse = bamActions.filter((x) => {\n if (x.module && !game.modules.get(x.module)?.active) return false;\n if (x.feat && !actorHasItemBySlug(selectedActor, x.feat)) return false;\n\n // Has the skill, or an alt skill if any\n const hasSkill =\n proficient(x.skill) ||\n x.altSkillAndFeat?.some((y) => proficient(y.skill) && actorHasItemBySlug(selectedActor, y.feat));\n\n return (\n x.actionType !== \"skill_trained\" ||\n showUnusable ||\n hasSkill ||\n cleverImproviser ||\n selectedActor.type === \"familiar\"\n );\n });\n\n actionsToUse.forEach((x) => {\n const action = x.action;\n if (x.skill === \"\" && action && isSingleCheckAction(action)) {\n const skillUsed = action\n .preview({ actor: selectedActor })\n .reduce((highest, current) =>\n (highest?.modifier ?? -100) > (current.modifier ?? 0) ? highest : current,\n );\n x.bonus = skillUsed.modifier;\n x.skill = skillUsed.slug as StatisticSlug;\n x.name += ` (${skillUsed.label})`;\n }\n\n const traits = x.action && typeof x.action === \"object\" && \"traits\" in x.action ? x.action.traits : [];\n x.showMAP = traits.includes(\"attack\");\n x.showDowntime = traits.includes(\"downtime\");\n x.showExploration = traits.includes(\"exploration\");\n if (x.showMAP) {\n x.MAP = [-5, -10];\n if (x.skill === \"athletics\")\n actionsToUse.push({\n ...x,\n name: `${x.name} (${game.i18n.localize(\"PF2E.TraitAgile\")})`,\n MAP: [-4, -8],\n });\n }\n });\n\n return actionsToUse.sort((a, b) => a.name.localeCompare(b.name, game.i18n.lang));\n}\n\n// Class to wrap a macro into an object that supports the ActionVariant\n// interface, which is what most of the system actions use.\nclass MacroActionVariant implements ActionVariant {\n readonly traits: AbilityTrait[] = [];\n readonly #macro: string;\n readonly #compendium: string;\n\n constructor(macro: string, compendiumId: string) {\n this.#macro = macro;\n if (compendiumId.startsWith(\"xdy-pf2e-workbench.\")) {\n const packBaseName = compendiumId.replace(\"xdy-pf2e-workbench.\", \"\");\n this.#compendium = systems.getModulePackId(packBaseName);\n } else {\n this.#compendium = compendiumId;\n }\n }\n\n get slug() {\n return this.#macro.slugify();\n }\n\n async use(options: ActionUseOptions): Promise {\n const pack = game.packs.get(this.#compendium);\n if (pack) {\n const macros = (await pack.getDocuments({ name: this.#macro })) as MacroPF2e[];\n if (macros.length > 0) {\n await macros[0].execute(R.pick(options, [\"event\"]));\n } else {\n ui.notifications.error(\n game.i18n.format(`${MODULENAME}.macros.basicActionMacros.macroNotFound`, {\n macroName: this.#macro,\n }),\n );\n }\n } else {\n ui.notifications.error(\n game.i18n.format(`${MODULENAME}.macros.basicActionMacros.compendiumNotFound`, {\n compendiumName: this.#compendium,\n }),\n );\n }\n }\n\n async toMessage(): Promise {\n // Required by interface, but not used by this module\n }\n}\n\n/**\n * This macro opens a dialog containing a list of actions to be used by the selected Actor\n * If no actor is selected, it selects the user's standard character.\n * If there is no user character, it shows up a warning notification.\n */\nexport async function basicActionMacros(): Promise {\n const bamActions: MacroAction[] = [\n {\n actionType: \"skill_untrained\",\n name: game.i18n.localize(`${MODULENAME}.macros.basicActionMacros.actions.AdministerFirstAidStabilize`),\n skill: \"medicine\",\n action: game.pf2e.actions.get(\"administer-first-aid\")?.variants.get(\"stabilize\"),\n icon: `systems/${game.system.id}/icons/features/feats/treat-wounds.webp`,\n },\n {\n actionType: \"skill_untrained\",\n name: game.i18n.localize(`${MODULENAME}.macros.basicActionMacros.actions.AdministerFirstAidStopBleeding`),\n skill: \"medicine\",\n action: game.pf2e.actions.get(\"administer-first-aid\")?.variants.get(\"stop-bleeding\"),\n icon: `systems/${game.system.id}/icons/conditions/persistent-damage.webp`,\n },\n {\n actionType: \"other\",\n name: game.i18n.localize(`${MODULENAME}.macros.basicActionMacros.actions.AidToggle`),\n skill: \"\",\n action: new MacroActionVariant(\"macroEffectAid\", \"xdy-pf2e-workbench.xdy-internal-utility-macros\"),\n icon: `systems/${game.system.id}/icons/spells/efficient-apport.webp`,\n },\n {\n actionType: \"other\",\n name: game.i18n.localize(`${MODULENAME}.macros.basicActionMacros.actions.AidASE`),\n skill: \"\",\n action: new MacroActionVariant(\"Aid\", \"pf2e-action-support-engine-macros.action-support-engine-macros\"),\n module: \"pf2e-action-support-engine\",\n icon: `systems/${game.system.id}/icons/spells/efficient-apport.webp`,\n },\n {\n actionType: \"other\",\n name: game.i18n.localize(`${MODULENAME}.macros.basicActionMacros.actions.AidPF2eMacros`),\n skill: \"\",\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n action: (options: { actors: ActorPF2e[] }) => (game as any)[\"activemacros\"].aid(options.actors?.[0]),\n module: \"pf2e-macros\",\n icon: `systems/${game.system.id}/icons/spells/efficient-apport.webp`,\n },\n {\n actionType: \"other\",\n name: game.i18n.localize(`${MODULENAME}.macros.basicActionMacros.actions.AvoidNotice`),\n skill: \"stealth\",\n action: game.pf2e.actions.get(\"avoid-notice\"),\n icon: `systems/${game.system.id}/icons/features/classes/surprice-attack.webp`,\n },\n {\n actionType: \"skill_untrained\",\n name: game.i18n.localize(`${MODULENAME}.macros.basicActionMacros.actions.Balance`),\n skill: \"acrobatics\",\n action: game.pf2e.actions.get(\"balance\"),\n icon: \"icons/skills/movement/feet-winged-boots-brown.webp\",\n },\n {\n actionType: \"skill_untrained\",\n name: game.i18n.localize(`${MODULENAME}.macros.basicActionMacros.actions.Climb`),\n skill: \"athletics\",\n action: game.pf2e.actions.get(\"climb\"),\n icon: \"icons/sundries/misc/ladder.webp\",\n },\n {\n actionType: \"skill_untrained\",\n name: game.i18n.localize(`${MODULENAME}.macros.basicActionMacros.actions.Coerce`),\n skill: \"intimidation\",\n action: game.pf2e.actions.get(\"coerce\"),\n icon: \"icons/skills/social/intimidation-impressing.webp\",\n },\n {\n actionType: \"skill_untrained\",\n name: game.i18n.localize(`${MODULENAME}.macros.basicActionMacros.actions.CommandAnAnimal`),\n skill: \"nature\",\n action: game.pf2e.actions.get(\"command-an-animal\"),\n icon: \"icons/environment/creatures/horse-white.webp\",\n },\n {\n actionType: \"skill_untrained\",\n name: game.i18n.localize(`${MODULENAME}.macros.basicActionMacros.actions.ConcealAnObject`),\n skill: \"stealth\",\n action: game.pf2e.actions.get(\"conceal-an-object\"),\n icon: `systems/${game.system.id}/icons/equipment/adventuring-gear/wax-key-blank.webp`,\n },\n {\n actionType: \"skill_trained\",\n name: game.i18n.localize(`${MODULENAME}.macros.basicActionMacros.actions.Craft`),\n skill: \"crafting\",\n action: game.pf2e.actions.craft,\n icon: \"icons/skills/trades/smithing-anvil-silver-red.webp\",\n },\n {\n actionType: \"skill_trained\",\n name: game.i18n.localize(`${MODULENAME}.macros.basicActionMacros.actions.CreateForgery`),\n skill: \"society\",\n action: game.pf2e.actions.get(\"create-forgery\"),\n icon: `systems/${game.system.id}/icons/spells/transcribe-moment.webp`,\n },\n {\n actionType: \"skill_untrained\",\n name: game.i18n.localize(`${MODULENAME}.macros.basicActionMacros.actions.CreateADiversionDistractingWords`),\n skill: \"deception\",\n action: game.pf2e.actions.get(\"create-a-diversion\")?.variants.get(\"distracting-words\"),\n icon: \"icons/skills/social/wave-halt-stop.webp\",\n },\n {\n actionType: \"skill_untrained\",\n name: game.i18n.localize(`${MODULENAME}.macros.basicActionMacros.actions.CreateADiversionGesture`),\n skill: \"deception\",\n action: game.pf2e.actions.get(\"create-a-diversion\")?.variants.get(\"gesture\"),\n icon: \"icons/skills/social/wave-halt-stop.webp\",\n },\n {\n actionType: \"skill_untrained\",\n name: game.i18n.localize(`${MODULENAME}.macros.basicActionMacros.actions.CreateADiversionTrick`),\n skill: \"deception\",\n action: game.pf2e.actions.get(\"create-a-diversion\")?.variants.get(\"trick\"),\n icon: `systems/${game.system.id}/icons/spells/charming-words.webp`,\n },\n {\n actionType: \"skill_trained\",\n name: game.i18n.localize(`${MODULENAME}.macros.basicActionMacros.actions.DecipherWritingArcana`),\n skill: \"arcana\",\n action: game.pf2e.actions.get(\"decipher-writing\"),\n options: { statistic: \"arcana\" },\n icon: \"icons/skills/trades/academics-book-study-runes.webp\",\n },\n {\n actionType: \"skill_trained\",\n name: game.i18n.localize(`${MODULENAME}.macros.basicActionMacros.actions.DecipherWritingOccultism`),\n skill: \"occultism\",\n action: game.pf2e.actions.get(\"decipher-writing\"),\n options: { statistic: \"occultism\" },\n icon: \"icons/skills/trades/academics-book-study-purple.webp\",\n },\n {\n actionType: \"skill_trained\",\n name: game.i18n.localize(`${MODULENAME}.macros.basicActionMacros.actions.DecipherWritingReligion`),\n skill: \"religion\",\n action: game.pf2e.actions.get(\"decipher-writing\"),\n options: { statistic: \"religion\" },\n icon: `systems/${game.system.id}/icons/equipment/other/spellbooks/thresholds-of-truth.webp`,\n },\n {\n actionType: \"skill_trained\",\n name: game.i18n.localize(`${MODULENAME}.macros.basicActionMacros.actions.DecipherWritingSociety`),\n skill: \"society\",\n action: game.pf2e.actions.get(\"decipher-writing\"),\n options: { statistic: \"society\" },\n icon: \"icons/skills/trades/academics-study-reading-book.webp\",\n },\n {\n actionType: \"skill_untrained\",\n name: game.i18n.localize(`${MODULENAME}.macros.basicActionMacros.actions.Demoralize`),\n skill: \"intimidation\",\n action: new MacroActionVariant(\n \"XDY DO_NOT_IMPORT Demoralize\",\n \"xdy-pf2e-workbench.asymonous-benefactor-macros-internal\",\n ),\n icon: \"icons/skills/social/intimidation-impressing.webp\",\n },\n {\n actionType: \"skill_trained\",\n name: game.i18n.localize(`${MODULENAME}.macros.basicActionMacros.actions.Disarm`),\n skill: \"athletics\",\n action: game.pf2e.actions.get(\"disarm\"),\n icon: \"icons/skills/melee/sword-damaged-broken-glow-red.webp\",\n },\n {\n actionType: \"skill_trained\",\n name: game.i18n.localize(`${MODULENAME}.macros.basicActionMacros.actions.DisableDevice`),\n skill: \"thievery\",\n action: game.pf2e.actions.get(\"disable-device\"),\n icon: `systems/${game.system.id}/icons/equipment/adventuring-gear/thieves-tools.webp`,\n },\n {\n actionType: \"skill_untrained\",\n name: game.i18n.localize(`${MODULENAME}.macros.basicActionMacros.actions.Escape`),\n skill: \"\",\n action: game.pf2e.actions.get(\"escape\"),\n icon: \"icons/skills/movement/feet-winged-boots-glowing-yellow.webp\",\n },\n {\n actionType: \"skill_trained\",\n name: game.i18n.localize(`${MODULENAME}.macros.basicActionMacros.actions.Feint`),\n skill: \"deception\",\n action: game.pf2e.actions.get(\"feint\"),\n icon: \"icons/skills/melee/maneuver-sword-katana-yellow.webp\",\n },\n {\n actionType: \"other\",\n name: game.i18n.localize(`${MODULENAME}.macros.basicActionMacros.actions.FollowTheExpertToggle`),\n skill: \"\",\n action: followTheExpert,\n icon: `systems/${game.system.id}/icons/spells/favorable-review.webp`,\n },\n {\n actionType: \"skill_untrained\",\n name: game.i18n.localize(`${MODULENAME}.macros.basicActionMacros.actions.ForceOpen`),\n skill: \"athletics\",\n action: game.pf2e.actions.get(\"force-open\"),\n icon: \"icons/equipment/feet/boots-armored-steel.webp\",\n },\n {\n actionType: \"skill_untrained\",\n name: game.i18n.localize(`${MODULENAME}.macros.basicActionMacros.actions.GatherInformation`),\n skill: \"diplomacy\",\n action: game.pf2e.actions.get(\"gather-information\"),\n icon: \"icons/skills/social/diplomacy-handshake.webp\",\n },\n {\n actionType: \"skill_untrained\",\n name: game.i18n.localize(`${MODULENAME}.macros.basicActionMacros.actions.Grapple`),\n skill: \"athletics\",\n action: game.pf2e.actions.get(\"grapple\"),\n icon: \"icons/skills/melee/unarmed-punch-fist.webp\",\n },\n {\n actionType: \"skill_untrained\",\n name: game.i18n.localize(`${MODULENAME}.macros.basicActionMacros.actions.Hide`),\n skill: \"stealth\",\n action: game.pf2e.actions.get(\"hide\"),\n icon: `systems/${game.system.id}/icons/features/classes/wild.webp`,\n },\n {\n actionType: \"skill_untrained\",\n name: game.i18n.localize(`${MODULENAME}.macros.basicActionMacros.actions.Impersonate`),\n skill: \"deception\",\n action: game.pf2e.actions.get(\"impersonate\"),\n icon: \"icons/equipment/head/mask-carved-scream-tan.webp\",\n },\n {\n actionType: \"skill_untrained\",\n name: game.i18n.localize(`${MODULENAME}.macros.basicActionMacros.actions.JumpHigh`),\n skill: \"athletics\",\n action: game.pf2e.actions.get(\"high-jump\"),\n icon: \"icons/skills/movement/arrows-up-trio-red.webp\",\n },\n {\n actionType: \"skill_untrained\",\n name: game.i18n.localize(`${MODULENAME}.macros.basicActionMacros.actions.JumpLong`),\n skill: \"athletics\",\n action: game.pf2e.actions.get(\"long-jump\"),\n icon: \"icons/skills/movement/figure-running-gray.webp\",\n },\n {\n actionType: \"skill_untrained\",\n name: game.i18n.localize(`${MODULENAME}.macros.basicActionMacros.actions.Lie`),\n skill: \"deception\",\n action: game.pf2e.actions.get(\"lie\"),\n icon: \"icons/magic/control/mouth-smile-deception-purple.webp\",\n },\n {\n actionType: \"skill_untrained\",\n name: game.i18n.localize(`${MODULENAME}.macros.basicActionMacros.actions.MakeAnImpression`),\n skill: \"diplomacy\",\n action: game.pf2e.actions.get(\"make-an-impression\"),\n icon: \"icons/environment/people/commoner.webp\",\n },\n {\n actionType: \"skill_trained\",\n name:\n game.i18n.localize(`${MODULENAME}.macros.basicActionMacros.actions.MakeAnImpression`) +\n \" - \" +\n game.i18n.localize(\"PF2E.Skill.Performance\"),\n skill: \"performance\",\n action: game.pf2e.actions.get(\"make-an-impression\"),\n options: { statistic: \"performance\" },\n icon: \"icons/environment/people/commoner.webp\",\n feat: \"impressive-performance\",\n },\n {\n actionType: \"skill_trained\",\n name: game.i18n.localize(`${MODULENAME}.macros.basicActionMacros.actions.ManeuverInFlight`),\n skill: \"acrobatics\",\n action: game.pf2e.actions.get(\"maneuver-in-flight\"),\n icon: \"icons/commodities/biological/wing-bird-white.webp\",\n },\n {\n actionType: \"skill_untrained\",\n name: game.i18n.localize(`${MODULENAME}.macros.basicActionMacros.actions.PalmAnObject`),\n skill: \"thievery\",\n action: game.pf2e.actions.get(\"palm-an-object\"),\n icon: \"icons/sundries/gaming/playing-cards.webp\",\n },\n {\n actionType: \"skill_untrained\",\n name: game.i18n.localize(`${MODULENAME}.macros.basicActionMacros.actions.Perform`),\n skill: \"performance\",\n action: game.pf2e.actions.get(\"perform\")?.variants.get(\"singing\"),\n icon: \"icons/skills/trades/music-singing-voice-blue.webp\",\n },\n {\n actionType: \"skill_trained\",\n name: game.i18n.localize(`${MODULENAME}.macros.basicActionMacros.actions.PickALock`),\n skill: \"thievery\",\n action: game.pf2e.actions.get(\"pick-a-lock\"),\n icon: \"icons/skills/social/theft-pickpocket-bribery-brown.webp\",\n },\n {\n actionType: \"other\",\n name: game.i18n.localize(\"PF2E.Actions.PointOut.Title\"),\n skill: \"\",\n action: game.pf2e.actions.get(\"point-out\"),\n icon: `systems/${game.system.id}/icons/conditions/observed.webp`,\n },\n {\n actionType: \"other\",\n name: game.i18n.localize(`${MODULENAME}.macros.basicActionMacros.actions.RaiseAShieldToggle`),\n skill: \"\",\n action: game.pf2e.actions.raiseAShield,\n icon: `systems/${game.system.id}/icons/actions/raise-a-shield.webp`,\n },\n {\n actionType: \"skill_untrained\",\n name: game.i18n.localize(`${MODULENAME}.macros.basicActionMacros.actions.RecallKnowledge`),\n skill: \"\",\n action: new MacroActionVariant(\n \"XDY DO_NOT_IMPORT Recall_Knowledge\",\n \"xdy-pf2e-workbench.asymonous-benefactor-macros-internal\",\n ),\n icon: \"icons/skills/trades/academics-study-reading-book.webp\",\n },\n {\n actionType: \"skill_untrained\",\n name: game.i18n.localize(`${MODULENAME}.macros.basicActionMacros.actions.Repair`),\n skill: \"crafting\",\n action: game.pf2e.actions.repair,\n icon: \"icons/tools/smithing/anvil.webp\",\n },\n {\n actionType: \"skill_untrained\",\n name: game.i18n.localize(`${MODULENAME}.macros.basicActionMacros.actions.Reposition`),\n skill: \"athletics\",\n action: game.pf2e.actions.get(\"reposition\"),\n icon: \"icons/sundries/gaming/chess-pawn-white-pink.webp\",\n },\n {\n actionType: \"skill_untrained\",\n name: game.i18n.localize(`${MODULENAME}.macros.basicActionMacros.actions.Request`),\n skill: \"diplomacy\",\n action: game.pf2e.actions.get(\"request\"),\n icon: \"icons/skills/social/thumbsup-approval-like.webp\",\n },\n {\n actionType: \"basic\",\n name: game.i18n.localize(`${MODULENAME}.macros.basicActionMacros.actions.Seek`),\n skill: \"perception\",\n action: game.pf2e.actions.get(\"seek\"),\n icon: \"icons/tools/scribal/magnifying-glass.webp\",\n },\n {\n actionType: \"skill_untrained\",\n name: game.i18n.localize(`${MODULENAME}.macros.basicActionMacros.actions.SenseDirection`),\n skill: \"survival\",\n action: game.pf2e.actions.get(\"sense-direction\"),\n icon: \"icons/tools/navigation/compass-brass-blue-red.webp\",\n },\n {\n actionType: \"basic\",\n name: game.i18n.localize(`${MODULENAME}.macros.basicActionMacros.actions.SenseMotive`),\n skill: \"perception\",\n action: game.pf2e.actions.get(\"sense-motive\"),\n icon: \"icons/environment/people/commoner.webp\",\n },\n {\n actionType: \"skill_untrained\",\n name: game.i18n.localize(`${MODULENAME}.macros.basicActionMacros.actions.Shove`),\n skill: \"athletics\",\n action: game.pf2e.actions.get(\"shove\"),\n icon: `systems/${game.system.id}/icons/spells/hydraulic-push.webp`,\n },\n {\n actionType: \"skill_untrained\",\n name: game.i18n.localize(`${MODULENAME}.macros.basicActionMacros.actions.Sneak`),\n skill: \"stealth\",\n action: game.pf2e.actions.get(\"sneak\"),\n icon: `systems/${game.system.id}/icons/conditions/unnoticed.webp`,\n },\n {\n actionType: \"skill_trained\", // Technically not, but... See https://discord.com/channels/613968515677814784/738122137943932958/1175650650575605870\n name: game.i18n.localize(`${MODULENAME}.macros.basicActionMacros.actions.Squeeze`),\n skill: \"acrobatics\",\n action: game.pf2e.actions.get(\"squeeze\"),\n icon: \"icons/commodities/tech/claw-mechanical.webp\",\n },\n {\n actionType: \"skill_untrained\",\n name: game.i18n.localize(`${MODULENAME}.macros.basicActionMacros.actions.Steal`),\n skill: \"thievery\",\n action: game.pf2e.actions.get(\"steal\"),\n icon: \"icons/containers/bags/coinpouch-gold-red.webp\",\n },\n {\n actionType: \"skill_untrained\",\n name: game.i18n.localize(`${MODULENAME}.macros.basicActionMacros.actions.SubsistSociety`),\n skill: \"society\",\n action: game.pf2e.actions.get(\"subsist\"),\n options: { statistic: \"society\" },\n icon: \"icons/environment/settlement/building-rubble.webp\",\n },\n {\n actionType: \"basic\",\n name: game.i18n.localize(`${MODULENAME}.macros.basicActionMacros.actions.SubsistSurvival`),\n skill: \"survival\",\n action: game.pf2e.actions.get(\"subsist\"),\n options: { statistic: \"survival\" },\n icon: \"icons/environment/wilderness/camp-improvised.webp\",\n },\n {\n actionType: \"skill_untrained\",\n name: game.i18n.localize(`${MODULENAME}.macros.basicActionMacros.actions.Swim`),\n skill: \"athletics\",\n action: game.pf2e.actions.get(\"swim\"),\n icon: \"icons/creatures/fish/fish-shark-swimming.webp\",\n },\n {\n actionType: \"other\",\n name: game.i18n.localize(`${MODULENAME}.macros.basicActionMacros.actions.TakeCoverToggle`),\n skill: \"\",\n action: game.pf2e.actions.get(\"take-cover\"),\n icon: `systems/${game.system.id}/icons/equipment/shields/tower-shield.webp`,\n },\n {\n actionType: \"skill_trained\",\n name: game.i18n.localize(`${MODULENAME}.macros.basicActionMacros.actions.Track`),\n skill: \"survival\",\n action: game.pf2e.actions.get(\"track\"),\n icon: `systems/${game.system.id}/icons/conditions/observed.webp`,\n },\n {\n actionType: \"skill_trained\",\n name: game.i18n.localize(`${MODULENAME}.macros.basicActionMacros.actions.TreatDisease`),\n skill: \"medicine\",\n action: game.pf2e.actions.get(\"treat-disease\"),\n icon: \"icons/magic/nature/root-vine-caduceus-healing.webp\",\n },\n {\n actionType: \"skill_trained\",\n name: game.i18n.localize(`${MODULENAME}.macros.basicActionMacros.actions.TreatPoison`),\n skill: \"medicine\",\n action: game.pf2e.actions.get(\"treat-poison\"),\n icon: `systems/${game.system.id}/icons/effects/treat-poison.webp`,\n },\n {\n actionType: \"skill_trained\",\n name: game.i18n.localize(`${MODULENAME}.macros.basicActionMacros.actions.TreatWounds`),\n skill: \"medicine\",\n altSkillAndFeat: [\n { skill: \"nature\", feat: \"natural-medicine\" },\n { skill: \"crafting\", feat: \"chirurgeon\" },\n ],\n action: new MacroActionVariant(\n \"XDY DO_NOT_IMPORT Treat Wounds and Battle Medicine\",\n \"xdy-pf2e-workbench.asymonous-benefactor-macros-internal\",\n ),\n icon: \"icons/skills/wounds/injury-stapled-flesh-tan.webp\",\n },\n {\n actionType: \"skill_untrained\",\n name: game.i18n.localize(`${MODULENAME}.macros.basicActionMacros.actions.Trip`),\n skill: \"athletics\",\n action: game.pf2e.actions.get(\"trip\"),\n icon: \"icons/skills/wounds/bone-broken-marrow-yellow.webp\",\n },\n {\n actionType: \"skill_untrained\",\n name: game.i18n.localize(`${MODULENAME}.macros.basicActionMacros.actions.TumbleThrough`),\n skill: \"acrobatics\",\n action: game.pf2e.actions.get(\"tumble-through\"),\n icon: \"icons/skills/movement/feet-winged-sandals-tan.webp\",\n },\n {\n actionType: \"basic\",\n name: game.i18n.localize(\"PF2E.Actions.DropProne.Title\"),\n skill: \"\",\n action: game.pf2e.actions.get(\"drop-prone\"),\n icon: `systems/${game.system.id}/icons/conditions/prone.webp`,\n },\n ];\n if (foundry.applications.instances.get(\"xdy-pf2e-workbench-BAM-app\")?.rendered) {\n foundry.applications.instances.get(\"xdy-pf2e-workbench-BAM-app\")?.close();\n return;\n }\n\n const controlled = canvas.tokens.controlled.flatMap((token) => token.actor ?? []);\n if (game.user.character) {\n controlled.push(game.user.character);\n }\n\n const supportedActorTypes = [\"character\", \"npc\", \"familiar\"];\n const selectedActor = controlled.filter((actor) => supportedActorTypes.includes(actor.type))[0];\n\n if (!selectedActor) {\n ui.notifications.warn(game.i18n.localize(`${MODULENAME}.macros.basicActionMacros.noActorSelected`));\n return;\n }\n\n const actionsToUse = prepareActions(selectedActor, bamActions);\n\n const actors =\n game.scenes.current?.tokens\n .map((t) => t.actor)\n .filter((a) => a !== null)\n .filter((a) => supportedActorTypes.includes(a.type)) || [];\n const party = game.actors.party?.members || [];\n const partyIds = party.map((actor) => actor.id);\n\n const allActorsSkills = createMapOfSkillsPerActor(actors);\n\n if (partyIds.includes(selectedActor.id)) {\n const partySkills = createMapOfSkillsPerActor(party);\n getBestBonuses(partySkills, partyIds, actionsToUse);\n }\n\n const columns = 1 + ~~((actionsToUse.length - 1) / 14);\n const width = 26 + columns * 260;\n // const height =\n // 30 + ~~(((30 * actionsToUse.filter((x) => !x.showMAP).length + 1) +\n // (64 * actionsToUse.filter((x) => x.showMAP).length + 1)) / columns\n // );\n const tabView = getModuleSetting(\"bamTabview\");\n\n const selectedActorSkills = allActorsSkills.get(selectedActor.id) ?? {};\n const data = actionsToUse.map((action, idx) =>\n createButtonData(action, idx, selectedActor, partyIds, selectedActorSkills),\n );\n\n const filteredData = {\n encounter: data.filter((value) => !(value.action.showDowntime || value.action.showExploration)),\n downtime: data.filter((value) => value.action.showDowntime),\n exploration: data.filter((value) => value.action.showExploration),\n tabView,\n };\n const { ApplicationV2, HandlebarsApplicationMixin } = foundry.applications.api;\n\n class BAMapp extends HandlebarsApplicationMixin(ApplicationV2) {\n static override DEFAULT_OPTIONS = {\n tag: \"form\",\n id: \"xdy-pf2e-workbench-BAM-app\",\n position: { width },\n window: {\n title: game.i18n.format(`${MODULENAME}.macros.basicActionMacros.title`, { name: selectedActor.name }),\n contentClasses: [\"pf2e-bg\", \"bam-dialog\", \"standard-form\"],\n resizable: true,\n },\n form: {\n handler: BAMapp.handler,\n closeOnSubmit: false,\n submitOnChange: false,\n },\n actions: Object.fromEntries(new Map(actionsToUse.map((_e, i) => [i, BAMapp.use]))),\n };\n static override PARTS = {\n index: { template: \"modules/xdy-pf2e-workbench/templates/macros/bam/index.hbs\" },\n footer: { template: \"templates/generic/form-footer.hbs\" },\n };\n static override TABS = {\n primary: {\n tabs: [\n {\n id: \"encounter\",\n label: \"Encounter\",\n },\n {\n id: \"exploration\",\n label: \"Exploration\",\n },\n {\n id: \"downtime\",\n label: \"Downtime\",\n },\n ],\n initial: \"encounter\",\n },\n };\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n static async handler(event: PointerEvent, _form: HTMLFormElement, _formData: any) {\n const ev = (event as PointerEvent & { submitter?: HTMLElement | null }).submitter;\n if (ev && ev.dataset.action === \"cancel\") {\n const app = foundry.applications.instances.get(\"xdy-pf2e-workbench-BAM-app\");\n app?.close();\n }\n }\n\n static async use(event: PointerEvent, button: HTMLElement) {\n const idx = Number(button.dataset.action);\n if (isNaN(idx)) return;\n const action = actionsToUse[idx];\n const current = action.action;\n if (typeof current === \"object\") {\n // TODO Handle other variants than map\n const mapValue = -(Number.parseInt(button.dataset.map ?? \"0\") / 5);\n await current.use({\n event,\n actors: [selectedActor],\n multipleAttackPenalty: mapValue,\n ...action.options,\n });\n } else if (current) {\n await current({\n event,\n actors: [selectedActor],\n skill: action.skill,\n });\n }\n }\n\n override async _prepareContext(options?: object): Promise {\n // @ts-expect-error TODO fix\n const context = await super._prepareContext(options);\n foundry.utils.mergeObject(context, filteredData);\n return context;\n }\n\n // noinspection JSUnusedGlobalSymbols\n override async _preparePartContext(partId: string, context: object, options?: object): Promise {\n // @ts-expect-error TODO fix\n context = await super._preparePartContext(partId, context, options);\n switch (partId) {\n case \"footer\":\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (context as any).buttons = [\n {\n type: \"cancel\",\n action: \"cancel\",\n icon: \"fa-solid fa-xmark\",\n label: \"Cancel\",\n },\n ];\n break;\n case \"index\":\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (context as any).tabs = this._prepareTabs(\"primary\");\n break;\n default:\n break;\n }\n return context;\n }\n }\n\n new BAMapp().render({ force: true });\n}\n\n// basicActionMacros();\n","// Originally from Avery (Velara) Avery#9136, modified by me. Included with permission.\nimport { MODULENAME } from \"../../constants.ts\";\n\n/**\n * Builds the NPC Spellbook Journal.\n *\n * @return {Promise} Returns a promise that resolves when the journal is created.\n */\nexport async function buildNpcSpellbookJournal(): Promise {\n // @ts-expect-error - ui.activeWindow is not fully typed\n const activeWindow = ui.activeWindow;\n let actor;\n if (activeWindow?.constructor.name === \"NPCSheetPF2e\") {\n actor = activeWindow.token?.actor || activeWindow.actor;\n } else {\n const actors = canvas.tokens.controlled.map((a) => a.actor).filter((a) => a?.isOfType(\"npc\"));\n if (actors?.length === 1) {\n actor = actors[0];\n }\n }\n\n const spellcastingEntries = actor?.spellcasting?.contents?.filter((item: { spells: unknown }) => item.spells);\n const length = spellcastingEntries?.length;\n\n if (!actor || length === 0) {\n ui.notifications.warn(game.i18n.localize(`${MODULENAME}.macros.buildNpcSpellbookJournal.noSpellcastingEntry`));\n return;\n }\n\n const spellList: { entry: string; spells: string[] }[] = [];\n for (let i = 0; i < length; i++) {\n spellList[i] = { entry: spellcastingEntries[i].name, spells: [] };\n for (let ii = 0; ii < spellcastingEntries[i]?.spells?.contents?.length; ii++) {\n spellList[i].spells.push(\"@UUID[\" + spellcastingEntries[i].spells.contents[ii].sourceId + \"]\");\n }\n }\n let content = `\n\n \n \n`;\n\n for (let ff = 0; ff < spellList.length; ff++) {\n content += `\n \n \n \n \n `;\n }\n const updates: { name: string; pages: { name: string; text: { content: string } }[]; content?: string } = {\n name: game.i18n.format(`xdy-pf2e-workbench.macros.buildNpcSpellbookJournal.generatedSpellbookFor`, {\n name: actor.name,\n }),\n pages: [{ name: \"Spell book\", text: { content } }],\n };\n updates.content += `
EntrySpells
${spellList[ff].entry}
${spellList[ff].spells}
`;\n\n const journal = game.journal.getName(updates.name);\n if (journal) {\n await journal.delete();\n }\n await JournalEntry.create(updates);\n}\n\n// await buildSpellbookJournal();\n","import { MODULENAME } from \"../constants.ts\";\n\nexport function isAllowedFor(allowSettingKey: string, role: \"player\" | \"gm\"): boolean {\n const value = game.settings.get(MODULENAME, allowSettingKey) as string;\n if (value === \"all\") return true;\n if (role === \"player\") return value === \"players\";\n if (role === \"gm\") return value === \"gm\";\n return false;\n}\n","import { MODULENAME } from \"../../constants.ts\";\nimport {\n degreeOfSuccessWithRerollHandling,\n fireAndForget,\n getActorFromMessage,\n getModuleSetting,\n isActuallyDamageRoll,\n isFirstGM,\n objectHasKey,\n shouldIHandleThisMessage,\n} from \"../../utils.ts\";\nimport { isAllowedFor } from \"../../utils/settings.ts\";\nimport type { ActorPF2e, CharacterPF2e, DamageRoll, ScenePF2e, TokenDocumentPF2e } from \"foundry-pf2e\";\nimport { ActorFlagsPF2e, ChatContextFlag, ChatMessagePF2e, RollOptionFlags, SpellPF2e } from \"foundry-pf2e\";\nimport { Rolled } from \"foundry/client/dice/roll.mts\";\nimport * as systems from \"../../utils/systems.ts\";\nimport {\n AutoRollDamageOptions,\n getEffectiveToolbeltTargetHelperData,\n isExperimentalToolbeltSaveIntegrationEnabled,\n pendingToolbeltDamageInjections,\n shouldWaitForToolbeltTargetHelper,\n} from \"./toolbeltIntegration.ts\";\n\nexport async function autoRollDamage(message: ChatMessagePF2e, options: AutoRollDamageOptions = {}): Promise {\n const numberOfMessagesToCheck = 10;\n const settings = {\n autoRollDamageAllow: getModuleSetting(\"autoRollDamageAllow\"),\n autoRollDamageForStrike: getModuleSetting(\"autoRollDamageForStrike\"),\n autoRollDamageForSpellAttack: getModuleSetting(\"autoRollDamageForSpellAttack\"),\n autoRollDamageForSpellWhenNotAnAttack: getModuleSetting(\"autoRollDamageForSpellWhenNotAnAttack\"),\n };\n\n const shouldAutoRollDamage =\n settings.autoRollDamageAllow &&\n (settings.autoRollDamageForStrike ||\n settings.autoRollDamageForSpellAttack ||\n settings.autoRollDamageForSpellWhenNotAnAttack !== \"no\");\n\n const shouldHandle = options.forceSaveSpellRoll\n ? isFirstGM()\n : shouldIHandleThisMessage(\n message,\n isAllowedFor(\"autoRollDamageAllow\", \"player\"),\n isAllowedFor(\"autoRollDamageAllow\", \"gm\"),\n );\n\n if (shouldAutoRollDamage && shouldHandle) {\n const originUuid = systems.getFlag(message, \"origin.uuid\");\n\n if (originUuid) {\n const actor = getActorFromMessage(message);\n const rollType = systems.getFlag(message, \"context.type\");\n\n const origin: SpellPF2e | null = originUuid ? ((await fromUuid(originUuid)) as SpellPF2e) : null;\n const isAttackSpell = origin?.traits?.has(\"attack\") ?? false;\n const isSaveSpell = origin?.system?.defense?.save ?? false;\n const hasFixedTime = Number.isInteger(parseInt(origin?.system?.time?.value ?? \"\")) ?? false;\n\n const rollForNonSpellAttack = rollType === \"attack-roll\" && settings.autoRollDamageForStrike;\n const rollForNonAttackSpell =\n origin !== null &&\n !isAttackSpell &&\n systems.getFlag(message, \"casting\") !== null &&\n hasFixedTime &&\n origin?.system?.damage;\n\n const rollForNonAttackSaveSpell =\n isSaveSpell &&\n rollForNonAttackSpell &&\n (settings.autoRollDamageForSpellWhenNotAnAttack === \"saveSpell\" ||\n settings.autoRollDamageForSpellWhenNotAnAttack === \"anySpell\");\n\n if (shouldWaitForToolbeltTargetHelper(message, rollForNonAttackSaveSpell, options)) {\n return;\n }\n\n const rollForNonAttackNonSaveSpell =\n !isSaveSpell &&\n rollForNonAttackSpell &&\n (settings.autoRollDamageForSpellWhenNotAnAttack === \"nonSaveSpell\" ||\n settings.autoRollDamageForSpellWhenNotAnAttack === \"anySpell\");\n\n const rollForAttackSpell = isAttackSpell && settings.autoRollDamageForSpellAttack && hasFixedTime;\n\n const degreeOfSuccess = options.forcedDegreeOfSuccess ?? degreeOfSuccessWithRerollHandling(message);\n const isFailure = [\"criticalFailure\", \"failure\"].includes(degreeOfSuccess);\n const isSuccess = [\"criticalSuccess\", \"success\"].includes(degreeOfSuccess);\n const isBasicSave = systems.getFlag(message, \"context.options\")?.includes(\"item:defense:basic\");\n const shouldRollForcedSaveSpell = options.forceSaveSpellRoll && rollForNonAttackSaveSpell;\n\n const originMessage = await getLatestChatMessageWithOrigin(5, originUuid);\n const flags = originMessage?.flags;\n\n const targetHelperActive = game.modules.get(\"pf2e-target-helper\")?.active;\n const targetHelperWillAutoroll =\n targetHelperActive && game.settings.get(\"pf2e-target-helper\", \"multipleTargetRollDamage\") !== \"no\";\n const letTargetHelperAutorollDamage =\n // @ts-expect-error module-specific flag\n (flags[\"pf2e-target-helper\"]?.targets ?? 0) > 1 && targetHelperWillAutoroll;\n\n if (\n actor &&\n (rollForNonAttackNonSaveSpell ||\n shouldRollForcedSaveSpell ||\n (rollForNonAttackSaveSpell && (isFailure || (isBasicSave && degreeOfSuccess === \"success\"))) ||\n (rollForAttackSpell && isSuccess)) &&\n !letTargetHelperAutorollDamage &&\n // Whyzo spell. Don't roll.\n !(isAttackSpell && isSaveSpell)\n ) {\n // @ts-expect-error TODO fix typing\n await handleSpell(flags, numberOfMessagesToCheck, originUuid, origin, message, degreeOfSuccess);\n } else if (actor && rollForNonSpellAttack && isSuccess) {\n await handleNonSpell(actor, message, degreeOfSuccess);\n }\n }\n }\n}\n\n/**\n * Checks if the given message satisfies the conditions to perform a flat check,\n * and returns whether the damage should be rolled or not.\n *\n * @param {ChatMessagePF2e} message - The chat message to check.\n * @return {Promise} - A boolean indicating whether to roll the damage.\n */\n// Cache for flat check results to avoid repeated searches\nconst flatCheckResultCache = new Map();\n\nexport async function noOrSuccessfulFlatcheck(message: ChatMessagePF2e): Promise {\n let rollDamage = true;\n if (!game.modules.get(\"pf2-flat-check\")?.active) {\n return rollDamage;\n }\n\n // Check if we need to do a flat check at all\n const actorFlat = message.actor?.itemTypes.condition.filter((x) => [\"blinded\", \"dazzled\"].includes(x.slug)) ?? [];\n const targetFlat =\n message.target?.actor?.itemTypes.condition.filter((x) =>\n [\"concealed\", \"hidden\", \"invisible\", \"undetected\"].includes(x.slug),\n ) ?? [];\n\n if (actorFlat?.length === 0 && targetFlat?.length === 0) {\n return rollDamage;\n }\n\n const { token, actor } = message;\n let { item } = message;\n const match = systems.getFlag(message, \"origin.uuid\")?.match(/Item.(\\w+)/);\n if (!item && match && match[1] === \"xxPF2ExUNARMEDxx\") {\n item = { type: \"weapon\", data: {} } as unknown as NonNullable;\n }\n\n if (!token || !item || !actor || isActuallyDamageRoll(message)) {\n return rollDamage;\n }\n\n // Check cache first\n const cacheKey = `${message.id}`;\n if (flatCheckResultCache.has(cacheKey)) {\n return flatCheckResultCache.get(cacheKey) as boolean;\n }\n\n // Wait a short time for flat check message to be created\n await new Promise((resolve) => setTimeout(resolve, 150));\n\n // Look for flat check failure messages, but only search recent messages\n const array = game.messages.contents;\n const messageIndex = array.findIndex((msg) => msg.id === message.id);\n\n if (messageIndex > -1) {\n // Only search up to 5 messages after the current one\n const searchLimit = Math.min(5, array.length - messageIndex);\n const recentMessages = array.slice(messageIndex, messageIndex + searchLimit);\n\n rollDamage = !recentMessages.some((msg) => msg.content.includes(\"dice-result flat-check-failure\"));\n\n // Store in cache for future lookups\n flatCheckResultCache.set(cacheKey, rollDamage);\n }\n\n return rollDamage;\n}\n\nexport function persistentDamageHealing(message: ChatMessagePF2e): void {\n if (!message || !game.ready || !message.token || !message.actor || !message.isDamageRoll) return;\n\n const rolls = Array.isArray(message.rolls) ? (message.rolls as Rolled[]) : null;\n if (!rolls) return;\n\n let dtype: \"Damage\" | \"Healing\" | undefined;\n if (rolls.length === 0) return;\n if (rolls[0]?.instances?.some((i) => i.persistent && i.options.evaluatePersistent)) {\n dtype = \"Damage\";\n } else if (\n rolls.some((r) => r.kinds.has(\"healing\")) &&\n (message.flavor?.includes(\n game.i18n.localize(\"PF2E.Encounter.Broadcast.FastHealing.fast-healing.ReceivedMessage\"),\n ) ||\n message.flavor?.includes(\n game.i18n.localize(\"PF2E.Encounter.Broadcast.FastHealing.regeneration.ReceivedMessage\"),\n ))\n ) {\n dtype = \"Healing\";\n }\n\n if (dtype && getModuleSetting(`applyPersistent${dtype}`)) {\n const itemOptions = message.item?.getRollOptions(\"item\") ?? [];\n const rollOptions = new Set([...itemOptions, ...message.actor.getSelfRollOptions()]);\n const damage = dtype === \"Damage\" ? rolls[0] : -rolls.reduce((sum, current) => sum + (current.total ?? 1), 0);\n const apply = message.actor.applyDamage({\n damage,\n token: message.token,\n item: message.item,\n rollOptions,\n skipIWR: dtype === \"Healing\",\n });\n if (dtype === \"Damage\" && getModuleSetting(\"applyPersistentDamageRecoveryRoll\")) {\n // Use .then() here so the damage taken message is in chat before the recovery roll. It works without, but the order\n // of the messages will be undetermined.\n fireAndForget(\n apply.then(() => {\n if (message.item?.isOfType(\"condition\")) {\n message.item.rollRecovery();\n }\n }),\n \"damageHandler: persistent recovery roll\",\n );\n }\n // TODO Update the message to remove the recovery roll button, instead include the result in the message (and remove the message the following line creates.)\n }\n}\n\nfunction getActionFromMessage(actions: any[], message: ChatMessagePF2e) {\n const attackAbilities = actions\n .filter((atk) => {\n return atk?.system?.traits.value.includes(\"attack\");\n })\n .filter((atk) => {\n return atk.id === message.item?.id;\n });\n\n const strikes = message.actor?.system?.actions\n ?.filter((atk: { type: string }) => {\n return atk?.type === \"strike\";\n })\n .filter((atk) => {\n return atk?.item?.id === message.item?.id;\n });\n\n const allAttacks = attackAbilities.concat(strikes);\n\n if (allAttacks.length === 1) {\n // Normal case\n return allAttacks[0];\n } else if (allAttacks.length > 1 && strikes && strikes?.length > 1) {\n // The strike is most likely based on an RE which means that all actions get the same item id (e.g. animal form), try to regex it out of the message instead\n const strike = game.i18n.localize(`${MODULENAME}.SETTINGS.autoRollDamageForStrike.strike`);\n const s = `

(.*?)${strike}: (.*?)<`;\n const strikeName = message.flavor?.match(s);\n if (strikeName && strikeName[2]) {\n return actions.find((a: { label: string }) => a.label === strikeName[2]);\n } else {\n // If we can't find the strike label, give up.\n return null;\n }\n } else {\n // If we can't find the strike, give up.\n return null;\n }\n}\n\n// Cache for origin messages to avoid repeated searches\nconst originMessageCache = new Map();\n\nexport function evictDamageHandlerCaches(): void {\n if (flatCheckResultCache.size > 100) {\n flatCheckResultCache.clear();\n }\n if (originMessageCache.size > 100) {\n originMessageCache.clear();\n }\n}\n\nasync function getLatestChatMessageWithOrigin(numberOfMessagesToCheck: number, originUuid: string) {\n // Check cache first\n if (originMessageCache.has(originUuid)) {\n return originMessageCache.get(originUuid);\n }\n\n const chatLength = game.messages?.contents.length ?? 0;\n for (let i = 1; i <= Math.min(numberOfMessagesToCheck + 1, chatLength); i++) {\n const spellMessage = game.messages?.contents[chatLength - i];\n if (spellMessage && systems.getFlag(spellMessage, \"origin.uuid\") === originUuid) {\n // Store in cache for future lookups\n originMessageCache.set(originUuid, spellMessage);\n return spellMessage;\n }\n }\n return undefined;\n}\n\nasync function getCastRankFromChat(numberOfMessagesToCheck: number, originUuid: string): Promise {\n const spellMessage = await getLatestChatMessageWithOrigin(numberOfMessagesToCheck, originUuid);\n const level = spellMessage?.content.match(/data-cast-level=\"(\\d+)\"/);\n if (level && level[1]) {\n return parseInt(level[1]);\n }\n return 0;\n}\n\nasync function handleSpell(\n flags: ActorFlagsPF2e & {\n pf2e: { rollOptions: RollOptionFlags; trackedItems: Record; [p: string]: unknown };\n },\n numberOfMessagesToCheck: number,\n originUuid: string,\n origin: SpellPF2e,\n message: ChatMessagePF2e,\n degreeOfSuccess: string,\n) {\n const castRank = await determineCastRank(\n origin.name,\n flags,\n numberOfMessagesToCheck,\n originUuid,\n origin.system.level.value,\n );\n const rollDamage = await noOrSuccessfulFlatcheck(message);\n\n if (rollDamage) {\n // Fakes the event.closest function that pf2e uses to parse spell level for heightening damage rolls.\n const target = constructTargetElement(castRank);\n\n const toolbeltTargetHelperData = getEffectiveToolbeltTargetHelperData(message);\n const isToolbeltManaged =\n isExperimentalToolbeltSaveIntegrationEnabled() && toolbeltTargetHelperData?.type === \"spell\";\n\n if (isToolbeltManaged) {\n pendingToolbeltDamageInjections.set(originUuid, {\n targetHelperData: toolbeltTargetHelperData,\n createdAt: Date.now(),\n });\n }\n\n if ((systems.getFlag(message, \"origin.variant.overlays\")?.length ?? 0) > 0) {\n const overlays = systems.getFlag(message, \"origin.variant.overlays\");\n const variant = origin.loadVariant({\n castRank,\n // target,\n overlayIds: overlays?.[0] ? [overlays[0]] : [],\n });\n // @ts-expect-error TODO fix typing\n await variant.rollDamage({\n outcome: degreeOfSuccess,\n target,\n });\n } else {\n // @ts-expect-error TODO fix typing\n await origin?.rollDamage({\n outcome: degreeOfSuccess,\n target,\n });\n }\n\n if (isToolbeltManaged) {\n await message.setFlag(\"pf2e-toolbelt\", \"targetHelper\", null);\n }\n }\n}\n\nasync function determineCastRank(\n spellName: string,\n flags: ActorFlagsPF2e & {\n pf2e: { rollOptions: RollOptionFlags; trackedItems: Record; [p: string]: unknown };\n },\n numberOfMessagesToCheck: number,\n originUuid: string,\n value: number,\n): Promise {\n // @ts-expect-error TODO fix typing\n let castRank: number = flags.pf2e.origin?.castRank ? Number(flags.pf2e.origin?.castRank) : 0;\n if (castRank === 0) {\n castRank = await getCastRankFromChat(numberOfMessagesToCheck, originUuid);\n }\n if (castRank === 0) {\n if (getModuleSetting(\"autoRollDamageNotifyOnSpellCardNotFound\")) {\n ui.notifications.info(game.i18n.format(`${MODULENAME}.spellCardNotFound`, { spell: spellName }));\n }\n // Give up and use spell level\n castRank = value ?? 0;\n }\n return castRank;\n}\n\nfunction constructTargetElement(castRank: number): HTMLDivElement {\n const target = document.createElement(\"div\");\n target.dataset.castRank = castRank.toString();\n target.closest = () => {\n return { dataset: { castRank: castRank } };\n };\n return target;\n}\n\nasync function handleNonSpell(\n actor:\n | ActorPF2e | null>\n | CharacterPF2e | null>,\n message: ChatMessagePF2e,\n degreeOfSuccess: string,\n) {\n const options = actor?.getRollOptions([\"all\", \"damage-roll\"]);\n const attackOption = options?.find((option) => option.match(/(.*)-attack/));\n const damageOption = attackOption?.replace(\"-attack\", \"-damage\");\n\n if (damageOption) {\n options?.push(damageOption);\n }\n\n const checkContext = systems.getFlag(message, \"context\") ?? null;\n\n const mapIncreases =\n checkContext && \"mapIncreases\" in checkContext && [0, 1, 2].includes(checkContext.mapIncreases)\n ? checkContext.mapIncreases\n : null;\n const altUsage = checkContext && \"altUsage\" in checkContext ? checkContext.altUsage : null;\n const target = message.target?.token?.object ?? null;\n const actions = actor?.system?.actions;\n\n if (!actions || actions.length === 0) return;\n\n const rollDamage = await noOrSuccessfulFlatcheck(message); // Can't be inlined\n if (!rollDamage) return;\n\n const toRoll = getActionFromMessage(actions, message);\n\n if (toRoll && toRoll.type === \"strike\") {\n const method = degreeOfSuccess === \"success\" ? \"damage\" : \"critical\";\n return toRoll[method]?.({ event, altUsage, mapIncreases, checkContext, target, options });\n }\n\n await handleElementalBlastAttack(actor, message, degreeOfSuccess, checkContext);\n}\n\nasync function handleElementalBlastAttack(\n actor:\n | ActorPF2e | null>\n | CharacterPF2e | null>,\n message: { rolls: any[] },\n degreeOfSuccess: string,\n checkContext: ChatContextFlag | null,\n) {\n const roll = message.rolls?.find((r: { options: { action: string } }) => r.options?.action === \"elemental-blast\");\n if (roll && actor.isOfType(\"character\")) {\n const identifier = roll?.options.identifier;\n const [element, damageType, meleeOrRanged, actionCost]: (string | undefined)[] = identifier?.split(\".\") ?? [];\n\n if (objectHasKey(CONFIG.PF2E.elementTraits, element) && objectHasKey(CONFIG.PF2E.damageTypes, damageType)) {\n const params: Record = {\n element,\n damageType,\n melee: meleeOrRanged === \"melee\",\n actionCost: Number(actionCost) || 1,\n checkContext,\n outcome: degreeOfSuccess,\n event,\n };\n // @ts-expect-error TODO fix typing\n await new game.pf2e.ElementalBlast(actor).damage(params);\n }\n }\n return;\n}\n","import { MODULENAME } from \"../../constants.ts\";\nimport { getModuleSetting } from \"../../utils.ts\";\nimport * as systems from \"../../utils/systems.ts\";\nimport { ChatMessagePF2e } from \"foundry-pf2e\";\nimport { autoRollDamage } from \"./index.ts\";\n\nexport const pendingToolbeltDamageInjections = new Map<\n string,\n { targetHelperData: ToolbeltTargetHelperData; createdAt: number }\n>();\n\nexport const toolbeltTargetHelperCache = new Map();\nexport const toolbeltSaveTracker = new Map();\n\nexport function clearToolbeltCaches(): void {\n toolbeltSaveTracker.clear();\n toolbeltTargetHelperCache.clear();\n pendingToolbeltDamageInjections.clear();\n}\n\ntype LibWrapperApi = { register: (...args: unknown[]) => void };\ntype ChatMessageWrapper = (\n this: ChatMessagePF2e,\n wrapped: (...args: unknown[]) => Promise,\n ...args: unknown[]\n) => Promise;\n\nfunction wrapChatMessage(method: string, fn: ChatMessageWrapper): void {\n const api = (globalThis as unknown as { libWrapper?: LibWrapperApi }).libWrapper;\n api?.register(MODULENAME, method, fn, \"WRAPPER\");\n}\n\nlet toolbeltWrappersRegistered = false;\n\nexport function registerToolbeltWrappers(): void {\n if (toolbeltWrappersRegistered) {\n return;\n }\n\n if (!(globalThis as unknown as { libWrapper?: LibWrapperApi }).libWrapper) {\n return;\n }\n\n wrapChatMessage(\"ChatMessage.prototype.update\", function (this, wrapped, changes, ...args) {\n cacheToolbeltTargetHelperData(this.id, readTargetHelperFromUpdate(changes as Record));\n return wrapped(changes, ...args);\n });\n\n wrapChatMessage(\"ChatMessage.prototype.setFlag\", function (this, wrapped, scope, key, value, ...args) {\n if (scope === \"pf2e-toolbelt\" && key === \"targetHelper\") {\n if (value && typeof value === \"object\") {\n cacheToolbeltTargetHelperData(this.id, value);\n } else {\n toolbeltTargetHelperCache.delete(this.id);\n }\n }\n return wrapped(scope, key, value, ...args);\n });\n\n wrapChatMessage(\"ChatMessage.prototype._preCreate\", function (this, wrapped, data, ...args) {\n const originUuid = systems.getFlag(this, \"origin.uuid\");\n if (this.isDamageRoll && originUuid) {\n const pending = pendingToolbeltDamageInjections.get(originUuid);\n if (pending) {\n this.updateSource({\n flags: { \"pf2e-toolbelt\": { targetHelper: pending.targetHelperData } },\n });\n pendingToolbeltDamageInjections.delete(originUuid);\n }\n }\n return wrapped(data, ...args);\n });\n\n toolbeltWrappersRegistered = true;\n}\n\nfunction readTargetHelperFromUpdate(changes: Record): unknown {\n const flattened = changes[\"flags.pf2e-toolbelt.targetHelper\"];\n if (flattened !== undefined) {\n return flattened;\n }\n\n const flags = changes.flags;\n if (!flags || typeof flags !== \"object\") {\n return undefined;\n }\n\n const pf2eToolbelt = (flags as Record)[\"pf2e-toolbelt\"];\n if (!pf2eToolbelt || typeof pf2eToolbelt !== \"object\") {\n return undefined;\n }\n\n return (pf2eToolbelt as Record).targetHelper;\n}\n\nfunction cacheToolbeltTargetHelperData(messageId: string, value: unknown): void {\n if (!value || typeof value !== \"object\") {\n return;\n }\n toolbeltTargetHelperCache.set(messageId, {\n data: foundry.utils.deepClone(value) as ToolbeltTargetHelperData,\n updatedAt: Date.now(),\n });\n}\n\nexport function getToolbeltTargetHelperData(message: ChatMessagePF2e): ToolbeltTargetHelperData | null {\n if (!game.modules.get(\"pf2e-toolbelt\")?.active) {\n return null;\n }\n const targetHelper = message.getFlag(\"pf2e-toolbelt\", \"targetHelper\");\n return targetHelper && typeof targetHelper === \"object\" ? (targetHelper as ToolbeltTargetHelperData) : null;\n}\n\nexport function getCachedToolbeltTargetHelperData(messageId: string): ToolbeltTargetHelperData | null {\n return toolbeltTargetHelperCache.get(messageId)?.data ?? null;\n}\n\nexport function getEffectiveToolbeltTargetHelperData(message: ChatMessagePF2e): ToolbeltTargetHelperData | null {\n const cached = getCachedToolbeltTargetHelperData(message.id);\n const fromFlags = getToolbeltTargetHelperData(message);\n\n if (!cached && !fromFlags) {\n return null;\n }\n\n return { ...cached, ...fromFlags };\n}\n\nfunction collectSaveEntries(data: ToolbeltTargetHelperData | null): [string, ToolbeltTargetHelperSaveData][] {\n if (!data?.saveVariants) {\n return [];\n }\n const entries: [string, ToolbeltTargetHelperSaveData][] = [];\n for (const saveVariant of Object.values(data.saveVariants)) {\n if (saveVariant?.saves) {\n entries.push(...Object.entries(saveVariant.saves));\n }\n }\n return entries;\n}\n\nexport function isToolbeltSaveSuccessOutcome(value: unknown): value is ToolbeltSaveSuccessOutcome {\n return (SAVE_OUTCOMES as readonly unknown[]).includes(value);\n}\n\nexport function getToolbeltPayloadTargetId(target: { id?: string } | null | undefined): string | null {\n const targetId = target?.id;\n return typeof targetId === \"string\" && targetId.length > 0 ? targetId : null;\n}\n\nfunction tokenIdFromUuid(uuid: string): string | null {\n const tokenMatch = uuid.match(/Token\\.([^.]+)/);\n if (tokenMatch?.[1]) {\n return tokenMatch[1];\n }\n const lastSegment = uuid.split(\".\").at(-1);\n return lastSegment && lastSegment !== \"Token\" ? lastSegment : null;\n}\n\nexport function getToolbeltExpectedTargetIds(data: ToolbeltTargetHelperData | null): Set {\n if (!data?.targets || !Array.isArray(data.targets)) {\n return new Set();\n }\n\n return new Set(data.targets.map(tokenIdFromUuid).filter((id): id is string => id !== null));\n}\n\nexport function getToolbeltSavedTargetIds(data: ToolbeltTargetHelperData | null): Set {\n return new Set(collectSaveEntries(data).map(([targetId]) => targetId));\n}\n\nexport function getToolbeltSaveOutcomes(data: ToolbeltTargetHelperData | null): ToolbeltSaveSuccessOutcome[] {\n return collectSaveEntries(data)\n .map(([, saveData]) => saveData?.success)\n .filter(isToolbeltSaveSuccessOutcome);\n}\n\nexport function isToolbeltBasicSave(data: ToolbeltTargetHelperData | null): boolean {\n if (!data?.saveVariants) {\n return false;\n }\n return Object.values(data.saveVariants).some((sv) => !!sv && Boolean(sv.basic));\n}\n\nexport function getOrCreateToolbeltTrackerState(\n messageId: string,\n expectedTargetIds: Set,\n): ToolbeltSaveTrackerState {\n const existing = toolbeltSaveTracker.get(messageId);\n if (existing) {\n for (const id of expectedTargetIds) existing.expectedTargetIds.add(id);\n existing.updatedAt = Date.now();\n return existing;\n }\n\n const state: ToolbeltSaveTrackerState = {\n expectedTargetIds,\n savedTargetIds: new Set(),\n saveOutcomes: new Set(),\n hasBasicSave: false,\n completed: false,\n updatedAt: Date.now(),\n };\n toolbeltSaveTracker.set(messageId, state);\n return state;\n}\n\nexport function shouldRollToolbeltSaveSpellDamage(state: ToolbeltSaveTrackerState): boolean {\n const hasFailure = state.saveOutcomes.has(\"criticalFailure\") || state.saveOutcomes.has(\"failure\");\n if (hasFailure) {\n return true;\n }\n return state.hasBasicSave && state.saveOutcomes.has(\"success\");\n}\n\nexport function isExperimentalToolbeltSaveIntegrationEnabled(): boolean {\n return getModuleSetting(\"experimentalToolbeltSaveIntegration\");\n}\n\nexport function shouldWaitForToolbeltTargetHelper(\n message: ChatMessagePF2e,\n rollForNonAttackSaveSpell: boolean,\n options: AutoRollDamageOptions,\n): boolean {\n if (options.ignoreToolbeltTargetHelperWait) {\n return false;\n }\n\n return (\n isExperimentalToolbeltSaveIntegrationEnabled() &&\n rollForNonAttackSaveSpell &&\n getEffectiveToolbeltTargetHelperData(message)?.type === \"spell\"\n );\n}\n\nexport async function handlePf2eToolbeltRollSave(payload: ToolbeltRollSaveHookPayload): Promise {\n if (!isExperimentalToolbeltSaveIntegrationEnabled()) {\n return;\n }\n\n const hookMessage = payload.message;\n const message = (game.messages.get(hookMessage.id) as ChatMessagePF2e | undefined) ?? hookMessage;\n const toolbeltData = getEffectiveToolbeltTargetHelperData(message);\n\n if (toolbeltData?.type !== \"spell\") {\n return;\n }\n\n const expectedTargetIds = getToolbeltExpectedTargetIds(toolbeltData);\n if (expectedTargetIds.size === 0) {\n return;\n }\n\n const state = getOrCreateToolbeltTrackerState(message.id, expectedTargetIds);\n\n if (state.completed) {\n return;\n }\n\n state.hasBasicSave ||= isToolbeltBasicSave(toolbeltData);\n for (const savedTargetId of getToolbeltSavedTargetIds(toolbeltData)) {\n state.savedTargetIds.add(savedTargetId);\n }\n for (const outcome of getToolbeltSaveOutcomes(toolbeltData)) {\n state.saveOutcomes.add(outcome);\n }\n const payloadTargetId = getToolbeltPayloadTargetId(payload.target);\n if (payloadTargetId) {\n state.savedTargetIds.add(payloadTargetId);\n }\n const payloadSuccessOutcome = isToolbeltSaveSuccessOutcome(payload.data?.success) ? payload.data?.success : null;\n if (payloadSuccessOutcome) {\n state.saveOutcomes.add(payloadSuccessOutcome);\n }\n state.updatedAt = Date.now();\n\n const toolbeltFlags = message.flags?.[\"pf2e-toolbelt\"];\n const toolbeltFlagsCleared =\n !!toolbeltFlags && typeof toolbeltFlags === \"object\" && Object.keys(toolbeltFlags).length === 0;\n if (toolbeltFlagsCleared) {\n return;\n }\n\n const allSaved =\n state.expectedTargetIds.size > 0 && [...state.expectedTargetIds].every((id) => state.savedTargetIds.has(id));\n if (!allSaved) {\n return;\n }\n\n state.completed = true;\n\n if (shouldRollToolbeltSaveSpellDamage(state)) {\n // Wait a bit for toolbelt to do it's stuff\n await new Promise((resolve) => setTimeout(resolve, 100));\n await autoRollDamage(message, {\n ignoreToolbeltTargetHelperWait: true,\n forceSaveSpellRoll: true,\n forcedDegreeOfSuccess: \"failure\",\n });\n }\n}\n\nexport const SAVE_OUTCOMES = [\"criticalFailure\", \"failure\", \"success\", \"criticalSuccess\"] as const;\nexport type ToolbeltSaveSuccessOutcome = (typeof SAVE_OUTCOMES)[number];\n\nexport type ToolbeltTargetHelperSaveData = {\n success?: ToolbeltSaveSuccessOutcome;\n [key: string]: unknown;\n};\n\nexport type ToolbeltTargetHelperSaveVariant = {\n basic?: boolean;\n saves?: Record;\n [key: string]: unknown;\n};\n\nexport type ToolbeltTargetHelperData = {\n type?: string;\n targets?: string[];\n saveVariants?: Record;\n};\n\nexport type ToolbeltSaveTrackerState = {\n expectedTargetIds: Set;\n savedTargetIds: Set;\n saveOutcomes: Set;\n hasBasicSave: boolean;\n completed: boolean;\n updatedAt: number;\n};\n\nexport type ToolbeltRollSaveHookPayload = {\n message: ChatMessagePF2e;\n target?: { id?: string } | null;\n data?: { success?: unknown } & Record;\n};\n\nexport type AutoRollDamageOptions = {\n ignoreToolbeltTargetHelperWait?: boolean;\n forceSaveSpellRoll?: boolean;\n forcedDegreeOfSuccess?: string;\n};\n","import { clearToolbeltCaches } from \"../feature/damageHandler/toolbeltIntegration.ts\";\n\nexport function combatStartHook(): void {\n clearToolbeltCaches();\n}\n","import {\n fireAndForget,\n getActorFromMessage,\n getModuleFlag,\n getModuleSetting,\n isFirstGM,\n shouldIHandleThis,\n shouldIHandleThisMessage,\n} from \"../../utils.ts\";\nimport { isAllowedFor } from \"../../utils/settings.ts\";\nimport { logDebug } from \"../../utils/logging.ts\";\nimport { CHARACTER_TYPE, NPC_TYPE } from \"../../xdy-pf2e-workbench.ts\";\nimport { MODULENAME } from \"../../constants.ts\";\nimport { ActorPF2e, ActorSystemData, ChatMessagePF2e, ItemPF2e } from \"foundry-pf2e\";\nimport { moveOnZeroHP } from \"../initiativeHandler/index.ts\";\nimport * as systems from \"../../utils/systems.ts\";\n\nfunction createStatusEffectChatMessage(actor: ActorPF2e, name: string, i18nKey: string, context: string): void {\n fireAndForget(\n ChatMessage.create({\n flavor: game.i18n.format(`${MODULENAME}.SETTINGS.${i18nKey}`, { name }),\n speaker: ChatMessage.getSpeaker({ actor }),\n whisper:\n systems.getSystemSetting(\"metagame\", \"secretDamage\") && !actor?.hasPlayerOwner\n ? ChatMessage.getWhisperRecipients(\"GM\").map((u) => u.id)\n : [],\n }),\n context,\n );\n}\n\nexport function dyingHandlingPreUpdateActorHook(\n actor: any,\n update: Record,\n currentActorHp: number,\n updateHp: number,\n autoGainDying: string,\n): void {\n const automaticMove = getModuleSetting(\"enableAutomaticMove\");\n const automoveIfZeroHP =\n game.combat &&\n ((automaticMove === \"reaching0HPCharactersOnly\" && actor.type === CHARACTER_TYPE) ||\n (automaticMove === \"reaching0HP\" && [CHARACTER_TYPE, NPC_TYPE].includes(actor.type)));\n const autoRemoveDying = getModuleSetting(\"autoRemoveDyingAtGreaterThanZeroHP\");\n const autoRemoveUnconscious = getModuleSetting(\"autoRemoveUnconsciousAtGreaterThanZeroHP\");\n\n const isHealed = currentActorHp <= 0 && updateHp > 0;\n\n if (autoGainDying && !autoGainDying.startsWith(\"no\")) {\n fireAndForget(\n (async () => {\n const hpRaisedAbove0 = await handleDyingOnZeroHP(\n actor,\n fu.deepClone(update),\n currentActorHp,\n updateHp,\n autoGainDying,\n );\n logDebug(\"Workbench increaseDyingOnZeroHP complete\");\n if (hpRaisedAbove0 || isHealed) {\n if (autoRemoveDying && !autoRemoveDying.startsWith(\"no\")) {\n await new Promise((resolve) => setTimeout(resolve, 250));\n await autoRemoveDyingAtGreaterThanZeroHp(actor, true, autoRemoveDying);\n logDebug(\"Workbench autoRemoveDyingAtGreaterThanZeroHP complete\");\n }\n if (autoRemoveUnconscious) {\n await autoRemoveUnconsciousAtGreaterThanZeroHP(actor, true);\n }\n } else if (automoveIfZeroHP && currentActorHp > 0 && updateHp <= 0) {\n moveOnZeroHP(actor);\n }\n })(),\n \"dyingHandlingPreUpdateActorHook\",\n );\n } else {\n if (isHealed) {\n fireAndForget(\n (async () => {\n if (autoRemoveDying && !autoRemoveDying.startsWith(\"no\")) {\n await autoRemoveDyingAtGreaterThanZeroHp(actor, true, autoRemoveDying);\n }\n if (autoRemoveUnconscious) {\n await autoRemoveUnconsciousAtGreaterThanZeroHP(actor, true);\n }\n })(),\n \"dyingHandlingPreUpdateActorHook (hp restored)\",\n );\n } else if (automoveIfZeroHP && currentActorHp > 0 && updateHp <= 0) {\n moveOnZeroHP(actor);\n }\n }\n}\n\nexport async function itemHandlingItemHook(item: ItemPF2e): Promise {\n if (isFirstGM() && item.slug === \"dying\" && item.parent) {\n fireAndForget(handleDying(0, 0, item.parent, false), \"itemHandlingItemHook handleDying\");\n }\n\n const giveWounded = getModuleSetting(\"giveWoundedWhenDyingRemoved\");\n const giveUnconscious = getModuleSetting(\"giveUnconsciousIfDyingRemovedAt0HP\");\n if (giveWounded) {\n await giveWoundedWhenDyingRemoved(item);\n logDebug(\"Workbench giveWoundedWhenDyingRemoved complete\");\n }\n if (giveUnconscious) {\n await giveUnconsciousIfDyingRemovedAt0HP(item);\n logDebug(\"Workbench giveUnconsciousIfDyingRemovedAt0HP complete\");\n }\n}\n\nexport function handleDyingRecoveryRoll(message: ChatMessagePF2e, enabled: boolean): void {\n const flavor = message.flavor;\n const token = message.token;\n if (\n enabled &&\n shouldIHandleThisMessage(\n message,\n isAllowedFor(\"handleDyingRecoveryRollAllow\", \"player\"),\n isAllowedFor(\"handleDyingRecoveryRollAllow\", \"gm\"),\n ) &&\n (flavor.includes(game.i18n.localize(\"PF2E.Recovery.critFailure\")) ||\n flavor.includes(game.i18n.localize(\"PF2E.Recovery.critSuccess\")) ||\n flavor.includes(game.i18n.localize(\"PF2E.Recovery.failure\")) ||\n flavor.includes(game.i18n.localize(\"PF2E.Recovery.success\"))) &&\n message.id === game.messages.contents.pop()?.id &&\n token &&\n token.actor &&\n token.isOwner\n ) {\n const outcome = systems.getFlag(message, \"context.outcome\") ?? \"\";\n\n const actor = getActorFromMessage(message);\n if (!actor) return;\n\n const originalDyingCounter = token.actor?.getCondition(\"dying\")?.value ?? 0;\n let dyingCounter = 0;\n let outcomeString = \"\";\n switch (outcome) {\n case \"criticalFailure\":\n dyingCounter = dyingCounter + 2;\n outcomeString = game.i18n.localize(\"PF2E.CritFailure\");\n break;\n case \"criticalSuccess\":\n dyingCounter = dyingCounter - 2;\n outcomeString = game.i18n.localize(\"PF2E.CritSuccess\");\n break;\n case \"failure\":\n dyingCounter = dyingCounter + 1;\n outcomeString = game.i18n.localize(\"PF2E.Failure\");\n break;\n case \"success\":\n outcomeString = game.i18n.localize(\"PF2E.Success\");\n dyingCounter = dyingCounter - 1;\n break;\n }\n if (originalDyingCounter > 0 || dyingCounter !== 0) {\n fireAndForget(\n handleDying(dyingCounter, originalDyingCounter, actor),\n \"handleDyingRecoveryRoll handleDying\",\n );\n\n const total = message.rolls.reduce((total, roll) => total + roll.total, 0);\n fireAndForget(\n ChatMessage.create({\n flavor: game.i18n.format(`${MODULENAME}.SETTINGS.handleDyingRecoveryRoll.handled`, {\n outcome: outcomeString,\n defeated: token.combatant?.defeated\n ? game.i18n.format(`${MODULENAME}.SETTINGS.handleDyingRecoveryRoll.defeated`, {\n name: token.actor?.name ?? \"???\",\n })\n : \"\",\n roll: total,\n }),\n speaker: message.speaker,\n }),\n \"handleDyingRecoveryRoll ChatMessage\",\n );\n fireAndForget(message.delete({ render: false }), \"handleDyingRecoveryRoll delete\");\n }\n }\n}\n\nexport async function handleDying(\n dyingCounter: number,\n originalDyingCounter: number,\n actor: ActorPF2e,\n isDefeated = actor.combatant?.defeated,\n): Promise {\n // @ts-expect-error TODO Is this the right place to look for it?\n const dyingMax = actor.system.attributes.dying?.max;\n const shouldDie = originalDyingCounter + dyingCounter >= (dyingMax ?? 4) && !isDefeated;\n const shouldBecomeDying = originalDyingCounter + dyingCounter > 0 && !isDefeated;\n if (shouldDie) {\n await actor.increaseCondition(\"dying\", {\n max: dyingMax ?? 4,\n value: dyingMax ?? 4,\n });\n await actor.combatant?.toggleDefeated();\n await actor.unsetFlag(MODULENAME, \"dyingLastApplied\");\n logDebug(\"dyingLastApplied cleared because dead\");\n } else if (shouldBecomeDying) {\n await actor.increaseCondition(\"dying\", {\n max: dyingMax ?? 4,\n value: Math.min(dyingCounter, dyingMax ?? 4),\n });\n const dying = actor.getCondition(\"dying\");\n if (dying) {\n logDebug(`dyingCounter was ${originalDyingCounter} is ${dying.value}`);\n const now = Date.now();\n await actor.setFlag(MODULENAME, \"dyingLastApplied\", now);\n logDebug(`dyingLastApplied set to ${now}, dyingCounter was ${originalDyingCounter} is ${dying.value}`);\n }\n } else {\n const dyingCondition = actor.getCondition(\"dying\");\n if (dyingCondition) {\n await actor.decreaseCondition(\"dying\", { forceRemove: true });\n await actor.unsetFlag(MODULENAME, \"dyingLastApplied\");\n logDebug(\"dyingLastApplied cleared because not dying\");\n } else {\n await actor.unsetFlag(MODULENAME, \"dyingLastApplied\");\n logDebug(\"handleDying (clear flag, dying already removed)\");\n }\n }\n}\n\nexport async function autoRemoveDyingAtGreaterThanZeroHp(\n actor: ActorPF2e,\n hpAboveZero: boolean,\n autoRemoveDying: string,\n): Promise {\n const dying = actor.getCondition(\"dying\");\n if (shouldIHandleThis(actor) && dying && !dying.isLocked && hpAboveZero) {\n const value = dying?.value || 0;\n if (dying && value > 0 && !dying.isLocked) {\n if (isRelevantForActor(actor.type, autoRemoveDying)) {\n await handleDying(0, 0, actor);\n }\n }\n }\n return true;\n}\n\nfunction isRelevantForActor(actorType: string, option: string): boolean {\n return option.endsWith(\"ForCharacters\") ? [\"character\", \"familiar\"].includes(actorType) : true;\n}\n\nexport async function autoRemoveUnconsciousAtGreaterThanZeroHP(\n actor: ActorPF2e,\n hpRaisedAboveZero: boolean,\n): Promise {\n const unconscious = actor.getCondition(\"unconscious\");\n if (shouldIHandleThis(actor) && hpRaisedAboveZero && unconscious && !unconscious.isLocked) {\n await actor.decreaseCondition(\"unconscious\", { forceRemove: true });\n }\n}\n\nexport function getRelevantMessages(actor: ActorPF2e): ChatMessagePF2e[] {\n const relevant = game.messages.contents.slice(-Math.min(10, game.messages.size));\n return getModuleSetting(\"autoGainDyingIgnoresTargeting\")\n ? relevant\n : relevant.filter((message) => message.target?.actor.id === actor.id);\n}\n\nfunction filterMessagesByContextType(messages: ChatMessagePF2e[], contextType: string): ChatMessagePF2e[] {\n return messages.filter((message) => systems.getFlag(message, \"context.type\") === contextType);\n}\n\nfunction filterMessagesByStrikeDamaging(messages: ChatMessagePF2e[]): ChatMessagePF2e[] {\n return messages.filter((message) => systems.getFlag(message, \"strike.damaging\"));\n}\n\nfunction filterMessagesByActorEnemy(messages: ChatMessagePF2e[]): ChatMessagePF2e[] {\n return messages.filter((message) => message.target?.actor && message.actor?.isEnemyOf(message.target?.actor));\n}\n\nfunction findLastMessageWithTotalGreaterOrEqual(\n messages: ChatMessagePF2e[],\n total: number,\n): ChatMessagePF2e | undefined {\n return messages.findLast((message) => message.rolls?.[0]?.total >= total);\n}\n\nexport function checkIfLatestDamageMessageIsCriticalHitByEnemy(actor: ActorPF2e, option: string): boolean {\n const hp = actor.attributes.hp;\n if (hp && hp.value && game.messages.contents.length > 0 && isRelevantForActor(actor.type, option)) {\n const relevant = getRelevantMessages(actor);\n const isDamageRoll = filterMessagesByContextType(relevant, \"damage-roll\");\n const isDamagingStrike = filterMessagesByStrikeDamaging(isDamageRoll);\n const attackerIsEnemy = filterMessagesByActorEnemy(isDamagingStrike);\n const criticalSuccess = filterMessagesByCriticalSuccess(attackerIsEnemy);\n const bigEnough = findLastMessageWithTotalGreaterOrEqual(criticalSuccess, hp.value);\n const chatMessagePF2e = bigEnough === isDamageRoll?.reverse()[0] ? bigEnough : null;\n return chatMessagePF2e !== null && chatMessagePF2e !== undefined;\n }\n return false;\n}\n\nfunction filterMessagesByCriticalSuccess(messages: ChatMessagePF2e[]): ChatMessagePF2e[] {\n return messages.filter((message) => systems.getFlag(message, \"context.outcome\") === \"criticalSuccess\");\n}\n\nexport function handleOrcFerocity(\n actor: ActorPF2e,\n update: Record,\n effectsToCreate: any[],\n name: string,\n shouldIncreaseWounded = true,\n hpNowAboveZero = false,\n): { shouldIncreaseWounded: boolean; hpNowAboveZero: boolean } {\n const orcFerocity = actor.itemTypes.feat.find((feat) => feat.slug === \"orc-ferocity\");\n const orcFerocityUsed: any = actor.itemTypes.effect.find((effect) => effect.slug === \"orc-ferocity-used\");\n const incredibleFerocity = actor.itemTypes.feat.find((feat) => feat.slug === \"incredible-ferocity\");\n const undyingFerocity = actor.itemTypes.feat.find((feat) => feat.slug === \"undying-ferocity\");\n const rampagingFerocity = actor.itemTypes.feat.find((feat) => feat.slug === \"rampaging-ferocity\");\n if (orcFerocity && (!orcFerocityUsed || orcFerocityUsed.isExpired)) {\n fu.setProperty(update, \"system.attributes.hp.value\", 1);\n if (undyingFerocity) {\n fu.setProperty(update, \"system.attributes.hp.temp\", Math.max(actor.level, actor.hitPoints?.temp ?? 0));\n }\n\n shouldIncreaseWounded = true;\n\n const effect: any = {\n type: \"effect\",\n name: game.i18n.localize(`${MODULENAME}.effects.orcFerocityUsed`),\n img: `systems/${game.system.id}/icons/default-icons/alternatives/ancestries/orc.svg`,\n system: {\n slug: \"orc-ferocity-used\",\n tokenIcon: {\n show: false,\n },\n duration: {\n value: incredibleFerocity ? 1 : 24,\n unit: \"hours\",\n sustained: false,\n expiry: \"turn-start\",\n },\n },\n };\n effectsToCreate.push(effect);\n\n if (rampagingFerocity) {\n createStatusEffectChatMessage(\n actor,\n name,\n \"autoGainDyingAtZeroHP.orcFerocityMessage\",\n \"handleOrcFerocity ChatMessage\",\n );\n }\n\n hpNowAboveZero = true;\n }\n return { shouldIncreaseWounded, hpNowAboveZero };\n}\n\nexport function handleDeliberateDeath(actor: ActorPF2e, effectsToCreate: any[], name: string): void {\n const deliberateDeath = actor.itemTypes.feat.find((feat) => feat.slug === \"deliberate-death\");\n const deliberateDeathUsed: any = actor.itemTypes.effect.find((effect) => effect.slug === \"deliberate-death-used\");\n if (deliberateDeath && (!deliberateDeathUsed || deliberateDeathUsed.isExpired)) {\n const effect: any = {\n type: \"effect\",\n name: game.i18n.localize(`${MODULENAME}.effects.deliberateDeathUsed`),\n img: \"icons/skills/melee/strike-dagger-skull-white.webp\",\n system: {\n slug: \"deliberate-death-used\",\n tokenIcon: {\n show: false,\n },\n duration: {\n value: 24,\n unit: \"hours\",\n sustained: false,\n expiry: \"turn-start\",\n },\n },\n };\n effectsToCreate.push(effect);\n\n createStatusEffectChatMessage(\n actor,\n name,\n \"autoGainDyingAtZeroHP.deliberateDeathMessage\",\n \"handleDeliberateDeath ChatMessage\",\n );\n }\n}\n\nexport async function handleDyingOnZeroHP(\n actor: any,\n update: Record,\n hp: number,\n updateHp: number,\n autogainDying: string,\n): Promise {\n if (!shouldIHandleThis(actor) || hp <= 0 || updateHp > 0) {\n return updateHp > 0;\n }\n\n const name = `${actor.token?.name ?? actor.name}`;\n let shouldIncreaseWounded = false;\n let dyingCounter = 0;\n let hpNowAboveZero = false;\n const effectsToCreate: any[] = [];\n const nonlethalOption = getModuleSetting(\"nonLethalIsNotLethal\");\n\n ({ shouldIncreaseWounded, hpNowAboveZero } = handleOrcFerocity(\n actor,\n update,\n effectsToCreate,\n name,\n shouldIncreaseWounded,\n hpNowAboveZero,\n ));\n\n handleDeliberateDeath(actor, effectsToCreate, name);\n\n if (!hpNowAboveZero && isRelevantForActor(actor.type, autogainDying)) {\n if (autogainDying?.startsWith(\"addWoundedLevel\")) {\n dyingCounter = (actor.getCondition(\"wounded\")?.value ?? 0) + 1;\n } else {\n dyingCounter = 1;\n }\n }\n\n if (checkIfLatestDamageMessageIsCriticalHitByEnemy(actor, autogainDying)) {\n dyingCounter += 1;\n }\n\n if (hpNowAboveZero) {\n await actor.update(update);\n }\n\n if (shouldIncreaseWounded) {\n await actor.increaseCondition(\"wounded\");\n }\n\n if (isRelevantForActor(actor.type, nonlethalOption)) {\n if (!hpNowAboveZero && checkIfLatestDamageMessageIsNonlethal(actor, nonlethalOption)) {\n if (!actor.hasCondition(\"unconscious\")) {\n await actor.toggleCondition(\"unconscious\");\n }\n dyingCounter = 0;\n }\n }\n\n fireAndForget(handleDying(dyingCounter, 0, actor), \"handleDyingOnZeroHP handleDying\");\n\n if (effectsToCreate.length > 0) {\n await actor.createEmbeddedDocuments(\"Item\", effectsToCreate);\n }\n\n return hpNowAboveZero;\n}\n\nexport async function giveWoundedWhenDyingRemoved(item: ItemPF2e): Promise {\n const actor = item.parent;\n if (isFirstGM() && item.slug === \"dying\" && actor) {\n const items: any = actor.items;\n let bounceBack: any = false,\n bounceBackUsed: any = false,\n numbToDeath: any = false,\n numbToDeathUsed: any = false;\n if (items) {\n bounceBack = items.find((feat: { slug: string }) => feat.slug === \"bounce-back\"); // TODO https://2e.aonprd.com/Feats.aspx?ID=1441\n bounceBackUsed = actor.itemTypes.effect.find((effect) => effect.slug === \"bounce-back-used\") ?? false;\n\n numbToDeath = items.find((feat: { slug: string }) => feat.slug === \"numb-to-death\"); // TODO https://2e.aonprd.com/Feats.aspx?ID=1182\n numbToDeathUsed = actor.itemTypes.effect.find((effect) => effect.slug === \"numb-to-death-used\") ?? false;\n }\n const name = `${actor.token?.name ?? actor.name}`;\n\n if (numbToDeath && (!numbToDeathUsed || numbToDeathUsed.isExpired)) {\n const effect: any = {\n type: \"effect\",\n name: game.i18n.localize(`${MODULENAME}.effects.numbToDeathUsed`),\n img: \"icons/magic/death/hand-dirt-undead-zombie.webp\",\n system: {\n slug: \"numb-to-death-used\",\n tokenIcon: {\n show: false,\n },\n duration: {\n value: 24,\n unit: \"hours\",\n sustained: false,\n expiry: \"turn-start\",\n },\n },\n };\n\n createStatusEffectChatMessage(\n actor,\n name,\n \"giveWoundedWhenDyingRemoved.numbToDeathMessage\",\n \"giveWoundedWhenDyingRemoved ChatMessage\",\n );\n\n await actor.createEmbeddedDocuments(\"Item\", [effect]);\n } else if (bounceBack && (!bounceBackUsed || bounceBackUsed.isExpired)) {\n const effect: any = {\n type: \"effect\",\n name: game.i18n.localize(`${MODULENAME}.effects.bounceBackUsed`),\n img: \"icons/magic/life/ankh-gold-blue.webp\",\n system: {\n slug: \"bounce-back-used\",\n tokenIcon: {\n show: false,\n },\n duration: {\n value: 24,\n unit: \"hours\",\n sustained: false,\n expiry: \"turn-start\",\n },\n },\n };\n\n await actor.createEmbeddedDocuments(\"Item\", [effect]);\n } else {\n await item.parent?.increaseCondition(\"wounded\");\n }\n }\n}\n\nexport async function giveUnconsciousIfDyingRemovedAt0HP(item: ItemPF2e): Promise {\n const actor = item.parent;\n if (\n isFirstGM() &&\n item.slug === \"dying\" &&\n getModuleSetting(\"giveUnconsciousIfDyingRemovedAt0HP\") &&\n (actor.system).attributes?.hp?.value === 0 &&\n !actor.hasCondition(\"unconscious\")\n ) {\n if (!actor.hasCondition(\"unconscious\")) {\n await item.parent?.toggleCondition(\"unconscious\");\n }\n }\n}\n\nexport function dyingHandlingCreateChatMessageHook(message: ChatMessagePF2e): void {\n const autoGainDying = getModuleSetting(\"autoGainDyingIfTakingDamageWhenAlreadyDying\");\n if (autoGainDying && !autoGainDying.startsWith(\"no\")) {\n const actor = message.actor;\n if (actor && shouldIHandleThis(actor)) {\n if (message.content?.includes(\"damage-taken\")) {\n const now = Date.now();\n const flag = getModuleFlag(actor, \"dyingLastApplied\") || now;\n logDebug(`dyingLastApplied is ${flag}, now is ${now}`);\n // Ignore this if it occurs within last few seconds of the last time we applied dying\n const notTooSoon = !flag?.between(now - 4000, now);\n if (notTooSoon) {\n const originalDyingCounter = actor?.getCondition(\"dying\")?.value ?? 0;\n let dyingCounter = 0;\n if (!autoGainDying.startsWith(\"no\") && originalDyingCounter > 0) {\n const wasCritical = checkIfLatestDamageMessageIsCriticalHitByEnemy(actor, autoGainDying);\n\n if (isRelevantForActor(actor.type, autoGainDying)) {\n dyingCounter = dyingCounter + 1;\n\n if (wasCritical) {\n dyingCounter = dyingCounter + 1;\n }\n }\n logDebug(\n `Before handleDying dyingLastApplied is ${flag}, now is ${now}, dyingCounter was ${originalDyingCounter} will increase by ${dyingCounter}`,\n );\n\n fireAndForget(\n handleDying(dyingCounter, originalDyingCounter, actor),\n \"dyingHandlingCreateChatMessageHook handleDying\",\n );\n }\n }\n }\n }\n }\n}\n\nexport function checkIfLatestDamageMessageIsNonlethal(actor: ActorPF2e, option: string): boolean {\n const hp = actor.attributes.hp;\n if (hp && hp.value && game.messages.contents.length > 0 && isRelevantForActor(actor.type, option)) {\n const relevant = getRelevantMessages(actor);\n const lastDamageRoll = relevant.findLast(\n (message) => systems.getFlag(message, \"context.type\") === \"damage-roll\",\n );\n const totalDamage = lastDamageRoll?.rolls?.[0]?.total ?? 0;\n const isNonlethal = lastDamageRoll\n ? (systems.getFlag(lastDamageRoll, \"context.options\") ?? []).includes(\"nonlethal\")\n : false;\n return (totalDamage >= hp.value && isNonlethal) ?? false;\n }\n return false;\n}\n","import { ActorPF2e, ChatMessagePF2e, TokenDocumentPF2e } from \"foundry-pf2e\";\nimport { MODULENAME } from \"../../constants.ts\";\nimport { getModuleSetting, shouldIHandleThis } from \"../../utils.ts\";\nimport * as systems from \"../../utils/systems.ts\";\n\nfunction ignoreDeadEidolon(actor: ActorPF2e) {\n return actor?.traits.has(\"eidolon\") && getModuleSetting(\"reminderCannotAttackIgnoreDeadEidolon\");\n}\n\nexport function checkAttackValidity(message: ChatMessagePF2e, cancelAttack: boolean): boolean {\n if (!shouldBeChecked(message)) return true;\n\n const token = getSpeakerToken(message);\n\n const reason = getAttackReason(\n token,\n // @ts-expect-error TODO Fix typing\n systems.getFlag(message, \"context.options\")?.filter((o) => o.startsWith(\"action:\")),\n );\n\n if (reason) {\n // @ts-expect-error TODO Fix typing\n notifyUser(token, reason, systems.getFlag(message, \"context.title\"), cancelAttack);\n return false;\n }\n\n return true;\n}\n\nfunction getSpeakerToken(message: ChatMessagePF2e): TokenDocumentPF2e {\n return canvas?.scene?.tokens.get(message.speaker.token);\n}\n\nfunction shouldBeChecked(message: ChatMessagePF2e): boolean {\n const context = systems.getFlag(message, \"context\") ?? {};\n // @ts-expect-error TODO Fix typing\n const traits = context?.traits;\n\n const flag = systems.getFlag(message, \"context.type\");\n return (\n message.actor &&\n shouldIHandleThis(message.actor) &&\n message.flags &&\n message.author &&\n [\"spell-attack-roll\", \"attack-roll\", \"skill-check\"].includes(flag) &&\n traits?.some((t: string) => t === \"attack\")\n );\n}\n\nfunction getAttackReason(token: TokenDocumentPF2e, actions: string[]): string {\n const actor = token?.actor;\n if (!actor) return \"\";\n const conditionReasons = {\n dead: `${MODULENAME}.SETTINGS.reminderCannotAttack.dead`,\n hasNoHp: `${MODULENAME}.SETTINGS.reminderCannotAttack.hasNoHp`,\n defeated: `${MODULENAME}.SETTINGS.reminderCannotAttack.defeated`,\n unconscious: `${MODULENAME}.SETTINGS.reminderCannotAttack.unconscious`,\n dying: `${MODULENAME}.SETTINGS.reminderCannotAttack.dying`,\n petrified: `${MODULENAME}.SETTINGS.reminderCannotAttack.petrified`,\n restrained: `${MODULENAME}.SETTINGS.reminderCannotAttack.restrained`,\n };\n\n if (actor?.isDead && !ignoreDeadEidolon(actor)) {\n return conditionReasons.dead;\n } else if ((actor?.hitPoints?.value ?? 0) <= 0 && !ignoreDeadEidolon(actor) && actor?.type !== \"hazard\") {\n return conditionReasons.hasNoHp;\n } else if (actor?.hasCondition(\"dying\") && !ignoreDeadEidolon(actor)) {\n return conditionReasons.dying;\n } else if (game.combats.active?.combatant?.token === token && game.combats.active.combatant.defeated) {\n return conditionReasons.defeated;\n } else if (actor?.hasCondition(\"unconscious\")) {\n return conditionReasons.unconscious;\n } else if (actor?.hasCondition(\"petrified\")) {\n return conditionReasons.petrified;\n } else if (\n actor?.hasCondition(\"restrained\") &&\n ![\"action:escape\", \"action:force-open\"].some((a) => actions.includes(a))\n ) {\n return conditionReasons.restrained;\n }\n return \"\";\n}\n\nfunction notifyUser(token: TokenDocumentPF2e, reason: string, title: string, cancelAttack: boolean) {\n const reasonKey = cancelAttack ? \"reminderCannotAttack.error\" : \"reminderCannotAttack.info\";\n const actorName = token.actor?.name || \"(unknown)\";\n\n ui.notifications[cancelAttack ? \"error\" : \"info\"](generateNotificationMessage(title, actorName, reason, reasonKey));\n}\n\nfunction generateNotificationMessage(title: string, actorName: string, reason: string, reasonKey: string): string {\n return game.i18n.format(`${MODULENAME}.SETTINGS.${reasonKey}`, {\n title,\n actorName,\n reason: game.i18n.localize(reason),\n });\n}\n","import { fireAndForget, minionsInCurrentScene, shouldIHandleThis } from \"../../utils.ts\";\nimport { isAllowedFor } from \"../../utils/settings.ts\";\nimport { MODULENAME } from \"../../constants.ts\";\nimport { ActorPF2e, ChatContextFlag, ChatMessagePF2e, CombatantPF2e, UserPF2e } from \"foundry-pf2e\";\nimport * as systems from \"../../utils/systems.ts\";\n\nexport function actionsReminder(combatant: CombatantPF2e, reduction = 0): void {\n const actor = combatant.actor;\n if (actor && shouldIHandleThis(actor)) {\n if (shouldShowActionReminder(actor, reduction)) {\n const actionsMessage = `${combatant.token?.name} has ${Math.max(\n calculateMaxActions(actor) -\n Math.max(\n actor.getCondition(\"stunned\")?.value ?? 0,\n actor.getCondition(\"slowed\")?.value ?? 0,\n reduction,\n ),\n 0,\n )} actions remaining.`;\n\n fireAndForget(\n ChatMessage.create(\n {\n flavor: actionsMessage,\n whisper: !actor?.hasPlayerOwner ? ChatMessage.getWhisperRecipients(\"GM\").map((u) => u.id) : [],\n },\n {},\n ),\n \"actionsReminder ChatMessage\",\n );\n ui.notifications.info(actionsMessage);\n }\n }\n}\n\nexport function shouldShowActionReminder(actor: ActorPF2e, reduction: number): boolean {\n const showForPC = isAllowedFor(\"actionsReminderAllow\", \"player\") && actor?.hasPlayerOwner;\n const showForNPC = isAllowedFor(\"actionsReminderAllow\", \"gm\") && !actor?.hasPlayerOwner;\n return (showForPC || showForNPC) && hasConditionOrReduction(actor, reduction);\n}\n\nexport function hasConditionOrReduction(actor: ActorPF2e, reduction: number): boolean {\n return actor.hasCondition(\"stunned\", \"slowed\", \"quickened\") || reduction > 0;\n}\n\nfunction calculateMaxActions(actor: ActorPF2e) {\n return actor.traits?.has(\"minion\") ? 2 : 3 + (actor.hasCondition(\"quickened\") ? 1 : 0);\n}\n\nexport async function autoReduceStunned(combatant: CombatantPF2e, userId: string): Promise {\n if (!combatant?.actor || (userId !== game.user.id && !shouldIHandleThis(combatant?.actor))) {\n return 0;\n }\n\n let stunReduction = 0;\n const actors: ActorPF2e[] = [combatant?.actor, ...minionsInCurrentScene(combatant?.actor)];\n\n for (const actor of actors) {\n const stunned = actor.getCondition(\"stunned\")?.value ?? 0;\n if (stunned) {\n stunReduction = Math.min(stunned, calculateMaxActions(actor));\n for (let i = 0; i < stunReduction; i++) {\n await actor?.decreaseCondition(\"stunned\");\n }\n const combat = combatant?.combat;\n if (!combat) continue;\n await actor?.setFlag(MODULENAME, \"stunReduction\", {\n combat: combat.id,\n round: combat.round,\n reducedBy: stunReduction,\n });\n }\n }\n return stunReduction;\n}\n\nexport function reminderTargeting(message: ChatMessagePF2e, setting: string): boolean {\n const context: ChatContextFlag = systems.getFlag(message, \"context\");\n\n if (\n message.actor &&\n shouldIHandleThis(message.actor) &&\n message.flags &&\n message.author &&\n context &&\n context.type &&\n [\"spell-attack-roll\", \"attack-roll\"].includes(context.type)\n ) {\n const targets = (message.author).targets;\n if (!targets || targets.size === 0) {\n // @ts-expect-error TODO Fix typing\n const title = context?.title;\n\n if (setting === \"reminder\") {\n const info = game.i18n.format(`${MODULENAME}.SETTINGS.reminderTargeting.info`, { title });\n ui.notifications.info(info);\n } else if (setting === \"mustTarget\") {\n const error = game.i18n.format(`${MODULENAME}.SETTINGS.reminderTargeting.error`, { title });\n ui.notifications.error(error);\n return false;\n }\n }\n }\n return true;\n}\n","import { getModuleSetting, isFirstGM } from \"../../utils.ts\";\nimport { ActorPF2e, ChatMessagePF2e, TokenDocumentPF2e } from \"foundry-pf2e\";\nimport { MODULENAME } from \"../../constants.ts\";\nimport * as systems from \"../../utils/systems.ts\";\n\nexport async function reminderBreathWeapon(message: ChatMessagePF2e): Promise {\n const messageContent = message.content;\n const token: TokenDocumentPF2e = canvas?.scene?.tokens.get(message.speaker.token);\n if (isFirstGM() && messageContent && game.combats && game.combats.active && token?.actor) {\n let rounds;\n if (\n messageContent.includes(\"fa-solid fa-dice-d20\") &&\n messageContent.includes(\"data-roll\") &&\n messageContent.includes(\"data-tooltip\")\n ) {\n const regex = /<\\/i>(\\d).* rounds/;\n const matches = messageContent.match(regex);\n if (matches && matches.length > 1) {\n rounds = Number(matches[1]);\n }\n // Skip dragon form and the like\n } else if (!systems.getFlag(message, \"origin.rollOptions\")?.includes(\"polymorph\")) {\n const gmRollTagMatch = messageContent.match(/]*class=\"inline-roll gmroll\"[^>]*>/);\n const gmRollFormulaMatch = gmRollTagMatch?.[0]?.match(/data-formula=\"(1d\\d+)\"/);\n if (gmRollFormulaMatch?.[1]) {\n const formula = gmRollFormulaMatch[1];\n if (Roll.validate(formula)) {\n const roll = await new Roll(formula).roll();\n rounds = roll.total;\n }\n } else {\n const diceFormulaMatch = messageContent.match(/1d([46])( rounds| recharge|<\\/a> rounds)/i);\n if (diceFormulaMatch?.[1]) {\n const formula = `1d${diceFormulaMatch[1]}`;\n if (Roll.validate(formula)) {\n const roll = await new Roll(formula).roll();\n rounds = roll.total;\n }\n }\n }\n }\n if (rounds) {\n const data: any = await getEffectDetails(token.actor, messageContent, rounds);\n await token.actor?.createEmbeddedDocuments(\"Item\", [data]);\n }\n }\n}\n\nasync function getEffectDetails(activeActor: ActorPF2e, messageContent: string, diceValue: number) {\n const titleRetrieved = messageContent.match(/>(.*?) ${game.i18n.localize(`${MODULENAME}.SETTINGS.reminderBreathWeapon.name`)}

`,\n },\n source: {\n value: game.i18n.localize(`${MODULENAME}.SETTINGS.reminderBreathWeapon.defaultName`),\n },\n rules: [],\n slug: `xdy-breath-weapon-reminder-${fu.randomID()}`,\n unidentified:\n getModuleSetting(\"reminderBreathWeaponHidden\") &&\n !game.actors?.party?.members.map((m) => m?.id).includes(activeActor.id),\n traits: {\n value: [],\n },\n level: {\n value: activeActor.level ?? 0,\n },\n badge: null,\n context: null,\n },\n };\n}\n","import { ChatMessagePF2e } from \"foundry-pf2e\";\nimport * as systems from \"../utils/systems.ts\";\nimport { fireAndForget, getModuleFlag, getModuleSetting, isActuallyDamageRoll } from \"../utils.ts\";\nimport { autoRollDamage, evictDamageHandlerCaches } from \"../feature/damageHandler/index.ts\";\nimport { dyingHandlingCreateChatMessageHook } from \"../feature/damageHandler/dyingHandling.ts\";\nimport { checkAttackValidity } from \"../feature/reminders/checkAttackValidity.ts\";\nimport { reminderTargeting } from \"../feature/reminders/index.ts\";\nimport { reminderBreathWeapon } from \"../feature/reminders/reminderBreathWeapon.ts\";\n\nfunction isDamageTaken(message: ChatMessagePF2e): boolean {\n return systems.getFlag(message, \"context.type\") === \"damage-taken\";\n}\n\nexport function createChatMessageHook(message: ChatMessagePF2e): void {\n evictDamageHandlerCaches();\n const reminderCancelAttack = getModuleSetting(\"reminderCannotAttack\");\n if (reminderCancelAttack === \"reminder\") {\n checkAttackValidity(message, false);\n }\n\n const reminderTargetingSetting = getModuleSetting(\"reminderTargeting\");\n if ([\"no\", \"reminder\"].includes(reminderTargetingSetting)) {\n reminderTargeting(message, reminderTargetingSetting);\n }\n\n // Early return for damage rolls or damage taken messages\n const isDamageRoll = isActuallyDamageRoll(message);\n const isDamage = isDamageRoll || isDamageTaken(message);\n\n if (!isDamage) {\n const skipAutoRoll = getModuleFlag(message, \"noAutoDamageRoll\");\n if (!skipAutoRoll) {\n fireAndForget(autoRollDamage(message), \"autoRollDamage\");\n }\n\n // Check if we need to remind about breath weapon\n const reminderBreathWeaponEnabled = getModuleSetting(\"reminderBreathWeapon\");\n if (reminderBreathWeaponEnabled) {\n fireAndForget(reminderBreathWeapon(message), \"reminderBreathWeapon\");\n }\n }\n\n // Always process dying handling\n dyingHandlingCreateChatMessageHook(message);\n}\n","import { MODULENAME } from \"../../constants.ts\";\nimport { getModuleSetting, isActuallyDamageRoll, NOT_MYSTIFIED_VALUE } from \"../../utils.ts\";\nimport { ChatMessagePF2e, CreaturePF2e, PhysicalItemPF2e, ScenePF2e, TokenDocumentPF2e } from \"foundry-pf2e\";\n\nexport function chatCardDescriptionCollapse(html: HTMLElement): void {\n if (!(html instanceof HTMLElement)) {\n return;\n }\n\n const hasCardContent = html.querySelectorAll(\".card-content:not(span.flavor-text *)\");\n if (hasCardContent.length > 0) {\n const effectItem = game.i18n.localize(`${MODULENAME}.effectItem`);\n if (getModuleSetting(\"autoCollapseItemChatCardContent\") === \"collapsedDefault\") {\n hasCardContent.forEach((content) => ((content as HTMLElement).style.display = \"none\"));\n const cardContentSiblings = (hasCardContent[0] as HTMLElement).parentElement?.children;\n if (cardContentSiblings?.[0]) {\n cardContentSiblings[0].insertAdjacentHTML(\"beforeend\", eye);\n }\n if (getModuleSetting(\"autoCollapseItemChatCardMoveEffectLinks\")) {\n const linksToMove: any[] = [];\n const pTags = Array.from(html.getElementsByTagName(\"p\"));\n for (const pTag of pTags) {\n const contentLink = pTag.querySelector(\"a.content-link\");\n if (contentLink && contentLink?.getAttribute(\"data-tooltip\")?.includes(effectItem)) {\n linksToMove.push(pTag);\n }\n }\n\n const chatMessageContainer = html.closest(\".chat-message\");\n if (chatMessageContainer && linksToMove.length > 0) {\n linksToMove[0].classList.add(\"item-block-line\");\n // Append all linksToMove to the end of the chatMessageContainer\n chatMessageContainer.append(...linksToMove);\n }\n }\n }\n\n // Add listener for hide/unhide click\n const header = html.querySelector(\".card-header\");\n if (header instanceof HTMLElement) {\n header.addEventListener(\"click\", (event) => {\n event.preventDefault();\n header\n .closest(\".chat-message\")\n ?.querySelectorAll(\".card-content\")\n ?.forEach((content) => {\n if (content instanceof HTMLElement)\n content.style.display = content.style.display === \"none\" ? \"block\" : \"none\";\n });\n toggleEyes(header);\n });\n }\n }\n}\n\nfunction toggleEyes(html: HTMLElement) {\n const hasEye = html.querySelectorAll(\".fa-eye\");\n const hasEyeSlash = html.querySelectorAll(\".fa-eye-slash\");\n for (const eye of Array.from(hasEye)) {\n eye.classList.toggle(\"fa-eye-slash\");\n eye.classList.toggle(\"fa-eye\");\n }\n for (const eye of Array.from(hasEyeSlash)) {\n eye.classList.toggle(\"fa-eye-slash\");\n eye.classList.toggle(\"fa-eye\");\n }\n}\n\nfunction handleRollNoteToggling(html: HTMLElement) {\n let note;\n const hasNote = html.querySelectorAll(\".roll-note\");\n for (note of Array.from(hasNote)) {\n (note as HTMLElement).style.display = (note as HTMLElement).style.display === \"none\" ? \"block\" : \"none\";\n }\n toggleEyes(html);\n}\n\nexport function chatActionCardDescriptionCollapse(html: HTMLElement): void {\n const hasAction = html.querySelectorAll(\".action\");\n if (hasAction.length > 0) {\n const rollNotes = html.querySelectorAll(\".roll-note\");\n if (rollNotes.length > 0) {\n if (getModuleSetting(\"autoCollapseItemActionChatCardContent\") === \"collapsedDefault\") {\n for (const note of Array.from(rollNotes)) {\n (note as HTMLElement).style.display = \"none\";\n }\n\n const actionSiblings = (hasAction[0] as HTMLElement).parentElement?.children;\n if (actionSiblings?.[1]) {\n actionSiblings[1].insertAdjacentHTML(\"beforeend\", eye);\n }\n }\n html.addEventListener(\"click\", (event) => {\n const target = event.target as HTMLElement;\n if (target?.matches(\"h4.action, .fa-eye, .fa-eye-slash, strong\")) {\n event.preventDefault();\n handleRollNoteToggling(html);\n }\n });\n }\n }\n}\n\nconst eye = ' ';\n\nexport function chatAttackCardDescriptionCollapse(html: HTMLElement): void {\n const hasRollNote = html.querySelectorAll(\".roll-note\");\n if (hasRollNote.length > 0) {\n if (getModuleSetting(\"autoCollapseItemAttackChatCardContent\") === \"collapsedDefault\") {\n for (const note of hasRollNote) {\n (note as HTMLElement).style.display = \"none\";\n }\n\n hasRollNote[0].parentNode?.parentNode?.children[0].insertAdjacentHTML(\"beforeend\", eye);\n }\n html.addEventListener(\"click\", (event) => {\n const target = event.target as HTMLElement;\n if (target.matches(\"h4.action, .fa-eye, .fa-eye-slash, strong\")) {\n event.preventDefault();\n handleRollNoteToggling(html);\n }\n });\n }\n}\n\n// Cache for recent damage messages to avoid filtering all messages repeatedly\nconst recentDamageMessages = new Set();\nconst MAX_RECENT_MESSAGES = 10;\n\n// Update recent damage messages when a new message is created\nHooks.on(\"createChatMessage\", (message: ChatMessagePF2e) => {\n if (isActuallyDamageRoll(message)) {\n // Add to recent damage messages\n recentDamageMessages.add(message.id);\n\n // Keep only the most recent messages\n if (recentDamageMessages.size > MAX_RECENT_MESSAGES) {\n const toRemove = Array.from(recentDamageMessages)[0];\n recentDamageMessages.delete(toRemove);\n }\n }\n});\n\nHooks.on(\"deleteChatMessage\", (message: ChatMessagePF2e) => {\n recentDamageMessages.delete(message.id);\n});\n\nexport function damageCardExpand(message: ChatMessagePF2e, html: HTMLElement, expandDmg: string): void {\n const diceTooltips = html.querySelectorAll(\".dice-tooltip\");\n\n // If no dice tooltips, nothing to do\n if (diceTooltips.length === 0) return;\n\n // Always expand if setting is \"expandedAll\"\n if (expandDmg === \"expandedAll\") {\n diceTooltips.forEach((diceTooltip: HTMLElement) => (diceTooltip.style.display = \"block\"));\n return;\n }\n\n // For \"expandedNew\" settings, check if this message is in the recent damage messages\n if (expandDmg.startsWith(\"expandedNew\")) {\n // For \"expandedNewest\", only expand the most recent message\n if (expandDmg.endsWith(\"est\")) {\n // Get the most recent damage message\n const mostRecentMessage = Array.from(recentDamageMessages).pop();\n if (message.id === mostRecentMessage) {\n diceTooltips.forEach((diceTooltip: HTMLElement) => (diceTooltip.style.display = \"block\"));\n }\n } else {\n // For \"expandedNew\", expand if message is in recent damage messages\n if (recentDamageMessages.has(message.id)) {\n diceTooltips.forEach((diceTooltip: HTMLElement) => (diceTooltip.style.display = \"block\"));\n }\n }\n }\n}\n\nconst RARITY_THRESHOLD_SUFFIXES = {\n common: \"Common\",\n uncommon: \"Uncommon\",\n rare: \"Rare\",\n unique: \"Unique\",\n} as const;\n\ntype RarityKey = keyof typeof RARITY_THRESHOLD_SUFFIXES;\nconst RARITY_KEYS: RarityKey[] = [\"common\", \"uncommon\", \"rare\", \"unique\"];\n\nfunction getThresholdSettingKey(rarity: RarityKey, usingPartyLevel: boolean): `mystifyThreshold${string}${string}` {\n const suffix = usingPartyLevel ? \"Pl\" : \"Abs\";\n return `mystifyThreshold${RARITY_THRESHOLD_SUFFIXES[rarity]}${suffix}`;\n}\n\nconst PHYSICAL_ITEM_TYPES = new Set([\n \"armor\",\n \"shield\",\n \"consumable\",\n \"backpack\",\n \"book\",\n \"equipment\",\n \"treasure\",\n \"weapon\",\n]);\n\n/**\n * Mystify NPC items using per-rarity level thresholds.\n *\n * Thresholds are read from settings (or passed as override). When usingPartyLevel is true, thresholds are\n * offsets from party level; when false, they are absolute item levels.\n * Unique items with threshold -1 are always mystified.\n *\n * @param actor - The NPC actor whose items to mystify.\n * @param usingPartyLevel - Whether thresholds are party-level offsets. Defaults to the setting.\n * @param thresholds - Optional per-rarity threshold overrides. Defaults to settings.\n */\nexport async function mystifyNpcItemsByRarity(\n actor: CreaturePF2e | null>,\n usingPartyLevel: boolean = getModuleSetting(\n \"npcMystifyAllPhysicalMagicalItemsOfThisLevelOrGreaterUsingPartyLevel\",\n ),\n thresholds: Partial> = {},\n): Promise {\n if (!actor?.items) {\n return;\n }\n\n const baseLevel = usingPartyLevel ? (game.actors?.party?.level ?? 0) : 0;\n\n const resolvedThresholds: Record = {};\n for (const rarity of RARITY_KEYS) {\n resolvedThresholds[rarity] =\n thresholds[rarity] ??\n Number.parseInt(getModuleSetting(getThresholdSettingKey(rarity, usingPartyLevel)));\n }\n\n const itemUpdates: {\n _id: string;\n \"system.identification.status\": string;\n \"system.identification.unidentified\": unknown;\n }[] = [];\n\n for (const item of actor.items) {\n if (!PHYSICAL_ITEM_TYPES.has(item.type)) continue;\n\n const physicalItem = item as unknown as PhysicalItemPF2e;\n if (\n !physicalItem.isIdentified ||\n physicalItem.isTemporary ||\n !(physicalItem.isMagical || physicalItem.isAlchemical)\n )\n continue;\n\n const threshold = resolvedThresholds[physicalItem.rarity];\n if (threshold === undefined || threshold === Number(NOT_MYSTIFIED_VALUE)) continue;\n\n const effectiveThreshold = baseLevel + threshold;\n if (physicalItem.level < effectiveThreshold) continue;\n\n itemUpdates.push({\n _id: item.id,\n \"system.identification.status\": \"unidentified\",\n \"system.identification.unidentified\": physicalItem.getMystifiedData(\"unidentified\"),\n });\n }\n\n if (itemUpdates.length > 0) {\n await actor.updateEmbeddedDocuments(\"Item\", itemUpdates);\n }\n}\n","import { TokenDocumentPF2e } from \"foundry-pf2e\";\nimport { NPC_TYPE } from \"../xdy-pf2e-workbench.ts\";\n\nimport * as systems from \"../utils/systems.ts\";\nimport { fireAndForget, getModuleSetting } from \"../utils.ts\";\nimport { tokenCreateMystification } from \"../feature/tokenMystificationHandler/index.ts\";\nimport { mystifyNpcItemsByRarity } from \"../feature/qolHandler/index.ts\";\n\nexport async function createTokenHook(token: TokenDocumentPF2e, ..._args: unknown[]): Promise {\n if (game.user?.isGM && getModuleSetting(\"npcMystifier\")) {\n fireAndForget(tokenCreateMystification(token), \"tokenCreateMystification\");\n }\n\n if (\n game.user?.isGM &&\n systems.getSystemSetting(\"automation\", \"lootableNPCs\") &&\n getModuleSetting(\"npcMystifyAllPhysicalMagicalItems\") === \"onScene\" &&\n token.actor &&\n token.actor.isOfType(NPC_TYPE) &&\n token.actor.items &&\n token.actor.items.size > 0\n ) {\n await mystifyNpcItemsByRarity(token.actor);\n }\n}\n","import { EncounterPF2e, PhysicalItemPF2e } from \"foundry-pf2e\";\nimport { MODULENAME } from \"../constants.ts\";\nimport { getModuleSetting, sendHeldItemChatMessage } from \"../utils.ts\";\nimport { clearToolbeltCaches } from \"../feature/damageHandler/toolbeltIntegration.ts\";\n\nexport async function deleteCombatHook(encounter: EncounterPF2e, _options: object): Promise {\n clearToolbeltCaches();\n\n if (getModuleSetting(\"sheatheHeldItemsAfterEncounter\")) {\n await sheatheHeldItemsAfterEncounter(encounter);\n }\n}\n\nasync function sheatheHeldItemsAfterEncounter(encounter: EncounterPF2e) {\n const itemTypes = getModuleSetting(\"sheatheHeldItemsAfterEncounterTypes\")\n .split(\",\")\n .map((t) => t.trim())\n .filter((t) => t);\n\n for (const combatant of encounter.combatants) {\n const actor = combatant.actor;\n if (!actor) {\n continue;\n }\n const items = actor.items?.filter((i) => (i as PhysicalItemPF2e).isHeld);\n if (!items || items.length === 0) {\n continue;\n }\n\n const itemsToSheathe = items.filter((i) => itemTypes.includes(i.type));\n if (itemsToSheathe.length > 0) {\n for (const item of itemsToSheathe) {\n // @ts-expect-error TODO fix typing\n await actor.changeCarryType(item, { carryType: \"worn\", handsHeld: 0, inSlot: false });\n }\n sendHeldItemChatMessage(\n actor,\n itemsToSheathe,\n `${MODULENAME}.SETTINGS.sheatheHeldItemsAfterEncounter.message`,\n \"sheatheHeldItems ChatMessage\",\n );\n }\n }\n}\n","import { ItemPF2e } from \"foundry-pf2e\";\nimport { itemHandlingItemHook } from \"../feature/damageHandler/dyingHandling.ts\";\n\nexport async function deleteItemHook(item: ItemPF2e, _options: object): Promise {\n await itemHandlingItemHook(item);\n}\n","import { ActorPF2e, CombatantPF2e } from \"foundry-pf2e\";\nimport { actorHasItemBySlug, getModuleFlag, minionsInCurrentScene, shouldIHandleThis } from \"../../utils.ts\";\n\nexport async function reduceFrightened(combatant: CombatantPF2e, userId: string): Promise {\n if (!combatant || !combatant.actor || (userId !== game.user.id && !shouldIHandleThis(combatant.actor))) {\n return;\n }\n\n const actors: ActorPF2e[] = [combatant.actor, ...minionsInCurrentScene(combatant.actor)];\n\n for (const actor of actors) {\n const minimumFrightened = getModuleFlag(actor, \"condition.frightened.min\", 0);\n const frightened = actor.getCondition(\"frightened\");\n const currentFrightened = frightened?.value ?? 0;\n const doubleFrightenReductionSlugs: string[] = [\n \"dwarven-doughtiness\",\n \"calm-and-centered\"\n ]\n\n if (frightened && currentFrightened > 0 && !frightened.isLocked) {\n const reduceBy = doubleFrightenReductionSlugs.some((slug) => actorHasItemBySlug(actor, slug)) ? 2 : 1;\n\n for (let i = 0; i < reduceBy && currentFrightened - i > minimumFrightened; i++) {\n await actor.decreaseCondition(\"frightened\");\n }\n }\n }\n}\n","import { CombatantPF2e, EncounterPF2e } from \"foundry-pf2e\";\n\nimport { fireAndForget, getModuleSetting } from \"../utils.ts\";\nimport { reduceFrightened } from \"../feature/conditionHandler/index.ts\";\n\nexport function pf2eEndTurnHook(combatant: CombatantPF2e, _combat: EncounterPF2e, userId: string): void {\n if (getModuleSetting(\"decreaseFrightenedConditionEachTurn\")) {\n fireAndForget(reduceFrightened(combatant, userId), \"reduceFrightened\");\n }\n}\n","import { CheckRoll, ResourceData } from \"foundry-pf2e\";\nimport { Rolled } from \"foundry/client/dice/roll.mts\";\nimport { getModuleSetting } from \"../utils.ts\";\n\n/** Matches `pf2e.reroll` / `pf2e.preReroll` 4th argument on pf2e v14-dev (`Check.rerollFromMessage`). */\ntype Pf2eRerollHookOptions = { keep?: \"new\" | \"higher\" | \"lower\" };\n\n/** Hero Point variant rules */\nexport function pf2eRerollHook(\n _oldRoll: Rolled,\n newRoll: Rolled,\n resource: ResourceData | null,\n hookOptions: Pf2eRerollHookOptions,\n): void {\n const keep = hookOptions.keep ?? \"new\";\n if (resource?.slug !== \"hero-points\" || keep !== \"new\") return;\n\n const die = newRoll.dice.find((d) => d instanceof foundry.dice.terms.Die && d.number === 1 && d.faces === 20);\n const result = die?.results.find((r) => r.active && r.result <= 10);\n\n // Handle Keeley's Hero Point Rule\n if (die && result && getModuleSetting(\"heroPointRules\") === \"keeleysHeroPointRule\") {\n newRoll.terms.push(\n foundry.dice.terms.OperatorTerm.fromData({ class: \"OperatorTerm\", operator: \"+\", evaluated: true }),\n foundry.dice.terms.NumericTerm.fromData({ class: \"NumericTerm\", number: 10, evaluated: true }),\n );\n // @ts-expect-error It's protected. Meh.\n newRoll._total += 10;\n newRoll.reroll();\n newRoll.options.keeleyAdd10 = true;\n } else if (die && result && getModuleSetting(\"heroPointRules\") === \"heroicRerolls\") {\n // Handle Heroic Rerolls: if d20 result < 10, set it to 10\n const oldResult = result.result;\n result.result = 10;\n // @ts-expect-error It's protected. Meh.\n newRoll._total = newRoll._total - oldResult + 10;\n newRoll.options.heroicReroll = true;\n } else if (getModuleSetting(\"heroPointRules\") === \"useHighestHeroPointRoll\") {\n // Handle useHighestHeroPointRoll setting\n hookOptions.keep = \"higher\";\n }\n}\n","import { fireAndForget } from \"../utils.ts\";\nimport {\n handlePf2eToolbeltRollSave,\n ToolbeltRollSaveHookPayload,\n} from \"../feature/damageHandler/toolbeltIntegration.ts\";\n\nexport function pf2eToolbeltRollSaveHook(payload: ToolbeltRollSaveHookPayload): void {\n fireAndForget(handlePf2eToolbeltRollSave(payload), \"pf2eToolbeltRollSaveHook\");\n}\n","import { CombatantPF2e, EncounterPF2e } from \"foundry-pf2e\";\nimport { getModuleSetting } from \"../utils.ts\";\nimport { actionsReminder, autoReduceStunned } from \"../feature/reminders/index.ts\";\n\nexport async function pf2eStartTurnHook(\n combatant: CombatantPF2e,\n _combat: EncounterPF2e,\n userId: string,\n): Promise {\n const forWhom = getModuleSetting(\"actionsReminderAllow\");\n if (getModuleSetting(\"autoReduceStunned\")) {\n const reduction = await autoReduceStunned(combatant, userId);\n if (forWhom !== \"none\") {\n actionsReminder(combatant, reduction);\n }\n } else if (forWhom !== \"none\") {\n actionsReminder(combatant, 0);\n }\n\n // TODO Handle removal of game.combats.active.combatant.defeated/unsetting of deathIcon (are those the same?) for combatants that are neither dying nor have 0 HP.\n}\n","import { getModuleSetting, housepatcher } from \"../utils.ts\";\n\nexport async function pf2eSystemReadyHook(): Promise {\n const housepatcherSetting = getModuleSetting(\"housepatcher\");\n if (game.user.isGM && housepatcherSetting) {\n await housepatcher(housepatcherSetting);\n }\n}\n","import { SpellPF2e } from \"foundry-pf2e\";\nimport { MODULENAME } from \"../../constants.ts\";\n\nconst I18N_RECALL_KNOWLEDGE = \"PF2E.RecallKnowledge.Label\";\nconst I18N_TRAIT_PREFIX = \"PF2E.Trait\";\n\nexport const TRADITION_SKILLS: Record = {\n arcane: \"arcana\",\n divine: \"religion\",\n occult: \"occultism\",\n primal: \"nature\",\n};\n\nexport function buildSpellMessage(\n originSpell: SpellPF2e | null,\n tokenName: string,\n type: string,\n tradition: string,\n spellUuid: string,\n originalContent: string,\n isBasicSave: boolean | undefined,\n showTraits: boolean,\n traitsBlocklist: string,\n): string {\n if (!originSpell) {\n return game.i18n.localize(`${MODULENAME}.SETTINGS.castPrivateSpellWithPublicMessage.secondPartNoRk`);\n }\n\n let content = buildSpellHeader(tokenName, type, tradition, spellUuid);\n\n if (showTraits) {\n content += buildTraitsSection(originSpell, traitsBlocklist);\n }\n\n content += buildRecallKnowledgeSection(originSpell, tradition);\n content += buildSaveButtonSection(originalContent, originSpell, isBasicSave);\n\n return content;\n}\n\nfunction buildSpellHeader(tokenName: string, type: string, tradition: string, spellUuid: string): string {\n const localizedTradition = localizeTrait(tradition);\n return game.i18n.localize(\n game.i18n.format(`${MODULENAME}.SETTINGS.castPrivateSpellWithPublicMessage.firstPart`, {\n tokenName,\n type,\n traditionString: localizedTradition,\n spellUUID: spellUuid,\n }),\n );\n}\n\nfunction buildTraitsSection(originSpell: SpellPF2e, blocklistRaw: string): string {\n const blocklist = blocklistRaw\n .split(\",\")\n .map((t) => t.trim())\n .filter((t) => t);\n\n const traits = Object.values(originSpell.system.traits.value)\n .map((trait) => String(trait))\n .filter((trait) => !blocklist.includes(trait))\n .map((trait) => localizeTrait(trait))\n .sort()\n .join(\", \");\n\n return game.i18n.localize(\n game.i18n.format(`${MODULENAME}.SETTINGS.castPrivateSpellWithPublicMessageShowTraits.traitPart`, { traits }),\n );\n}\n\nfunction buildRecallKnowledgeSection(originSpell: SpellPF2e, tradition: string): string {\n const level = originSpell.system.level.value;\n const dcRK = getDcRkForSpellRank(level) + getDcRkForRarity(originSpell.system.traits?.rarity ?? \"common\");\n const skill = TRADITION_SKILLS[tradition] ?? \"\";\n\n return game.i18n.format(`${MODULENAME}.SETTINGS.castPrivateSpellWithPublicMessage.secondPartRK`, {\n skill,\n dcRK,\n rk: `{${game.i18n.localize(I18N_RECALL_KNOWLEDGE)}\\t}`,\n });\n}\n\nfunction buildSaveButtonSection(\n originalContent: string,\n originSpell: SpellPF2e,\n isBasicSave: boolean | undefined,\n): string {\n const tempDiv = document.createElement(\"div\");\n tempDiv.innerHTML = originalContent;\n\n const saveButtons = tempDiv.querySelectorAll('button[data-action=\"spell-save\"]');\n if (saveButtons.length !== 1) return \"\";\n\n const saveButton = saveButtons[0];\n const dataSave = saveButton.getAttribute(\"data-save\") ?? \"\";\n const targetHelperActive = game.modules.find((s) => s.id === \"pf2e-target-helper\")?.active;\n\n if (targetHelperActive) {\n return game.i18n.format(`${MODULENAME}.SETTINGS.castPrivateSpellWithPublicMessage.noButtonSavePart`, {\n dataSave,\n basic: isBasicSave\n ? game.i18n.localize(`${MODULENAME}.SETTINGS.castPrivateSpellWithPublicMessage.basic`)\n : \"\",\n });\n }\n\n const dataDC = saveButton.getAttribute(\"data-dc\") ?? \"\";\n return buildFullSavePart(dataSave, dataDC, originSpell, isBasicSave);\n}\n\nfunction buildFullSavePart(\n dataSave: string,\n dataDC: string,\n originSpell: SpellPF2e,\n isBasicSave: boolean | undefined,\n): string {\n const traits = Object.values(originSpell.system.traits.value)\n .map((trait) => game.pf2e.system.sluggify(String(trait)))\n .sort()\n .join(\",\");\n\n return game.i18n.format(`${MODULENAME}.SETTINGS.castPrivateSpellWithPublicMessage.savePart`, {\n dataSave,\n dataDC,\n traits,\n basic: isBasicSave ? \"|basic:true\" : \"\",\n });\n}\n\nfunction getDcRkForSpellRank(rank: number): number {\n const rankToDc: Record = {\n 1: 15,\n 2: 18,\n 3: 20,\n 4: 23,\n 5: 26,\n 6: 28,\n 7: 31,\n 8: 34,\n 9: 36,\n 10: 39,\n };\n return rankToDc[rank] ?? 0;\n}\n\nfunction getDcRkForRarity(rarity: string): number {\n const rarityMapping: Record = {\n uncommon: 2,\n rare: 5,\n unique: 10,\n common: 0,\n };\n return rarityMapping[rarity] ?? 0;\n}\n\nexport function localizeTrait(trait: string): string {\n if (!trait) return trait;\n return game.i18n.localize(`${I18N_TRAIT_PREFIX}${trait.charAt(0).toUpperCase() + trait.slice(1)}`);\n}\n","import { ChatMessagePF2e, ItemPF2e, SpellPF2e } from \"foundry-pf2e\";\nimport { MODULENAME } from \"../../constants.ts\";\nimport * as systems from \"../../utils/systems.ts\";\nimport { buildSpellMessage } from \"./buildPublicSpellMessage.ts\";\nimport { getModuleSetting } from \"../../utils.ts\";\n\nconst I18N_PREFIX = `${MODULENAME}.SETTINGS.castPrivateSpellWithPublicMessage`;\n\ninterface SpellcastingSettings {\n autoRevealIfKnown: boolean;\n autoRevealMembers: boolean;\n autoRevealOverrideGMRoll: boolean;\n publicMessage: boolean;\n showToGM: boolean;\n showTraits: boolean;\n traitsBlocklist: string;\n}\n\nexport async function handlePrivateSpellcasting(\n data: Record,\n message: ChatMessagePF2e,\n): Promise {\n const settings = readSpellcastingSettings();\n const spellUuid = systems.getFlag(message, \"origin.uuid\");\n const originSpell: SpellPF2e | null = fromUuidSync(spellUuid);\n\n const partyMembersWithSpell = findPartyMembersWithSpell(originSpell);\n\n if (settings.autoRevealIfKnown && partyMembersWithSpell && partyMembersWithSpell.length > 0) {\n if (settings.autoRevealMembers) {\n showPartymembersWithSpell(message, partyMembersWithSpell, data);\n }\n if (settings.autoRevealOverrideGMRoll) {\n message.applyRollMode(\"publicroll\");\n }\n return;\n }\n\n applyPrivateWhisperToMessage(data, message);\n\n if (settings.publicMessage && !isShiftModifierActive()) {\n const { content, flags } = await buildMessageData(message, originSpell, spellUuid, data, settings);\n\n const gmId = game.users.activeGM?.id;\n const whisper = settings.showToGM ? [] : game.users.filter((u) => u.active && u.id !== gmId).map((u) => u.id);\n\n await ChatMessage.create({\n author: game.userId,\n content,\n flags,\n whisper,\n });\n }\n}\n\nfunction readSpellcastingSettings(): SpellcastingSettings {\n return {\n autoRevealIfKnown: getModuleSetting(\"castPrivateSpellAutoRevealIfKnown\"),\n autoRevealMembers: getModuleSetting(\"castPrivateSpellAutoRevealPartyMembersThatKnowSpell\"),\n autoRevealOverrideGMRoll: getModuleSetting(\"castPrivateSpellAutoRevealOverrideGMRollMode\"),\n publicMessage: getModuleSetting(\"castPrivateSpellWithPublicMessage\"),\n showToGM: getModuleSetting(\"castPrivateSpellWithPublicMessageShowToGM\"),\n showTraits: getModuleSetting(\"castPrivateSpellWithPublicMessageShowTraits\"),\n traitsBlocklist: getModuleSetting(\"castPrivateSpellWithPublicMessageTraitsBlocklist\") ?? \"\",\n };\n}\n\nfunction findPartyMembersWithSpell(originSpell: SpellPF2e | null): string[] | undefined {\n if (!originSpell) return undefined;\n return game.actors?.party?.members\n ?.filter((actor) => actor?.items?.some((item: ItemPF2e) => actorKnowsSpell(item, originSpell)))\n .map((actor) => actor?.name);\n}\n\nfunction actorKnowsSpell(item: ItemPF2e, originSpell: SpellPF2e): boolean {\n if (item.slug !== originSpell.slug) return false;\n if (!item.isOfType(\"spell\")) return false;\n\n const spell = item as unknown as SpellPF2e;\n if (!spell.spellcasting) return false;\n\n return actorHasSpellAvailable(spell);\n}\n\nfunction actorHasSpellAvailable(spell: SpellPF2e): boolean {\n const entry = spell.spellcasting;\n\n // @ts-expect-error TODO Fix typing\n if (!entry?.isPrepared) return true;\n\n const slots = entry?.system?.slots;\n if (!slots) return false;\n\n // @ts-expect-error TODO Fix typing\n return Object.values(slots).some((group: { prepared: { id: string }[] }) =>\n group.prepared.some((s) => s.id === spell.id),\n );\n}\n\nfunction showPartymembersWithSpell(\n message: ChatMessagePF2e,\n membersWithSpell: string[] | undefined,\n data: Record,\n): void {\n const tempDiv = document.createElement(\"div\");\n tempDiv.innerHTML = message.content;\n\n const firstDivider = tempDiv.querySelector(\"hr.item-block-divider\");\n if (firstDivider) {\n const knownByText = game.i18n.format(`${I18N_PREFIX}.knownBy`, {\n spellHavers: membersWithSpell?.join(\",\") ?? \"\",\n });\n\n const knownByElement = document.createElement(\"div\");\n knownByElement.innerHTML = knownByText;\n firstDivider.insertAdjacentElement(\"afterend\", knownByElement);\n }\n\n const newContent = tempDiv.innerHTML;\n if (newContent !== message.content) {\n data.content = newContent;\n message.updateSource({ content: newContent });\n }\n}\n\nasync function buildMessageData(\n message: ChatMessagePF2e,\n originSpell: SpellPF2e | null,\n spellUuid: string,\n data: Record,\n settings: SpellcastingSettings,\n): Promise<{ content: string; flags: Record> }> {\n const anonymous = game.i18n.localize(`${I18N_PREFIX}.they`);\n const tokenName = game.pf2e.settings.tokens.nameVisibility\n ? anonymous\n : (message.alias ?? message.token?.name ?? message.actor?.name ?? anonymous);\n\n const type = systems.getFlag(message, \"origin.type\") ?? \"spell\";\n const tradition = systems.getFlag(message, \"casting.tradition\") ?? \"\";\n const isBasicSave = systems.getFlag(message, \"context.options\")?.includes(\"item:defense:basic\");\n\n const originalContent = (data.content ?? \"\") as string;\n const content = buildSpellMessage(\n originSpell,\n tokenName,\n type,\n tradition,\n spellUuid,\n originalContent,\n isBasicSave,\n settings.showTraits,\n settings.traitsBlocklist,\n );\n\n const flags = buildPrivateSpellFlags(message);\n\n return { content, flags };\n}\n\nfunction buildPrivateSpellFlags(message: ChatMessagePF2e): Record> {\n return {\n \"xdy-pf2e-workbench\": {\n privateSpell: {\n originUuid: systems.getFlag(message, \"origin.uuid\"),\n originCastRank: systems.getFlag(message, \"origin.castRank\"),\n originMessageUuid: message.uuid,\n },\n },\n };\n}\n\nfunction applyPrivateWhisperToMessage(data: Record, message: ChatMessagePF2e): void {\n data.style = CONST.CHAT_MESSAGE_STYLES.OTHER;\n data.whisper = ChatMessage.getWhisperRecipients(\"GM\").map((u) => u.id) as string[];\n if (!game.user.isGM) {\n (data.whisper as string[]).push(game.user.id);\n }\n\n message.updateSource(data);\n}\n\nfunction isShiftModifierActive(): boolean {\n // TODO Doesn't work on mac?\n const keyboardManager = foundry.helpers.interaction.KeyboardManager;\n return game.keyboard.isModifierActive(keyboardManager.MODIFIER_KEYS.SHIFT);\n}\n","import { ChatMessagePF2e, UserPF2e } from \"foundry-pf2e\";\nimport { NPC_TYPE } from \"../xdy-pf2e-workbench.ts\";\n\nimport * as systems from \"../utils/systems.ts\";\nimport { fireAndForget, getModuleSetting } from \"../utils.ts\";\nimport { handlePrivateSpellcasting } from \"../feature/qolHandler/handlePrivateSpellcasting.ts\";\nimport { persistentDamageHealing } from \"../feature/damageHandler/index.ts\";\nimport { reminderTargeting } from \"../feature/reminders/index.ts\";\nimport { checkAttackValidity } from \"../feature/reminders/checkAttackValidity.ts\";\n\n/** Modifier keys that invert the private/public spell casting behavior. */\nconst MODIFIER_KEYS = [\"ControlLeft\", \"ControlRight\", \"MetaLeft\", \"MetaRight\", \"Meta\", \"OsLeft\", \"OsRight\"];\n\nexport const preCreateChatMessageHook = (\n message: ChatMessagePF2e,\n data: Record,\n _options: unknown,\n _user: UserPF2e,\n): boolean => {\n let proceed = true;\n\n const reminderTargetingEnabled = getModuleSetting(\"reminderTargeting\") === \"mustTarget\";\n const reminderCannotAttack = getModuleSetting(\"reminderCannotAttack\");\n const castPrivateSpellEnabled = getModuleSetting(\"castPrivateSpell\");\n\n // Handle private spellcasting\n if (castPrivateSpellEnabled && systems.getFlag(message, \"casting.id\")) {\n const ctrlHeld = MODIFIER_KEYS.some((key) => game?.keyboard.downKeys.has(key));\n const inParty = game.actors?.party?.members?.some((member) => member?.id === message?.actor?.id) ?? false;\n const privateCast = castPrivately(inParty, message);\n\n if ((ctrlHeld && !privateCast) || (!ctrlHeld && privateCast)) {\n fireAndForget(handlePrivateSpellcasting(data, message), \"handlePrivateSpellcasting\");\n }\n }\n\n // Handle persistent damage/healing\n const applyPersistentDamage = getModuleSetting(\"applyPersistentDamage\");\n const applyPersistentHealing = getModuleSetting(\"applyPersistentHealing\");\n if (applyPersistentDamage || applyPersistentHealing) {\n persistentDamageHealing(message);\n }\n\n // Handle targeting reminders\n if (reminderTargetingEnabled) {\n proceed = reminderTargeting(message, getModuleSetting(\"reminderTargeting\"));\n }\n\n // Handle attack validity\n if (proceed && reminderCannotAttack === \"cancelAttack\") {\n proceed = checkAttackValidity(message, true);\n }\n\n return proceed;\n};\n\nfunction castPrivately(inParty: boolean, message: ChatMessagePF2e): boolean {\n const isNpc = message.actor?.type === NPC_TYPE;\n const isAlly = message.actor?.alliance === \"party\";\n const alwaysNpc = getModuleSetting(\"castPrivateSpellAlwaysFor\") === \"npcs\";\n const alwaysNonAlly = getModuleSetting(\"castPrivateSpellAlwaysFor\") === \"nonAllies\";\n const alwaysNonParty = getModuleSetting(\"castPrivateSpellAlwaysFor\") === \"nonPartymembers\";\n\n return (isNpc && alwaysNpc) || (!isAlly && alwaysNonAlly) || (!inParty && alwaysNonParty);\n}\n","import type { LearnFailureEntry, LearnFailures } from \"./types.ts\";\nimport { MODULENAME } from \"../../constants.ts\";\nimport { logError } from \"../../utils/logging.ts\";\n\nconst FLAG_LEARN_FAILURES = \"learnSpellFailures\";\n\nexport function sanitizeFlagKey(identifier: string): string {\n return identifier.replace(/\\./g, \"!\");\n}\n\nasync function getLearnFailures(actor: foundry.abstract.Document): Promise {\n return (actor.getFlag(MODULENAME, FLAG_LEARN_FAILURES) as LearnFailures) ?? {};\n}\n\nexport async function setLearnFailure(\n actor: foundry.abstract.Document,\n identifier: string,\n level: number,\n): Promise {\n const failures = await getLearnFailures(actor);\n failures[sanitizeFlagKey(identifier)] = { level, timestamp: game.time.worldTime };\n try {\n await actor.setFlag(MODULENAME, FLAG_LEARN_FAILURES, failures);\n } catch (err) {\n logError(\"setLearnFailure: setFlag failed\", err);\n }\n}\n\nexport async function clearLearnFailure(actor: foundry.abstract.Document, identifier: string): Promise {\n const failures = await getLearnFailures(actor);\n delete failures[sanitizeFlagKey(identifier)];\n try {\n if (Object.keys(failures).length === 0) {\n await actor.unsetFlag(MODULENAME, FLAG_LEARN_FAILURES);\n } else {\n await actor.setFlag(MODULENAME, FLAG_LEARN_FAILURES, failures);\n }\n } catch (err) {\n logError(\"clearLearnFailure: flag write failed\", err);\n }\n}\n\nexport function getLearnFailureEntry(\n actor: foundry.abstract.Document,\n identifier: string,\n): LearnFailureEntry | undefined {\n const failures = (actor.getFlag(MODULENAME, FLAG_LEARN_FAILURES) as LearnFailures) ?? {};\n return failures[sanitizeFlagKey(identifier)];\n}\n\nexport function getLearnFailureLevel(actor: foundry.abstract.Document, identifier: string): number | undefined {\n return getLearnFailureEntry(actor, identifier)?.level;\n}\n","import type { ActorPF2e, SpellcastingEntryPF2e } from \"foundry-pf2e\";\nimport { MODULENAME } from \"../../constants.ts\";\nimport { getLearnFailureEntry } from \"./flags.ts\";\nimport { actorHasItemBySlug } from \"../../utils.ts\";\n\nexport const I18N = `${MODULENAME}.spellLearn` as const;\n\nexport const RANK_CANTRIP = \"cantrip\";\n\nexport const OUTCOME_I18N_KEYS: Record = {\n criticalSuccess: \"learnResultCriticalSuccess\",\n success: \"learnResultSuccess\",\n failure: \"learnResultFailure\",\n criticalFailure: \"learnResultCriticalFailure\",\n skipped: \"learnSpellSkipped\",\n alreadyKnown: \"learnSpellBatchLearnAlreadyKnown\",\n};\n\nexport function getSpellcastingEntries(actor: ActorPF2e): SpellcastingEntryPF2e[] {\n const sc = actor.spellcasting;\n return sc ? ([...sc] as unknown as SpellcastingEntryPF2e[]) : [];\n}\n\nexport function getActorLevel(actor: ActorPF2e): number {\n return actor.system.details.level.value;\n}\n\nexport function hasLearnFailureAtCurrentLevel(actor: ActorPF2e, key: string): boolean {\n const entry = getLearnFailureEntry(actor, key);\n if (!entry) return false;\n if (getActorLevel(actor) > entry.level) return false;\n if (actorHasItemBySlug(actor, \"magical-shorthand\")) {\n const ONE_WEEK_SECONDS = 604800;\n if (game.time.worldTime - entry.timestamp >= ONE_WEEK_SECONDS) return false;\n }\n return true;\n}\n","const locked = new Set();\n\nexport function isLocked(scope: string): boolean {\n return locked.has(scope);\n}\n\n/** Acquires a simple lock for the given scope. Does not queue, callers must check isLocked first. */\nexport async function withLock(scope: string, fn: () => Promise): Promise {\n locked.add(scope);\n try {\n return await fn();\n } finally {\n locked.delete(scope);\n }\n}\n","import type { ActorPF2e } from \"foundry-pf2e\";\nimport { I18N } from \"./helpers.ts\";\nimport { withLock } from \"../../utils/locks.ts\";\nimport { fireAndForget } from \"../../utils.ts\";\n\nexport function postLearnChatMessage(\n actor: ActorPF2e,\n key: string,\n data: Record,\n): void {\n const message = game.i18n.format(`${I18N}.${key}`, data);\n fireAndForget(\n ChatMessage.create({\n content: message,\n speaker: ChatMessage.getSpeaker({ actor }),\n }),\n \"postLearnChatMessage\",\n );\n}\n\nexport async function createSpellWithLock(\n actor: ActorPF2e,\n data: Record,\n entryId?: string,\n): Promise {\n const clone = entryId\n ? { ...data, system: { ...((data.system as Record) ?? {}), location: { value: entryId } } }\n : data;\n return withLock(actor.id, async () => {\n const created = await actor.createEmbeddedDocuments(\"Item\", [clone]);\n return Array.isArray(created) && created.length > 0 ? ((created[0] as { uuid?: string })?.uuid ?? null) : null;\n });\n}\n","import { ActorPF2e, Coins, ItemPF2e } from \"foundry-pf2e\";\nimport { GameSystem, getSystemId } from \"../../utils/systems.ts\";\nimport { I18N } from \"./helpers.ts\";\nimport { logWarn } from \"../../utils/logging.ts\";\nimport { getModuleSetting, tryOrDefault } from \"../../utils.ts\";\nimport { postLearnChatMessage } from \"./spellChatUtils.ts\";\nimport type { DeductionResult } from \"./types.ts\";\n\nconst COIN_MULTIPLIERS = { cp: 1, sp: 10, credits: 10, gp: 100, pp: 1000 } as const;\n\nfunction currencyToCp(currency: Coins): number {\n return (\n (currency.cp ?? 0) +\n (currency.sp ?? 0) * COIN_MULTIPLIERS.sp +\n (currency.gp ?? 0) * COIN_MULTIPLIERS.gp +\n (currency.pp ?? 0) * COIN_MULTIPLIERS.pp +\n (currency.credits ?? 0) * COIN_MULTIPLIERS.credits\n );\n}\n\nexport function getCostDenominationMultiplier(): number {\n return getSystemId() === GameSystem.SF2E ? COIN_MULTIPLIERS.credits : COIN_MULTIPLIERS.gp;\n}\n\nexport function formatCostForDisplay(copper: number): string {\n const isSf2e = getSystemId() === GameSystem.SF2E;\n if (isSf2e) {\n const credits = Math.ceil(copper / COIN_MULTIPLIERS.credits);\n return `${credits} ${credits === 1 ? \"credit\" : \"credits\"}`;\n }\n return `${copper / COIN_MULTIPLIERS.gp} gp`;\n}\n\nfunction canAffordCost(actor: ActorPF2e, amountCopper: number): boolean {\n const inventory = actor.inventory ?? null;\n if (!inventory) return false;\n return currencyToCp(inventory.currency) >= amountCopper;\n}\n\nasync function deductCostFromActor(actor: ActorPF2e, amountCopper: number): Promise {\n const inventory = actor.inventory ?? null;\n if (!inventory) {\n logWarn(\"economyHandler: no inventory for actor; cannot deduct cost\");\n return { ok: false, debt: amountCopper };\n }\n\n const beforeCp = currencyToCp(inventory.currency);\n const coins: Record =\n getSystemId() === GameSystem.SF2E\n ? { sp: Math.ceil(amountCopper / COIN_MULTIPLIERS.sp) }\n : { gp: Math.ceil(amountCopper / COIN_MULTIPLIERS.gp) };\n const removed = await tryOrDefault(\n () => inventory.removeCurrency(coins, { byValue: true }),\n false,\n \"economyHandler: removeCurrency\",\n );\n if (!removed) {\n return { ok: false, debt: amountCopper };\n }\n\n const afterCp = currencyToCp(inventory.currency);\n const deductedCp = beforeCp - afterCp;\n\n if (deductedCp >= amountCopper) {\n return { ok: true, debt: 0 };\n }\n\n const debt = amountCopper - deductedCp;\n logWarn(\n `economyHandler: insufficient funds to deduct ${formatCostForDisplay(amountCopper)}; ${formatCostForDisplay(debt)} remaining`,\n );\n return { ok: false, debt };\n}\n\ninterface CostDeductionParams {\n actor: ActorPF2e;\n costCopper: number;\n spellName?: string;\n collectionName?: string;\n}\n\ntype DebtItemContext = Pick;\n\nfunction checkAndNotifyInsufficientFunds(params: CostDeductionParams): boolean {\n if (params.costCopper <= 0) return false;\n if (getModuleSetting(\"allowDebtItems\")) return false;\n if (canAffordCost(params.actor, params.costCopper)) return false;\n postLearnChatMessage(params.actor, \"insufficientFundsForLearn\", {\n actor: params.actor.name,\n cost: formatCostForDisplay(params.costCopper),\n spellName: params.spellName,\n collectionName: params.collectionName,\n });\n return true;\n}\n\nfunction buildDebtDescription(amountCopper: number, context?: DebtItemContext): string {\n const amount = formatCostForDisplay(amountCopper);\n const spellName = context?.spellName;\n const collectionName = context?.collectionName;\n\n if (collectionName) {\n return spellName\n ? game.i18n.format(`${I18N}.debtItemDescription`, { amount, spells: spellName, collectionName })\n : game.i18n.format(`${I18N}.debtItemDescriptionNoSpells`, { amount, collectionName });\n }\n return spellName\n ? game.i18n.format(`${I18N}.debtItemDescriptionForSpell`, { amount, spellName })\n : game.i18n.format(`${I18N}.debtItemDescriptionNoSpellbook`, { amount });\n}\n\nasync function createDebtItem(\n actor: ActorPF2e,\n amountCopper: number,\n context?: DebtItemContext,\n): Promise {\n const amount = formatCostForDisplay(amountCopper);\n const name = game.i18n.format(`${I18N}.debtItemName`, { amount });\n const description = buildDebtDescription(amountCopper, context);\n\n const itemData = {\n name,\n type: \"equipment\",\n img: \"icons/sundries/misc/piggybank.webp\",\n system: {\n description: { value: description },\n price: { value: { cp: 0, sp: 0, gp: 0, pp: 0 } },\n quantity: 1,\n slug: `xdy-spell-debt-item-${foundry.utils.randomID(8)}`,\n },\n };\n\n return tryOrDefault(\n async () => {\n // A bit ugly, but I'll use record here instead of a ts-expect-error that I'll never fix.\n const created = await actor.createEmbeddedDocuments(\"Item\", [itemData] as unknown as Record<\n string,\n unknown\n >[]);\n const item = (created?.[0] as ItemPF2e) ?? null;\n if (item) {\n postLearnChatMessage(actor, \"debtItemCreated\", {\n actor: actor.name,\n amount,\n spellName: context?.spellName,\n });\n }\n return item;\n },\n null,\n \"economyHandler: createDebtItem\",\n );\n}\n\nexport async function executeCostDeduction(params: CostDeductionParams): Promise {\n if (checkAndNotifyInsufficientFunds(params)) {\n return false;\n }\n\n const result = await deductCostFromActor(params.actor, params.costCopper);\n if (!result.ok) {\n const debtItem = await createDebtItem(params.actor, result.debt, {\n spellName: params.spellName,\n collectionName: params.collectionName,\n });\n // If a debt item was created, treat the deduction as satisfied.\n if (debtItem) return true;\n return false;\n }\n\n return true;\n}\n","import type { ActorPF2e, SpellPF2e } from \"foundry-pf2e\";\nimport type { ResolvedSpellTraits, SpellSourceIdAccess } from \"./types.ts\";\nimport { RANK_CANTRIP } from \"./helpers.ts\";\nimport { actorHasItemBySlug, getModuleSetting } from \"../../utils.ts\";\nimport { getCostDenominationMultiplier } from \"./economyHandler.ts\";\n\nfunction resolveSpellSystem(spell: SpellPF2e | Record): Record | undefined {\n return (spell as Record).system as Record | undefined;\n}\n\nexport function spellIdentifier(spell: SpellPF2e | Record): string | null {\n const access = spell as SpellSourceIdAccess;\n const sourceId: string | undefined = access.sourceId ?? access._stats?.compendiumSource;\n if (sourceId) return `sourceId:${sourceId}`;\n const slug = resolveSpellSystem(spell)?.slug;\n if (slug) return `slug:${slug}`;\n return null;\n}\n\nconst LEARN_SPELL_BASE_DC: Readonly> = {\n [RANK_CANTRIP]: 15,\n \"1\": 15,\n \"2\": 18,\n \"3\": 20,\n \"4\": 23,\n \"5\": 26,\n \"6\": 28,\n \"7\": 31,\n \"8\": 34,\n \"9\": 36,\n \"10\": 41,\n};\n\n/** Rarity DC adjustments (GM Core p.52). */\nconst RARITY_DC_ADJUSTMENT: Readonly> = {\n common: 0,\n uncommon: 2,\n rare: 5,\n unique: 10,\n};\n\n/**\n * Spell formula base cost per rank, in gp. (Convert to sp/credits for sf2e)\n * Learn a Spell costs are twice this. Use {@link getCostDenominationMultiplier} to convert to copper.\n */\nconst SPELL_FORMULA_COST: Readonly> = {\n [RANK_CANTRIP]: 1,\n \"1\": 1,\n \"2\": 3,\n \"3\": 8,\n \"4\": 18,\n \"5\": 35,\n \"6\": 70,\n \"7\": 150,\n \"8\": 325,\n \"9\": 750,\n \"10\": 3500,\n};\n\nfunction getLearnSpellBaseDc(rankKey: string): number {\n return LEARN_SPELL_BASE_DC[rankKey] ?? 15;\n}\n\nfunction getRarityDcAdjustment(rarity: string): number {\n return RARITY_DC_ADJUSTMENT[rarity?.toLowerCase()] ?? 0;\n}\n\nexport function calculateLearnDc(rankKey: string, traits: string[], modifier = 0): number {\n const baseDc = getLearnSpellBaseDc(rankKey);\n const rarity = traits.find((t) => RARITY_DC_ADJUSTMENT[t.toLowerCase()] !== undefined) ?? \"common\";\n const rarityAdj = getRarityDcAdjustment(rarity);\n return baseDc + rarityAdj + modifier;\n}\n\nexport function getLearnSpellDcAdjustment(): number {\n return getModuleSetting(\"learnSpellDcAdjustment\") ?? 0;\n}\n\nexport function getLearnSpellCostCopper(rankKey: string): number {\n return (SPELL_FORMULA_COST[rankKey] ?? 1) * 2 * getCostDenominationMultiplier();\n}\n\nexport function getLearnSpellHours(rankKey: string, actor?: ActorPF2e): number {\n if (actor && actorHasItemBySlug(actor, \"magical-shorthand\")) return 1 / 6;\n if (rankKey === RANK_CANTRIP) return 1;\n const rank = Number(rankKey);\n return Number.isFinite(rank) && rank > 0 ? rank : 1;\n}\n\nexport function getSpellTraitsAndRank(spell: SpellPF2e | Record): ResolvedSpellTraits | null {\n const spellSystem = resolveSpellSystem(spell) as\n | {\n level?: { value?: number };\n traits?: { value?: string[]; traditions?: string[] };\n }\n | undefined;\n const spellLevel: number | undefined = spellSystem?.level?.value;\n if (spellLevel === undefined) return null;\n const traits: string[] = spellSystem?.traits?.value ?? [];\n const traditions: string[] = spellSystem?.traits?.traditions ?? [];\n const isCantrip = traits.includes(RANK_CANTRIP) || spellLevel <= 0;\n const rankKey = isCantrip ? RANK_CANTRIP : String(spellLevel);\n const spellName = (spell as { name?: string }).name ?? \"\";\n return { traits, traditions, rankKey, spellName };\n}\n\nexport function getSpellDocData(spellDoc: SpellPF2e | Record): Record {\n return \"toObject\" in (spellDoc as unknown as Record)\n ? (spellDoc as unknown as { toObject: () => Record }).toObject()\n : (spellDoc as unknown as Record);\n}\n","import type { ActorPF2e, ItemPF2e, SpellcastingEntryPF2e, SpellPF2e } from \"foundry-pf2e\";\nimport { spellIdentifier } from \"./spellData.ts\";\nimport { getSpellcastingEntries, I18N } from \"./helpers.ts\";\nimport type { SpellRollSkill } from \"./learn/spellRoll.ts\";\n\nfunction* iterateKnownSpells(actor: ActorPF2e): Generator<[ItemPF2e, string]> {\n for (const entry of getSpellcastingEntries(actor)) {\n const spells: ItemPF2e[] = entry.spells?.contents ? [...entry.spells.contents] : [];\n for (const spell of spells) {\n const ident = spellIdentifier(spell as unknown as SpellPF2e);\n if (ident) yield [spell, ident];\n }\n }\n}\n\nexport function findKnownSpell(actor: ActorPF2e, identifier: string): ItemPF2e | null {\n if (!identifier) return null;\n for (const [spell, ident] of iterateKnownSpells(actor)) {\n if (ident === identifier) return spell;\n }\n return null;\n}\n\nexport function isSpellAlreadyKnownSync(actor: ActorPF2e, ident: string): boolean {\n return findKnownSpell(actor, ident) !== null;\n}\n\nexport function hasSpontaneousEntry(actor: ActorPF2e): boolean {\n return getSpellcastingEntries(actor).some((entry) => entry.isSpontaneous);\n}\n\nexport function getEntryTradition(entry: SpellcastingEntryPF2e): string | null {\n const tradition = entry.tradition ?? entry.system?.tradition?.value;\n return (tradition || null) as string | null;\n}\n\nexport function hasCompatibleTradition(actor: ActorPF2e, spellTraditions: string[]): boolean {\n if (spellTraditions.length === 0) return true;\n for (const entry of getSpellcastingEntries(actor)) {\n const trad = getEntryTradition(entry);\n if (trad && spellTraditions.includes(trad)) return true;\n }\n return false;\n}\n\nexport interface EntryDisplayInfo {\n name: string;\n tradition: string;\n type: string;\n}\n\nexport function getEntryDisplayInfo(entry: SpellcastingEntryPF2e): EntryDisplayInfo {\n const tradition = getEntryTradition(entry) ?? \"\";\n if (entry.isFocusPool) return { name: entry.name, tradition, type: \"focus\" };\n if (entry.isSpontaneous) return { name: entry.name, tradition, type: \"spontaneous\" };\n if (entry.isPrepared) return { name: entry.name, tradition, type: \"prepared\" };\n return { name: entry.name, tradition, type: \"spellcasting\" };\n}\n\nfunction getEntriesWithTradition(actor: ActorPF2e): { item: SpellcastingEntryPF2e; tradition: string }[] {\n const entries: { item: SpellcastingEntryPF2e; tradition: string }[] = [];\n for (const entry of getSpellcastingEntries(actor)) {\n const trad = getEntryTradition(entry);\n if (!trad) continue;\n entries.push({ item: entry, tradition: trad });\n }\n return entries;\n}\n\nfunction entryMatchesTradition(tradition: string, spellTraditions: string[]): boolean {\n return spellTraditions.length === 0 || spellTraditions.includes(tradition);\n}\n\nexport function pickSpellcastingEntryForActor(\n actor: ActorPF2e,\n spellTraditions: string[],\n preferredEntryId?: string,\n): SpellcastingEntryPF2e | null {\n const entries = getEntriesWithTradition(actor);\n if (entries.length === 0) return null;\n if (preferredEntryId) {\n const preferred = entries.find((e) => e.item.id === preferredEntryId);\n if (preferred && entryMatchesTradition(preferred.tradition, spellTraditions)) return preferred.item;\n if (preferred) return null;\n }\n\n const matchTrad = entries.find((e) => entryMatchesTradition(e.tradition, spellTraditions));\n return matchTrad?.item ?? null;\n}\n\nexport async function pickSpellcastingEntryWithDialog(\n actor: ActorPF2e,\n spellTraditions: string[],\n preferredEntryId?: string,\n): Promise {\n const entries = getEntriesWithTradition(actor);\n if (entries.length === 0) return null;\n if (preferredEntryId) {\n const preferred = entries.find((e) => e.item.id === preferredEntryId);\n if (preferred && entryMatchesTradition(preferred.tradition, spellTraditions)) return preferred.item;\n if (preferred) return null;\n }\n\n const matches = entries.filter((e) => entryMatchesTradition(e.tradition, spellTraditions));\n if (matches.length === 0) return null;\n if (matches.length === 1) return matches[0].item;\n\n const options = matches.map((m) => ({\n value: m.item.id!,\n label: m.item.name,\n }));\n const selection = await foundry.applications.api.DialogV2.wait({\n window: { title: game.i18n.localize(`${I18N}.pickEntryTitle`) },\n content: `

${game.i18n.localize(`${I18N}.pickEntryMessage`)}

`,\n buttons: options.map((opt) => ({\n action: opt.value,\n label: opt.label,\n })),\n });\n if (!selection) return null;\n return matches.find((m) => m.item.id === selection)?.item ?? null;\n}\n\nconst TRADITION_SKILL: Record = {\n arcane: \"arcana\",\n divine: \"religion\",\n occult: \"occultism\",\n primal: \"nature\",\n};\n\ntype ActorWithSkills = ActorPF2e & { skills?: Record };\n\nexport function getSkillCheckForEntry(actor: ActorPF2e, entry: SpellcastingEntryPF2e): SpellRollSkill | null {\n const tradSlug = getEntryTradition(entry) ?? \"\";\n const skillSlug = TRADITION_SKILL[tradSlug];\n if (!skillSlug) return null;\n return ((actor as ActorWithSkills).skills?.[skillSlug] as SpellRollSkill) ?? null;\n}\n","import { getActorLevel, hasLearnFailureAtCurrentLevel, I18N } from \"./helpers.ts\";\nimport { getLearnFailureLevel, sanitizeFlagKey } from \"./flags.ts\";\nimport { formatCostForDisplay } from \"./economyHandler.ts\";\n\nimport type { ActorPF2e } from \"foundry-pf2e\";\n\nfunction formatI18n(key: string, formatData?: Record): string {\n return formatData ? game.i18n.format(`${I18N}.${key}`, formatData) : game.i18n.localize(`${I18N}.${key}`);\n}\n\nfunction formatLearningTime(hours: number): string {\n if (hours < 1) return game.i18n.format(`${I18N}.learnSpellTime10Minutes`, { minutes: Math.round(hours * 60) });\n return game.i18n.format(`${I18N}.learnSpellTimeHours`, { hours });\n}\n\nexport async function showConfirm(\n titleKey: string,\n messageKey: string,\n formatData?: Record,\n buttonLabels?: { yes?: string; no?: string },\n): Promise {\n const yesLabel = buttonLabels?.yes\n ? game.i18n.localize(`${I18N}.${buttonLabels.yes}`)\n : game.i18n.localize(`${I18N}.yes`);\n const noLabel = buttonLabels?.no\n ? game.i18n.localize(`${I18N}.${buttonLabels.no}`)\n : game.i18n.localize(`${I18N}.no`);\n\n return await foundry.applications.api.DialogV2.confirm({\n window: { title: formatI18n(titleKey, formatData) },\n content: `

${formatI18n(messageKey, formatData)}

`,\n yes: { label: yesLabel },\n no: { label: noLabel },\n });\n}\n\ninterface OverrideLearnFailureResult {\n allowed: boolean;\n didOverride: boolean;\n}\n\nexport async function promptOverrideLearnFailure(\n actor: ActorPF2e,\n ident: string,\n spellName: string,\n): Promise {\n const key = sanitizeFlagKey(ident);\n if (!hasLearnFailureAtCurrentLevel(actor, key)) return { allowed: true, didOverride: false };\n const failureLevel = getLearnFailureLevel(actor, key) ?? getActorLevel(actor);\n const confirmed = await showConfirm(\n \"overrideLearnFailureTitle\",\n \"overrideLearnFailureMessage\",\n { spellName, level: failureLevel },\n { yes: \"overrideLearnFailureYes\", no: \"overrideLearnFailureNo\" },\n );\n return { allowed: confirmed, didOverride: confirmed };\n}\n\nexport async function showLearnSpellDialog(\n spellName: string,\n costCopper: number,\n hours: number,\n entryInfo?: { name: string; tradition: string; type: string },\n): Promise<\"yes\" | \"no\" | null> {\n const entryText = entryInfo\n ? `
${game.i18n.format(`${I18N}.learnSpellDialogEntry`, {\n entryName: entryInfo.name,\n tradition: entryInfo.tradition,\n type: entryInfo.type,\n })}`\n : \"\";\n const choice = await foundry.applications.api.DialogV2.wait({\n window: {\n title: game.i18n.localize(`${I18N}.learnSpellDialogTitle`),\n },\n content: `

${game.i18n.format(`${I18N}.learnSpellDialogMessage`, { spellName, cost: formatCostForDisplay(costCopper), time: formatLearningTime(hours) })}${entryText}

`,\n buttons: [\n {\n action: \"yes\",\n label: game.i18n.localize(`${I18N}.learnSpellYes`),\n icon: \"fa-solid fa-graduation-cap\",\n },\n {\n action: \"no\",\n label: game.i18n.localize(`${I18N}.learnSpellNo`),\n icon: \"fa-solid fa-check\",\n },\n {\n action: \"cancel\",\n label: game.i18n.localize(`${I18N}.learnSpellCancel`),\n icon: \"fa-solid fa-times\",\n },\n ],\n });\n if (!choice || choice === \"cancel\") return null;\n return choice as \"yes\" | \"no\";\n}\n","import type { ActorPF2e, SpellcastingEntryPF2e } from \"foundry-pf2e\";\nimport { I18N } from \"../helpers.ts\";\nimport { getSkillCheckForEntry } from \"../spellActorQueries.ts\";\nimport { logError } from \"../../../utils/logging.ts\";\nimport type { LearnOutcome } from \"../types.ts\";\n\nexport interface SpellRollSkill {\n roll(args: {\n dc: { value: number };\n skipDialog?: boolean;\n extraRollOptions?: string[];\n createMessage?: boolean;\n callback?: (roll: unknown, outcome: LearnOutcome | null) => Promise;\n }): Promise;\n}\n\ntype SpellRollCallback = (outcome: LearnOutcome | null) => Promise;\n\ninterface SpellRollOptions {\n skipDialog?: boolean;\n}\n\nexport function performSpellRoll(\n actor: ActorPF2e,\n entry: SpellcastingEntryPF2e,\n finalDc: number,\n callback?: SpellRollCallback,\n options?: SpellRollOptions,\n): Promise {\n const skill = getSkillCheckForEntry(actor, entry) as SpellRollSkill | null;\n if (!skill?.roll) {\n ui.notifications.warn(game.i18n.localize(`${I18N}.learnNoSkill`));\n return Promise.resolve(null);\n }\n\n const skipDialog = options?.skipDialog ?? false;\n\n return new Promise((resolve) => {\n void skill.roll({\n dc: { value: finalDc },\n skipDialog,\n extraRollOptions: [\"concentrate\", \"exploration\"],\n createMessage: true,\n callback: async (_roll: unknown, outcome: LearnOutcome | null) => {\n try {\n await callback?.(outcome);\n } catch (err) {\n logError(\"performSpellRoll: outcome callback threw\", err);\n ui.notifications.error(game.i18n.localize(`${I18N}.learnSpellFailed`));\n }\n resolve(outcome ?? null);\n },\n });\n });\n}\n","import type { ActorPF2e, SpellcastingEntryPF2e, SpellPF2e } from \"foundry-pf2e\";\nimport type {\n BatchLearnResult,\n BatchLearnSpellEntry,\n BatchLearnSpellResult,\n LearnOutcome,\n ResolvedSpellTraits,\n} from \"../types.ts\";\nimport { getActorLevel, hasLearnFailureAtCurrentLevel, I18N, OUTCOME_I18N_KEYS } from \"../helpers.ts\";\nimport { clearLearnFailure, sanitizeFlagKey, setLearnFailure } from \"../flags.ts\";\nimport {\n calculateLearnDc,\n getLearnSpellCostCopper,\n getLearnSpellDcAdjustment,\n getLearnSpellHours,\n getSpellDocData,\n getSpellTraitsAndRank,\n spellIdentifier,\n} from \"../spellData.ts\";\nimport { performSpellRoll } from \"./spellRoll.ts\";\nimport { findKnownSpell, pickSpellcastingEntryForActor } from \"../spellActorQueries.ts\";\nimport { createSpellWithLock, postLearnChatMessage } from \"../spellChatUtils.ts\";\nimport { executeCostDeduction, formatCostForDisplay } from \"../economyHandler.ts\";\nimport { logError } from \"../../../utils/logging.ts\";\n\nexport interface ValidatedLearnInput {\n ident: string | null;\n resolved: ResolvedSpellTraits;\n entry: SpellcastingEntryPF2e;\n finalDc: number;\n costCopper: number;\n hours: number;\n}\n\nexport function isSuccessOutcome(outcome: LearnOutcome | null | undefined): outcome is \"criticalSuccess\" | \"success\" {\n return outcome === \"criticalSuccess\" || outcome === \"success\";\n}\n\nexport function isFailureOutcome(outcome: LearnOutcome | null | undefined): outcome is \"failure\" | \"criticalFailure\" {\n return outcome === \"failure\" || outcome === \"criticalFailure\";\n}\n\nfunction isAlreadyKnownOutcome(outcome: LearnOutcome | null | undefined): outcome is \"alreadyKnown\" {\n return outcome === \"alreadyKnown\";\n}\n\nfunction isSkippedOutcome(outcome: LearnOutcome | null | undefined): outcome is \"skipped\" {\n return outcome === \"skipped\";\n}\n\nexport function computeEffectiveCost(costCopper: number, outcome: LearnOutcome | null | undefined): number {\n if (outcome === \"skipped\") return 0;\n if (outcome === \"criticalSuccess\" || outcome === \"criticalFailure\") return Math.floor(costCopper / 2);\n if (outcome === \"failure\") return 0;\n return costCopper;\n}\n\nfunction makeBatchResult(\n spell: BatchLearnSpellEntry,\n outcome: LearnOutcome | null,\n costCopper: number,\n hours: number,\n wasAlreadyKnown: boolean,\n): BatchLearnSpellResult {\n return {\n uuid: spell.uuid,\n name: spell.name,\n rankKey: spell.rankKey,\n outcome,\n costCopper,\n hours,\n wasAlreadyKnown,\n };\n}\n\ninterface BatchLearnContext {\n actor: ActorPF2e;\n entryId?: string;\n suppressIndividualMessages?: boolean;\n}\n\nexport async function executeBatchLearn(\n spells: BatchLearnSpellEntry[],\n ctx: BatchLearnContext,\n): Promise {\n const results: BatchLearnSpellResult[] = [];\n let totalCostCopper = 0;\n let totalHours = 0;\n let successCount = 0;\n let failureCount = 0;\n let skippedCount = 0;\n let alreadyKnownCount = 0;\n\n for (const spell of spells) {\n try {\n const { result, stopBatch } = await processSingleBatchSpell(spell, ctx);\n results.push(result);\n if (!stopBatch) {\n totalCostCopper += result.costCopper;\n totalHours += result.hours;\n }\n if (isAlreadyKnownOutcome(result.outcome)) alreadyKnownCount++;\n else if (isSkippedOutcome(result.outcome)) skippedCount++;\n else if (isSuccessOutcome(result.outcome)) successCount++;\n else if (isFailureOutcome(result.outcome)) failureCount++;\n if (stopBatch) break;\n } catch (err) {\n logError(`batchLearnSpells: unhandled error processing spell ${spell.name} (${spell.uuid})`, err);\n ui.notifications.warn(\n game.i18n.format(`${I18N}.batchLearnSingleError`, {\n spellName: spell.name,\n }) || `Failed to process ${spell.name}`,\n );\n results.push(makeBatchResult(spell, null, 0, 0, false));\n }\n }\n\n return {\n spells: results,\n totalCostCopper,\n totalHours,\n successCount,\n failureCount,\n skippedCount,\n alreadyKnownCount,\n };\n}\n\nasync function processSingleBatchSpell(\n spell: BatchLearnSpellEntry,\n ctx: BatchLearnContext,\n): Promise<{ result: BatchLearnSpellResult; stopBatch?: boolean }> {\n const spellDoc = (await fromUuid(spell.uuid)) as SpellPF2e | null;\n if (!spellDoc) {\n return { result: makeBatchResult(spell, null, 0, 0, false) };\n }\n\n const ident = spellIdentifier(spellDoc);\n if (ident && findKnownSpell(ctx.actor, ident) !== null) {\n return { result: makeBatchResult(spell, \"alreadyKnown\", 0, 0, true) };\n }\n\n const validated = await resolveAndValidate(spellDoc, ctx.actor, ctx.entryId);\n if (!validated) {\n return { result: makeBatchResult(spell, null, 0, 0, false) };\n }\n\n const outcome = await performSpellRoll(ctx.actor, validated.entry, validated.finalDc, undefined, {\n skipDialog: true,\n });\n\n return processBatchOutcome(spell, ctx, validated, spellDoc, outcome);\n}\n\nexport async function resolveAndValidate(\n spellDoc: SpellPF2e,\n actor: ActorPF2e,\n entryId?: string,\n checkCanAttempt = false,\n): Promise {\n const resolved = getSpellTraitsAndRank(spellDoc);\n if (!resolved) {\n ui.notifications.warn(game.i18n.localize(`${I18N}.learnSpellInvalidRank`));\n return null;\n }\n\n const ident = spellIdentifier(spellDoc);\n\n const entry = pickSpellcastingEntryForActor(actor, resolved.traditions, entryId);\n\n if (!entry) {\n ui.notifications.warn(game.i18n.localize(`${I18N}.learnNoCompatibleEntry`));\n return null;\n }\n\n if (checkCanAttempt && ident && hasLearnFailureAtCurrentLevel(actor, sanitizeFlagKey(ident))) {\n return null;\n }\n\n const finalDc = calculateLearnDc(resolved.rankKey, resolved.traits, getLearnSpellDcAdjustment());\n const costCopper = getLearnSpellCostCopper(resolved.rankKey);\n const hours = getLearnSpellHours(resolved.rankKey, actor);\n\n return { ident, resolved, entry, finalDc, costCopper, hours };\n}\n\ninterface LearnOutcomeContext {\n actor: ActorPF2e;\n ident: string | null;\n costCopper: number;\n hours: number;\n spellName: string;\n entryId: string;\n}\n\nexport async function processLearnOutcome(\n ctx: LearnOutcomeContext,\n outcome: LearnOutcome | null | undefined,\n suppressMessages: boolean,\n onSuccess: () => Promise,\n): Promise {\n const effectiveCost = computeEffectiveCost(ctx.costCopper, outcome);\n\n const deducted = await executeCostDeduction({\n actor: ctx.actor,\n costCopper: effectiveCost,\n spellName: ctx.spellName,\n });\n if (!deducted && effectiveCost > 0) return false;\n\n if (isSuccessOutcome(outcome)) {\n if (ctx.ident) await clearLearnFailure(ctx.actor, sanitizeFlagKey(ctx.ident));\n await onSuccess();\n } else if (isFailureOutcome(outcome)) {\n if (ctx.ident) await setLearnFailure(ctx.actor, sanitizeFlagKey(ctx.ident), getActorLevel(ctx.actor));\n }\n\n if (!suppressMessages && outcome) {\n postLearnChatMessage(ctx.actor, OUTCOME_I18N_KEYS[outcome] ?? \"\", {\n actor: ctx.actor.name,\n spellName: ctx.spellName,\n cost: formatCostForDisplay(effectiveCost),\n hours: ctx.hours,\n });\n }\n\n return true;\n}\n\nasync function processBatchOutcome(\n spell: BatchLearnSpellEntry,\n ctx: BatchLearnContext,\n validated: ValidatedLearnInput,\n spellDoc: SpellPF2e,\n outcome: LearnOutcome | null | undefined,\n): Promise<{ result: BatchLearnSpellResult; stopBatch?: boolean }> {\n const success = await processLearnOutcome(\n {\n actor: ctx.actor,\n ident: validated.ident,\n costCopper: validated.costCopper,\n hours: validated.hours,\n spellName: validated.resolved.spellName,\n entryId: validated.entry.id,\n },\n outcome,\n ctx.suppressIndividualMessages ?? false,\n async () => {\n await createSpellWithLock(ctx.actor, getSpellDocData(spellDoc), validated.entry.id);\n },\n );\n\n const effectiveCost = computeEffectiveCost(validated.costCopper, outcome);\n if (!success) {\n return { result: makeBatchResult(spell, outcome ?? null, 0, validated.hours, false), stopBatch: true };\n }\n return { result: makeBatchResult(spell, outcome ?? null, effectiveCost, validated.hours, false) };\n}\n","import type { ActorPF2e, SpellPF2e } from \"foundry-pf2e\";\nimport type { BatchLearnResult, BatchLearnSpellEntry, LearnOutcome, LearnSpellTarget } from \"../types.ts\";\nimport { clearLearnFailure, sanitizeFlagKey } from \"../flags.ts\";\nimport { getSpellDocData, getSpellTraitsAndRank, spellIdentifier } from \"../spellData.ts\";\nimport { postLearnChatMessage } from \"../spellChatUtils.ts\";\nimport { promptOverrideLearnFailure } from \"../dialogHelper.ts\";\nimport { performSpellRoll } from \"./spellRoll.ts\";\nimport { executeBatchLearn, processLearnOutcome, resolveAndValidate, type ValidatedLearnInput } from \"./batchLearn.ts\";\n\nexport class LearnSpellHandler {\n #target: LearnSpellTarget;\n\n constructor(target: LearnSpellTarget) {\n this.#target = target;\n }\n\n async initiateFromSpellData(spellData: Record, actor: ActorPF2e, entryId: string): Promise {\n const resolved = getSpellTraitsAndRank(spellData);\n if (!resolved) return;\n\n await this.#initiateCore(spellData, actor, entryId, false, async () => {\n const ident = spellIdentifier(spellData);\n if (ident) {\n const { allowed } = await promptOverrideLearnFailure(actor, ident, resolved.spellName);\n return allowed;\n }\n return true;\n });\n }\n\n async addSpellDirectly(\n spellData: Record,\n actor: ActorPF2e,\n entryId: string,\n spellName: string,\n ): Promise {\n const ident = spellIdentifier(spellData);\n const { allowed, didOverride } = ident\n ? await promptOverrideLearnFailure(actor, ident, spellName)\n : { allowed: true, didOverride: false };\n if (!allowed) return;\n\n await this.#target.addSpell(spellData, actor, entryId, \"\", spellName);\n postLearnChatMessage(actor, \"learnSpellSkipped\", { actor: actor.name, spellName });\n if (didOverride && ident) {\n await clearLearnFailure(actor, sanitizeFlagKey(ident));\n postLearnChatMessage(actor, \"learnFailureOverridden\", { actor: actor.name, spellName });\n }\n }\n\n async batchLearnSpells(\n spells: BatchLearnSpellEntry[],\n actor: ActorPF2e,\n entryId?: string,\n suppressIndividualMessages?: boolean,\n ): Promise {\n return executeBatchLearn(spells, {\n actor,\n entryId,\n suppressIndividualMessages,\n });\n }\n\n async #initiateCore(\n spell: SpellPF2e | Record,\n actor: ActorPF2e,\n entryId: string,\n checkCanAttempt: boolean,\n preRollFn?: (validated: ValidatedLearnInput) => Promise,\n ): Promise {\n const validated = await resolveAndValidate(spell as SpellPF2e, actor, entryId, checkCanAttempt);\n if (!validated) return;\n\n if (preRollFn) {\n const shouldContinue = await preRollFn(validated);\n if (!shouldContinue) return;\n }\n\n const target = this.#target;\n await performSpellRoll(\n actor,\n validated.entry,\n validated.finalDc,\n async (outcome: LearnOutcome | null | undefined) => {\n await processLearnOutcome(\n {\n actor,\n ident: validated.ident,\n costCopper: validated.costCopper,\n hours: validated.hours,\n spellName: validated.resolved.spellName,\n entryId: validated.entry.id,\n },\n outcome,\n false,\n async () => {\n const clone = getSpellDocData(spell);\n await target.addSpell(\n clone,\n actor,\n validated.entry.id,\n validated.resolved.rankKey,\n validated.resolved.spellName,\n );\n },\n );\n },\n );\n }\n}\n","import type { ActorPF2e, ItemPF2e } from \"foundry-pf2e\";\nimport { I18N } from \"../helpers.ts\";\nimport { getLearnSpellCostCopper, getLearnSpellHours, getSpellTraitsAndRank, spellIdentifier } from \"../spellData.ts\";\nimport {\n getEntryDisplayInfo,\n hasCompatibleTradition,\n hasSpontaneousEntry,\n isSpellAlreadyKnownSync,\n pickSpellcastingEntryForActor,\n pickSpellcastingEntryWithDialog,\n} from \"../spellActorQueries.ts\";\nimport { showLearnSpellDialog } from \"../dialogHelper.ts\";\nimport { isLocked, withLock } from \"../../../utils/locks.ts\";\nimport { fireAndForget, getModuleSetting } from \"../../../utils.ts\";\nimport { LearnSpellHandler } from \"./learnSpellHandler.ts\";\nimport type { LearnSpellTarget } from \"../types.ts\";\nimport { createSpellWithLock } from \"../spellChatUtils.ts\";\n\nexport class DirectEntryTarget implements LearnSpellTarget {\n async addSpell(\n spellData: Record,\n actor: ActorPF2e,\n entryId: string,\n _rankKey: string,\n _spellName: string,\n ): Promise {\n return createSpellWithLock(actor, spellData, entryId);\n }\n}\n\nconst learnSpellHandler = new LearnSpellHandler(new DirectEntryTarget());\n\nexport function shouldIntercept(item: ItemPF2e): boolean {\n if (item.type !== \"spell\") return false;\n const actor = item.actor;\n if (!actor || actor.type !== \"character\") return false;\n return getModuleSetting(\"enableGeneralLearnSpell\");\n}\n\nexport function preCreateItemSpellIntercept(item: ItemPF2e, data: object): false | void {\n if (!shouldIntercept(item)) return;\n\n const actor = item.actor;\n if (!actor) return;\n if (isLocked(actor.id)) return;\n\n const rawData = data as Record;\n const spellName = (rawData as { name?: string }).name ?? \"\";\n\n const ident = spellIdentifier(rawData);\n if (ident && isSpellAlreadyKnownSync(actor as ActorPF2e, ident)) {\n if (hasSpontaneousEntry(actor as ActorPF2e)) return;\n ui.notifications.info(game.i18n.format(`${I18N}.alreadyKnown`, { name: spellName }));\n return false;\n }\n\n fireAndForget(checkAndIntercept(rawData, actor as ActorPF2e, spellName), \"preCreateItemHook: spellAddIntercept\");\n\n return false;\n}\n\nasync function checkAndIntercept(\n rawData: Record,\n actor: ActorPF2e,\n _spellName: string,\n): Promise {\n const resolved = getSpellTraitsAndRank(rawData);\n if (resolved && !hasCompatibleTradition(actor, resolved.traditions)) {\n ui.notifications.warn(\n game.i18n.format(`${I18N}.traditionMismatch`, {\n spellName: resolved.spellName,\n traditions: resolved.traditions.join(\", \") || game.i18n.localize(`${I18N}.noTradition`),\n }),\n );\n return;\n }\n\n await withLock(actor.id, () => intercept(rawData, actor));\n}\n\nfunction getTargetEntryIdFromData(spellData: Record): string | undefined {\n const system = spellData.system as Record | undefined;\n const location = system?.location as Record | undefined;\n return location?.value as string | undefined;\n}\n\nasync function intercept(spellData: Record, actor: ActorPF2e): Promise {\n const traits = getSpellTraitsAndRank(spellData);\n const rankKey = traits?.rankKey ?? \"cantrip\";\n const spellName = (spellData as { name?: string }).name ?? \"\";\n const traditions = traits?.traditions ?? [];\n const actorEntryId = getTargetEntryIdFromData(spellData);\n\n const entry = actorEntryId\n ? pickSpellcastingEntryForActor(actor, traditions, actorEntryId)\n : await pickSpellcastingEntryWithDialog(actor, traditions);\n if (!entry) {\n const reason = actorEntryId\n ? game.i18n.format(`${I18N}.traditionMismatch`, {\n spellName,\n traditions: traditions.join(\", \") || game.i18n.localize(`${I18N}.noTradition`),\n })\n : game.i18n.localize(`${I18N}.learnNoCompatibleEntry`);\n ui.notifications.warn(reason);\n return;\n }\n\n const entryInfo = getEntryDisplayInfo(entry);\n const costCopper = getLearnSpellCostCopper(rankKey);\n const hours = getLearnSpellHours(rankKey, actor);\n const choice = await showLearnSpellDialog(spellName, costCopper, hours, entryInfo);\n if (!choice) return;\n\n if (choice === \"no\") {\n await addSpellWithoutCheck(spellData, actor, spellName, entry.id!);\n return;\n }\n\n await handleLearnSpell(spellData, actor, entry.id!);\n}\n\nasync function addSpellWithoutCheck(\n spellData: Record,\n actor: ActorPF2e,\n spellName: string,\n entryId: string,\n): Promise {\n await learnSpellHandler.addSpellDirectly(spellData, actor, entryId, spellName);\n}\n\nasync function handleLearnSpell(spellData: Record, actor: ActorPF2e, entryId: string): Promise {\n await learnSpellHandler.initiateFromSpellData(spellData, actor, entryId);\n}\n","import type { ActorPF2e, ItemPF2e } from \"foundry-pf2e\";\nimport { fireAndForget, getModuleSetting } from \"../../../utils.ts\";\nimport { I18N } from \"../helpers.ts\";\nimport { getSpellDocData, getSpellTraitsAndRank, spellIdentifier } from \"../spellData.ts\";\nimport { hasSpontaneousEntry, isSpellAlreadyKnownSync, pickSpellcastingEntryWithDialog } from \"../spellActorQueries.ts\";\nimport { LearnSpellHandler } from \"./learnSpellHandler.ts\";\nimport { showConfirm } from \"../dialogHelper.ts\";\nimport { isLocked } from \"../../../utils/locks.ts\";\nimport { DirectEntryTarget } from \"./spellAddInterceptHandler.ts\";\n\nfunction getEmbeddedSpell(scroll: ItemPF2e): Record | null {\n const spell = (scroll.system as { spell?: Record }).spell;\n if (spell && typeof spell === \"object\" && (spell as { name?: string }).name) return spell;\n return null;\n}\n\nfunction isScrollWithSpell(item: ItemPF2e): boolean {\n const system = item.system as { category?: string; spell?: unknown };\n return item.type === \"consumable\" && system.category === \"scroll\" && !!system.spell;\n}\n\nfunction isMystified(item: ItemPF2e): boolean {\n return (item.system as { identification?: { status?: string } })?.identification?.status === \"unidentified\";\n}\n\nasync function destroyScroll(scroll: ItemPF2e): Promise {\n if (!getModuleSetting(\"learnSpellDestroyScroll\")) return;\n if (!scroll.actor) return;\n const quantity = (scroll.system as { quantity?: number }).quantity ?? 1;\n await (quantity > 1 ? scroll.update({ \"system.quantity\": quantity - 1 }) : scroll.delete());\n}\n\nasync function handleScrollLearn(scroll: ItemPF2e, actor: ActorPF2e): Promise {\n if (isLocked(actor.id)) return;\n\n if (isMystified(scroll)) {\n ui.notifications.warn(game.i18n.localize(`${I18N}.scrollMystified`));\n return;\n }\n\n const embedded = getEmbeddedSpell(scroll);\n if (!embedded) return;\n\n const resolved = getSpellTraitsAndRank(embedded);\n if (!resolved) return;\n\n const confirmed = await showConfirm(\"learnFromScrollTitle\", \"learnFromScrollMessage\", {\n spellName: resolved.spellName,\n });\n if (!confirmed) return;\n\n const entry = await pickSpellcastingEntryWithDialog(actor, resolved.traditions);\n if (!entry) {\n ui.notifications.warn(\n game.i18n.format(`${I18N}.traditionMismatch`, {\n spellName: resolved.spellName,\n traditions: resolved.traditions.join(\", \"),\n }),\n );\n return;\n }\n\n const spellData = getSpellDocData(embedded);\n\n await new LearnSpellHandler(new DirectEntryTarget()).initiateFromSpellData(spellData, actor, entry.id!);\n await destroyScroll(scroll);\n}\n\nexport function scrollCreateIntercept(item: ItemPF2e, _data: object): void {\n if (!getModuleSetting(\"enableGeneralLearnSpell\")) return;\n if (!isScrollWithSpell(item)) return;\n\n const actor = item.actor as ActorPF2e | null;\n if (!actor || actor.type !== \"character\") return;\n\n const embedded = getEmbeddedSpell(item);\n if (embedded) {\n const ident = spellIdentifier(embedded);\n if (ident && isSpellAlreadyKnownSync(actor, ident) && hasSpontaneousEntry(actor)) return;\n }\n\n const name = item.name;\n const hookId = Hooks.on(\"createItem\", (created: ItemPF2e) => {\n if (created.actor?.id !== actor?.id || created.name !== name || !isScrollWithSpell(created)) return;\n Hooks.off(\"createItem\", hookId);\n fireAndForget(handleScrollLearn(created, actor!), \"createItem: scrollLearn\");\n });\n}\n","import { CreaturePF2e, ItemPF2e } from \"foundry-pf2e\";\nimport { CHARACTER_TYPE } from \"../xdy-pf2e-workbench.ts\";\nimport { MODULENAME } from \"../constants.ts\";\nimport { getModuleSetting, sendHeldItemChatMessage } from \"../utils.ts\";\nimport { preCreateItemSpellIntercept } from \"../feature/spells/learn/spellAddInterceptHandler.ts\";\nimport { scrollCreateIntercept } from \"../feature/spells/learn/scrollCreateIntercept.ts\";\n\nexport function preCreateItemHook(item: ItemPF2e, data: object, _options: object, _id: string): false | void {\n if (\n item.type === \"condition\" &&\n item.slug === \"unconscious\" &&\n item.actor?.isOfType(CHARACTER_TYPE) &&\n getModuleSetting(\"dropHeldItemsOnBecomingUnconscious\")\n ) {\n dropHeldItemsOnBecomingUnconscious(item.actor);\n }\n\n if (getModuleSetting(\"enableGeneralLearnSpell\")) {\n scrollCreateIntercept(item, data);\n const spellResult = preCreateItemSpellIntercept(item, data);\n if (spellResult === false) return false;\n }\n}\n\nfunction dropHeldItemsOnBecomingUnconscious(actor: CreaturePF2e) {\n const items = actor.inventory.filter((i) => i.isHeld);\n if (items && items.length > 0) {\n for (const item of items) {\n if (item.traits.has(\"free-hand\") || item.type === \"shield\" || item.traits.has(\"attached-to-shield\")) {\n // Presumed to strapped to an arm/worn on a hand, so just unreadied instead of dropped\n actor.changeCarryType(item, { carryType: \"worn\", handsHeld: 0, inSlot: false });\n } else {\n actor.changeCarryType(item, { carryType: \"dropped\", handsHeld: 0, inSlot: false });\n }\n }\n sendHeldItemChatMessage(\n actor,\n items,\n `${MODULENAME}.SETTINGS.dropHeldItemsOnBecomingUnconscious.message`,\n \"dropHeldItemsOnBecomingUnconscious ChatMessage\",\n );\n }\n}\n","import { ActorSystemData, CreaturePF2e } from \"foundry-pf2e\";\nimport { NPC_TYPE } from \"../xdy-pf2e-workbench.ts\";\nimport { getModuleSetting } from \"../utils.ts\";\nimport * as systems from \"../utils/systems.ts\";\nimport { dyingHandlingPreUpdateActorHook } from \"../feature/damageHandler/dyingHandling.ts\";\nimport { mystifyNpcItemsByRarity } from \"../feature/qolHandler/index.ts\";\n\nexport async function preUpdateActorHook(actor: CreaturePF2e, update: Record): Promise {\n const updateHp = fu.getProperty(update, \"system.attributes.hp.value\");\n\n // All these are only relevant if hp has changed (it's undefined otherwise)\n if (typeof updateHp === \"number\") {\n const currentActorHp = (actor.system).attributes.hp?.value || 0;\n if (\n game.user?.isGM &&\n actor?.type === NPC_TYPE &&\n actor?.items?.size > 0 &&\n currentActorHp > 0 &&\n updateHp <= 0 &&\n systems.getSystemSetting(\"automation\", \"lootableNPCs\") &&\n getModuleSetting(\"npcMystifyAllPhysicalMagicalItems\") === \"onZeroHp\"\n ) {\n await mystifyNpcItemsByRarity(actor);\n }\n\n const autoGainDying = getModuleSetting(\"autoGainDyingAtZeroHP\");\n dyingHandlingPreUpdateActorHook(actor, update, currentActorHp, updateHp, autoGainDying);\n }\n}\n","import { getModuleSetting } from \"../utils.ts\";\n\nexport function preUpdateTokenHook(\n _document: unknown,\n update: {\n x?: number | null;\n y?: number | null;\n },\n options: object,\n ..._args: unknown[]\n): void {\n if (getModuleSetting(\"tokenAnimation\") && (update.x !== null || update.y !== null)) {\n fu.setProperty(options, \"animation\", {\n movementSpeed: getModuleSetting(\"tokenAnimationSpeed\"),\n });\n }\n}\n","import { MODULENAME } from \"../constants.ts\";\n\nimport * as systems from \"../utils/systems.ts\";\n\nexport function readyHook(): void {\n const legacyVariantRuleAncestryParagon = game.settings.get(MODULENAME, \"legacyVariantRuleAncestryParagon\");\n const legacyVariantRuleDualClass = game.settings.get(MODULENAME, \"legacyVariantRuleDualClass\");\n\n // Add campaign feat sections if enabled\n if (legacyVariantRuleDualClass || legacyVariantRuleAncestryParagon) {\n const campaignFeatSections = systems.getSetting<\n {\n id: string;\n label: string;\n supported: string[];\n slots: number[];\n }[]\n >(\"campaignFeatSections\");\n if (legacyVariantRuleAncestryParagon) {\n if (!campaignFeatSections.find((section) => section.id === \"xdy_ancestryparagon\")) {\n campaignFeatSections.push({\n id: \"xdy_ancestryparagon\",\n label: game.i18n.localize(`${MODULENAME}.SETTINGS.legacyVariantRuleAncestryParagon.title`),\n supported: [\"ancestry\"],\n slots: [1, 3, 7, 11, 15, 19],\n });\n }\n }\n\n if (legacyVariantRuleDualClass) {\n if (!campaignFeatSections.find((section) => section.id === \"xdy_dualclass\")) {\n campaignFeatSections.push({\n id: \"xdy_dualclass\",\n label: game.i18n.localize(`${MODULENAME}.SETTINGS.legacyVariantRuleDualClass.title`),\n supported: [\"class\"],\n slots: [1, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20],\n });\n }\n }\n\n systems.setSetting(\"campaignFeatSections\", campaignFeatSections);\n }\n\n const campaignFeatSections = systems.getSetting<\n {\n id: string;\n label: string;\n supported: string[];\n slots: number[];\n }[]\n >(\"campaignFeatSections\");\n // ... or remove it if disabled.\n if (\n campaignFeatSections &&\n !legacyVariantRuleDualClass &&\n campaignFeatSections.find((section) => section.id === \"xdy_dualclass\")\n ) {\n campaignFeatSections.splice(\n campaignFeatSections.findIndex((section) => section.id === \"xdy_dualclass\"),\n 1,\n );\n systems.setSetting(\"campaignFeatSections\", campaignFeatSections);\n }\n\n if (\n campaignFeatSections &&\n !legacyVariantRuleAncestryParagon &&\n campaignFeatSections.find((section) => section.id === \"xdy_ancestryparagon\")\n ) {\n campaignFeatSections.splice(\n campaignFeatSections.findIndex((section) => section.id === \"xdy_ancestryparagon\"),\n 1,\n );\n systems.setSetting(\"campaignFeatSections\", campaignFeatSections);\n }\n}\n","import type { ActorPF2e } from \"foundry-pf2e\";\nimport { MODULENAME } from \"../../constants.ts\";\nimport { fireAndForget } from \"../../utils.ts\";\n\ninterface OglItemEntry {\n name: string;\n uuid: string;\n type: string;\n}\n\nconst SKIPPED_ITEM_TYPES = new Set([\"lore\", \"spellcastingEntry\"]);\n\nconst OGL_LICENSE = \"OGL\";\n\nlet activeOglDialog: foundry.applications.api.DialogV2 | null = null;\n\nfunction isOglItem(item: { type: string; system: { publication?: { license?: unknown } } }): boolean {\n if (SKIPPED_ITEM_TYPES.has(item.type)) return false;\n return (item.system.publication?.license as string | undefined) === OGL_LICENSE;\n}\n\nfunction getOglItems(actor: ActorPF2e): OglItemEntry[] {\n return actor.items.filter(isOglItem).map((item) => ({\n name: item.name,\n uuid: item.uuid,\n type: item.type,\n }));\n}\n\nfunction buildOglDialogContent(oglItems: OglItemEntry[]): string {\n const grouped = Map.groupBy(oglItems, (item) => item.type);\n const sortedTypes = [...grouped.keys()].sort();\n\n const sections = sortedTypes\n .map((type) => {\n const items = (grouped.get(type) ?? [])\n .sort((a, b) => a.name.localeCompare(b.name))\n .map((item) => `
  • @UUID[${item.uuid}]{${item.name}}
  • `)\n .join(\"\\n\");\n const localizedType = game.i18n.localize(`TYPES.Item.${type}`);\n return `

    ${localizedType}

    \\n
      \\n${items}\\n
    `;\n })\n .join(\"\\n\");\n\n return `\n
    \n

    ${game.i18n.format(`${MODULENAME}.SETTINGS.showCharacterOglTag.oglItemsFound`, { count: oglItems.length })}

    \n ${sections}\n
    \n `;\n}\n\nconst dialogLifecycle = {\n render: (_event: unknown, dialog: foundry.applications.api.DialogV2) => {\n activeOglDialog = dialog;\n },\n close: () => {\n activeOglDialog = null;\n },\n};\n\nexport async function showCharacterOglItemsDialog(actor: ActorPF2e): Promise {\n const oglItems = getOglItems(actor);\n const title = `${game.i18n.localize(`${MODULENAME}.SETTINGS.showCharacterOglTag.title`)}: ${actor.name}`;\n\n if (activeOglDialog) {\n await activeOglDialog.close();\n activeOglDialog = null;\n }\n\n // @ts-expect-error TextEditor is a Foundry global\n const content = await TextEditor.enrichHTML(buildOglDialogContent(oglItems));\n\n await foundry.applications.api.DialogV2.wait({\n window: { title, resizable: true },\n content,\n buttons: [{ action: \"close\", label: game.i18n.localize(\"Close\"), default: true }],\n ...dialogLifecycle,\n });\n}\n\nexport function actorHasOglContent(actor: ActorPF2e): boolean {\n return actor.items.some(isOglItem);\n}\n\nexport function addOglTagToCharacterSheet(html: HTMLElement, actor: ActorPF2e): boolean {\n if (!actorHasOglContent(actor)) return false;\n\n const traitsUl = html.querySelector(\".abcd ul.tags.traits\");\n if (!traitsUl) return false;\n\n if (traitsUl.querySelector(\".xdy-pf2e-workbench-ogl-char-tag\")) return false;\n\n const tooltipText = game.i18n.localize(`${MODULENAME}.SETTINGS.showCharacterOglTag.clickToView`);\n\n const oglTag = document.createElement(\"li\");\n oglTag.classList.add(\"tag\", \"xdy-pf2e-workbench-ogl-char-tag\");\n oglTag.textContent = \"OGL CONTENT\";\n oglTag.title = tooltipText;\n\n oglTag.addEventListener(\"click\", () => {\n fireAndForget(showCharacterOglItemsDialog(actor), \"showCharacterOglDialog\");\n });\n\n traitsUl.append(oglTag);\n\n return true;\n}\n","import { ActorPF2e, ActorSheetPF2e, FeatPF2e, ItemPF2e } from \"foundry-pf2e\";\nimport { CHARACTER_TYPE } from \"../../xdy-pf2e-workbench.ts\";\nimport { MODULENAME } from \"../../constants.ts\";\nimport { fireAndForget, getModuleSetting, shouldIHandleThis } from \"../../utils.ts\";\n\nexport function itemFromActor(element: Element, attributeName: string, actor: ActorPF2e): ItemPF2e | null {\n const itemId = element.getAttribute(attributeName);\n return itemId ? (actor.items?.get(itemId) ?? null) : null;\n}\n\nexport function itemFromCompendium(element: Element, qualifiedName: string): ItemPF2e | null {\n const itemUuid = element.getAttribute(qualifiedName);\n return itemUuid ? fromUuidSync(itemUuid) : null;\n}\n\ntype FetchItemFn = (element: Element) => ItemPF2e | null;\n\ninterface ColorItemsByRarityOptions {\n html: HTMLElement | undefined;\n actor: ActorPF2e;\n setting: string;\n listSelector: string;\n itemSelector: string;\n fetchItem: FetchItemFn;\n headingSelector?: string;\n}\n\nexport function colorActorItemsByRarity({\n html,\n actor,\n setting,\n listSelector,\n itemSelector,\n fetchItem,\n headingSelector = \"h4\",\n}: ColorItemsByRarityOptions): void {\n if (actor.type === CHARACTER_TYPE && getModuleSetting(setting)) {\n const lists = html?.querySelectorAll(listSelector) ?? [];\n for (const list of lists) {\n const itemNodes = list.querySelectorAll(itemSelector);\n for (const element of itemNodes) {\n const item = fetchItem(element);\n if (item) {\n const rarity = item.system?.traits?.rarity;\n if (rarity) {\n const headingElements = element.querySelectorAll(headingSelector);\n headingElements.forEach((heading) =>\n heading.classList.add(`xdy-pf2e-workbench-rarity-${rarity}`),\n );\n }\n }\n }\n }\n }\n}\n\nexport function markFeatsWithPrerequisites(html: HTMLElement, actor: ActorPF2e): void {\n if (actor.type !== CHARACTER_TYPE || !getModuleSetting(\"playerFeatsPrerequisiteHint\")) return;\n\n const featLists = html.querySelectorAll(\".feats-pane\");\n featLists.forEach((list) => {\n const slots = list.querySelectorAll(\".slot\");\n for (const element of slots) {\n const feat = itemFromActor(element, \"data-item-id\", actor);\n if (feat && feat.system.prerequisites.value.length > 0) {\n const h4Elements = element.querySelectorAll(\"h4\");\n h4Elements.forEach((h4Element) => (h4Element.innerHTML += \"*\"));\n }\n }\n });\n}\n\nconst WORKBENCH_SPELL_TO_CHAT = \"workbench-spell-to-chat\";\n\n/** Walk up from the action element to the spell container
  • . */\nfunction getSpellContainer(target: HTMLElement): Element | null {\n return target?.closest(`[data-action=\"${WORKBENCH_SPELL_TO_CHAT}\"]`)?.parentElement?.parentElement ?? null;\n}\n\nexport function rewriteSpellToChatToSendLink(sheet: ActorSheetPF2e, html: HTMLElement): void {\n if (sheet.actor?.type !== CHARACTER_TYPE) return;\n if (!getModuleSetting(\"playerSpellsChangeSendToChat\")) return;\n\n const actor = sheet.actor;\n\n html.querySelectorAll(\"li.spell\").forEach((spellElement) => {\n spellElement\n .querySelectorAll('div.item-name [data-action=\"item-to-chat\"]')\n .forEach((actionElement) => {\n if (actionElement.getAttribute(\"data-action\") === WORKBENCH_SPELL_TO_CHAT) return;\n\n actionElement.setAttribute(\"data-action\", WORKBENCH_SPELL_TO_CHAT);\n actionElement.onclick = (event: MouseEvent) => {\n const target = event.target as HTMLElement;\n const spellContainer = getSpellContainer(target);\n\n if (!shouldIHandleThis(actor) || !spellContainer) return;\n\n const item = itemFromActor(spellContainer, \"data-item-id\", actor);\n if (!item || item.type !== \"spell\") return;\n\n const flavor = `${game.i18n.localize(`${MODULENAME}.SETTINGS.playerSpellsChangeSendToChat.text`)}@UUID[${item.sourceId}]

    `;\n fireAndForget(\n ChatMessage.create({\n style: CONST.CHAT_MESSAGE_STYLES.OOC,\n speaker: ChatMessage.getSpeaker(),\n flavor,\n }),\n \"playerSpellsChange ChatMessage\",\n );\n };\n });\n });\n}\n","import { ActorPF2e, ActorSheetPF2e } from \"foundry-pf2e\";\n\nimport { extractHtmlElement, getModuleSetting } from \"../utils.ts\";\nimport { addOglTagToCharacterSheet } from \"../feature/characterOglContent/index.ts\";\nimport {\n colorActorItemsByRarity,\n itemFromActor,\n itemFromCompendium,\n markFeatsWithPrerequisites,\n rewriteSpellToChatToSendLink,\n} from \"../feature/actorSheet/index.ts\";\n\nexport function renderActorSheetHook(sheet: ActorSheetPF2e, element: unknown): void {\n const html = extractHtmlElement(element);\n if (!html || !sheet.actor) return;\n const actor = sheet.actor;\n\n colorActorItemsByRarity({\n html,\n actor,\n setting: \"playerSpellsRarityColour\",\n listSelector: \".spell-list\",\n itemSelector: \".spell\",\n fetchItem: (el) => itemFromActor(el, \"data-item-id\", actor),\n });\n colorActorItemsByRarity({\n html,\n actor,\n setting: \"playerFeatsRarityColour\",\n listSelector: \".feats-pane\",\n itemSelector: \".slot\",\n fetchItem: (el) => itemFromActor(el, \"data-item-id\", actor),\n });\n colorActorItemsByRarity({\n html,\n actor,\n setting: \"playerCraftingRarityColour\",\n listSelector: \".crafting-pane\",\n itemSelector: \".formula-item\",\n fetchItem: (el) => itemFromCompendium(el, \"data-item-uuid\"),\n });\n colorActorItemsByRarity({\n html,\n actor,\n setting: \"playerAbcdRarityColour\",\n listSelector: \".abcd\",\n itemSelector: \".detail\",\n fetchItem: (el) => itemFromActor(el.querySelector(\".detail-item-control\") ?? el, \"data-item-id\", actor),\n headingSelector: \"h3\",\n });\n\n markFeatsWithPrerequisites(html, actor);\n rewriteSpellToChatToSendLink(sheet, html);\n\n if (getModuleSetting(\"showCharacterOglTag\")) {\n addOglTagToCharacterSheet(html, actor);\n }\n}\n","import { ChatMessagePF2e } from \"foundry-pf2e\";\nimport { MODULENAME } from \"../../constants.ts\";\nimport * as systems from \"../../utils/systems.ts\";\n\nexport async function hideSpellNameInDamageroll(message: ChatMessagePF2e, html: HTMLElement): Promise {\n const uuid = systems.getFlag(message, \"origin.uuid\");\n if (!uuid) return;\n\n const mostRecentCasting = game.messages.contents.findLast(\n (m) => systems.getFlag(m, \"casting\") && systems.getFlag(m, \"origin.uuid\") === uuid,\n );\n if (!mostRecentCasting?.item || mostRecentCasting.whisper.length === 0) return;\n\n const flavor = html.querySelector(\".flavor-text\");\n if (!flavor?.innerHTML) return;\n\n const replacement =\n game.i18n.localize(`${MODULENAME}.SETTINGS.castPrivateSpell.aSpell`) + '

    ($&)

    ';\n flavor.innerHTML = flavor.innerHTML.replace(mostRecentCasting.item.name, replacement);\n}\n","import { ChatMessagePF2e } from \"foundry-pf2e\";\nimport { MODULENAME } from \"../constants.ts\";\nimport * as systems from \"../utils/systems.ts\";\nimport { getModuleSetting, isActuallyDamageRoll } from \"../utils.ts\";\nimport {\n chatActionCardDescriptionCollapse,\n chatAttackCardDescriptionCollapse,\n chatCardDescriptionCollapse,\n damageCardExpand,\n} from \"../feature/qolHandler/index.ts\";\nimport { handleDyingRecoveryRoll } from \"../feature/damageHandler/dyingHandling.ts\";\nimport { hideSpellNameInDamageroll } from \"../feature/qolHandler/hidePrivateSpellName.ts\";\n\nfunction needsCollapsing(setting: string): boolean {\n return setting === \"collapsedDefault\" || setting === \"nonCollapsedDefault\";\n}\n\nexport function renderChatMessageHook(message: ChatMessagePF2e, html: HTMLElement): void {\n deprecatedDyingHandlingRenderChatMessageHook(message);\n\n const isDamageRoll = isActuallyDamageRoll(message);\n\n if (isDamageRoll) {\n const expandDamageRolls = getModuleSetting(\"autoExpandDamageRolls\");\n if ([\"expandedAll\", \"expandedNew\", \"expandedNewest\"].includes(expandDamageRolls)) {\n damageCardExpand(message, html, expandDamageRolls);\n }\n\n const castPrivateSpellEnabled = getModuleSetting(\"castPrivateSpell\");\n if (castPrivateSpellEnabled && systems.getFlag(message, \"origin.type\") === \"spell\") {\n hideSpellNameInDamageroll(message, html);\n }\n } else {\n const collapseItemContent = getModuleSetting(\"autoCollapseItemChatCardContent\");\n const collapseItemAttackContent = getModuleSetting(\"autoCollapseItemAttackChatCardContent\");\n const collapseItemActionContent = getModuleSetting(\"autoCollapseItemActionChatCardContent\");\n\n if (needsCollapsing(collapseItemContent)) {\n chatCardDescriptionCollapse(html);\n }\n\n const itemType = message.item?.type ?? \"\";\n if (needsCollapsing(collapseItemAttackContent) && [\"weapon\", \"melee\", \"spell\"].includes(itemType)) {\n chatAttackCardDescriptionCollapse(html);\n }\n\n if (needsCollapsing(collapseItemActionContent) && (itemType === \"action\" || !message.item)) {\n chatActionCardDescriptionCollapse(html);\n }\n }\n\n const heroPointRules = getModuleSetting(\"heroPointRules\");\n if (heroPointRules !== \"no\") {\n handleVariantHeroPointRules(message, html);\n }\n}\n\nfunction deprecatedDyingHandlingRenderChatMessageHook(message: ChatMessagePF2e): void {\n handleDyingRecoveryRoll(message, getModuleSetting(\"handleDyingRecoveryRoll\"));\n}\n\nfunction addHeroPointTag(element: HTMLElement, slug: string, localeKey: string): boolean {\n const tags = element.querySelector(\".flavor-text > .tags.modifiers\");\n const newTotalElem = element.querySelector(\".reroll-second .dice-total\");\n if (!tags || !newTotalElem) return false;\n\n const newTag = document.createElement(\"span\");\n newTag.classList.add(\"tag\", \"tag_transparent\", slug);\n newTag.innerText = game.i18n.localize(`${MODULENAME}.SETTINGS.heroPointRules.${localeKey}`);\n newTag.dataset.slug = slug;\n\n const existingTag = tags.querySelector(\".tag\") as HTMLElement;\n if (existingTag?.dataset.visibility === \"gm\") {\n newTag.dataset.visibility = \"gm\";\n }\n\n tags.append(newTag);\n newTotalElem.classList.add(slug);\n return true;\n}\n\nfunction handleVariantHeroPointRules(message: ChatMessagePF2e, element: HTMLElement): void {\n const lastRoll = message.rolls.at(-1);\n if (!lastRoll) return;\n\n if (lastRoll.options.keeleyAdd10) {\n if (addHeroPointTag(element, \"keeley-add-10\", \"bonusTagKeeleys\")) {\n const formulaElem = element.querySelector(\".reroll-discard .dice-formula\");\n if (formulaElem) {\n const span = document.createElement(\"span\");\n span.className = \"keeley-add-10\";\n span.innerText = \" + 10\";\n formulaElem.append(span);\n }\n }\n }\n\n if (lastRoll.options.useHighestRoll) {\n addHeroPointTag(element, \"use-highest-roll\", \"bonusTagUseHighestRoll\");\n }\n\n if (lastRoll.options.heroicReroll) {\n addHeroPointTag(element, \"heroic-reroll\", \"bonusTagHeroicRerolls\");\n }\n}\n","import { phase, Phase } from \"../lifecycle.ts\";\nimport { getModuleSetting } from \"../utils.ts\";\n\nfunction encodeUriPathSegment(text: string): string {\n try {\n const isEncoded = text !== decodeURIComponent(text);\n return isEncoded ? text : encodeURIComponent(text);\n } catch {\n // text contains a raw % sign\n return encodeURIComponent(text);\n }\n}\n\nexport function renderGamePauseHook(): void {\n if (!document?.querySelector(\"#pause\")?.classList.contains(\"paused\")) {\n return;\n }\n\n const style = document.documentElement.style;\n\n const imagePath = getModuleSetting(\"customPauseImage\");\n\n if (imagePath !== \"\") {\n let url: string;\n if (/^https?:/i.test(imagePath)) {\n const imageUrl = new URL(imagePath);\n const strings = imageUrl.pathname.split(\"/\");\n strings.forEach((str, index) => {\n strings[index] = encodeUriPathSegment(str);\n });\n imageUrl.pathname = strings.join(\"/\");\n\n url = `url(\"${imageUrl}\")`;\n } else {\n url = `url(\"../../../${encodeUriPathSegment(imagePath)}\")`;\n }\n style.setProperty(\"--xdy-pf2e-workbench-pause\", url);\n }\n\n if (phase >= Phase.READY) {\n const element = document.querySelector(\"#pause > figcaption\");\n const pauseImage = document.querySelector(\"#pause > img\");\n\n const text = getModuleSetting(\"customPauseText\");\n\n if (text && element) {\n element.textContent = text;\n }\n\n if (getModuleSetting(\"pauseImageNoSpin\")) {\n pauseImage?.classList.remove(\"fa-spin\");\n } else {\n pauseImage?.classList.add(\"fa-spin\");\n }\n }\n}\n","import { ItemPF2e, ItemSheetPF2e } from \"foundry-pf2e\";\n\nimport { extractHtmlElement, getModuleSetting } from \"../utils.ts\";\n\nexport function renderItemSheetHook(sheet: ItemSheetPF2e, element: unknown): void {\n const html = extractHtmlElement(element);\n\n if (!html) return;\n\n if (!getModuleSetting(\"showItemLicenseTags\")) return;\n\n const item = sheet.item;\n const license: string | undefined = item?.system?.publication?.license;\n if (license !== \"ORC\" && license !== \"OGL\") return;\n\n const details = html.querySelector(\".details\");\n if (!details) return;\n\n // Avoid adding a duplicate tag\n if (details.querySelector(\".xdy-pf2e-workbench-license-tag\")) return;\n\n const licenseTag = document.createElement(\"span\");\n licenseTag.classList.add(\"tag\", \"xdy-pf2e-workbench-license-tag\");\n licenseTag.textContent = `LICENSE:${license}`;\n details.append(licenseTag);\n}\n","import { getModuleSetting } from \"../utils.ts\";\nimport { renderNameHud } from \"../feature/tokenMystificationHandler/index.ts\";\n\nexport function renderTokenHUDHook(app: { object?: unknown }, html: HTMLElement, _data: unknown): void {\n if (html && game.user?.isGM && getModuleSetting(\"npcMystifier\")) {\n renderNameHud(app as { object?: unknown }, html);\n }\n}\n","import type { EncounterPF2e } from \"foundry-pf2e\";\nimport { clearToolbeltCaches } from \"../feature/damageHandler/toolbeltIntegration.ts\";\n\nexport function updateCombatHook(_encounter: EncounterPF2e, changes: { round?: number }): void {\n if (changes.round !== undefined) {\n clearToolbeltCaches();\n }\n}\n","/*\n * Copyright 2021 Andrew Cuccinello, 2022 Jonas Karlsson\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { scaleNPCToLevel } from \"./NPCScaler.ts\";\nimport { ActorDirectoryPF2e } from \"foundry-pf2e\";\nimport { ContextMenuEntry } from \"foundry/client/applications/ux/context-menu.mts\";\nimport type DialogV2 from \"foundry/client/applications/api/dialog.mjs\";\n\nfunction condition(li: HTMLElement): boolean {\n return li.dataset.entryId !== undefined && (game.actors.get(li.dataset.entryId)?.isOfType(\"npc\") ?? false);\n}\n\nfunction callback(li: HTMLElement) {\n const actor = game.actors.get(li.dataset.entryId, { strict: true });\n const oldLevel = actor.level;\n if (!actor.isOfType(\"npc\")) return;\n\n new foundry.applications.api.DialogV2({\n window: { title: \"Scale NPC\" },\n content: `\n

    Scale a creature to a range of levels, creating the creature at each level in the range. The min level must be less than or\n equal to the max level. To only scale to a single level, set both equal to the desired level.

    \n
    \n
    `,\n buttons: [\n {\n action: \"scale\",\n default: true,\n icon: '',\n label: \"Scale\",\n callback: async (_event: PointerEvent | SubmitEvent, button: HTMLButtonElement, _dialog: DialogV2) => {\n ui.notifications.info(`Scaling NPC... please wait.`);\n const elements = button.form?.elements as HTMLFormControlsCollection & {\n startLevel: HTMLInputElement;\n endLevel: HTMLInputElement;\n };\n const startLevel = parseInt(elements.startLevel.value);\n const endLevel = parseInt(elements.endLevel.value);\n\n for (let i = startLevel; i <= endLevel; i++) {\n await scaleNPCToLevel(actor, i);\n }\n ui.notifications.info(`Scaled ${actor.name} to levels ${startLevel} - ${endLevel}.`);\n },\n },\n ],\n }).render({ force: true });\n}\n\nexport function onScaleNPCContextHook(_actors: ActorDirectoryPF2e, menuItems: ContextMenuEntry[]) {\n if (!game.user.isGM) return;\n menuItems.push({\n name: \"Scale to Level\",\n icon: '',\n condition,\n callback,\n });\n}\n","import { updateHooks } from \"../xdy-pf2e-workbench.ts\";\nimport { MODULENAME } from \"../constants.ts\";\nimport { HideListTemplateData, SettingsMenuPF2eWorkbench } from \"./menu.ts\";\nimport { capitalize, getModuleSetting, MAX_ABSOLUTE_LEVEL, NOT_MYSTIFIED_VALUE } from \"../utils.ts\";\nimport { SettingRegistration } from \"foundry/client/helpers/client-settings.mts\";\n\nfunction buildPlThresholdChoices(): Record {\n return {\n [NOT_MYSTIFIED_VALUE]: game.i18n.localize(`${MODULENAME}.SETTINGS.mystifyThreshold.notMystified`),\n \"4\": game.i18n.localize(`${MODULENAME}.SETTINGS.mystifyThreshold.plus4`),\n \"3\": game.i18n.localize(`${MODULENAME}.SETTINGS.mystifyThreshold.plus3`),\n \"2\": game.i18n.localize(`${MODULENAME}.SETTINGS.mystifyThreshold.plus2`),\n \"1\": game.i18n.localize(`${MODULENAME}.SETTINGS.mystifyThreshold.plus1`),\n \"0\": game.i18n.localize(`${MODULENAME}.SETTINGS.mystifyThreshold.plus0`),\n \"-1\": game.i18n.localize(`${MODULENAME}.SETTINGS.mystifyThreshold.minus1`),\n \"-2\": game.i18n.localize(`${MODULENAME}.SETTINGS.mystifyThreshold.minus2`),\n \"-3\": game.i18n.localize(`${MODULENAME}.SETTINGS.mystifyThreshold.minus3`),\n \"-4\": game.i18n.localize(`${MODULENAME}.SETTINGS.mystifyThreshold.minus4`),\n };\n}\n\nfunction buildAbsThresholdChoices(): Record {\n const choices: Record = {\n [NOT_MYSTIFIED_VALUE]: game.i18n.localize(`${MODULENAME}.SETTINGS.mystifyThreshold.notMystified`),\n };\n for (let i = 0; i <= MAX_ABSOLUTE_LEVEL; i++) {\n choices[String(i)] = String(i);\n }\n return choices;\n}\n\nconst PL_THRESHOLD_ORDER = [\"999\", \"4\", \"3\", \"2\", \"1\", \"0\", \"-1\", \"-2\", \"-3\", \"-4\"];\n\nfunction sortPlThresholdOptions(select: HTMLSelectElement): void {\n const orderIndex = new Map(PL_THRESHOLD_ORDER.map((val, idx) => [val, idx]));\n const all = [...select.options];\n all.sort((a, b) => {\n const ai = orderIndex.get(a.value) ?? 9999;\n const bi = orderIndex.get(b.value) ?? 9999;\n return ai - bi;\n });\n for (const opt of all) {\n select.appendChild(opt);\n }\n}\n\nconst RARITIES = [\"common\", \"uncommon\", \"rare\", \"unique\"] as const;\n\nexport class WorkbenchItemMystificationSettings extends SettingsMenuPF2eWorkbench {\n static override namespace = \"itemMystificationSettings\";\n static override readonly hidelist: HideListTemplateData = {\n npcMystifyAllPhysicalMagicalItemsOfThisLevelOrGreaterUsingPartyLevel: {\n type: \"input\",\n falsy: false,\n list: RARITIES.flatMap((r) => {\n const cap = capitalize(r);\n return [`mystifyThreshold${cap}Pl`];\n }),\n },\n };\n\n public static override get settings(): Record {\n return {\n npcMystifyAllPhysicalMagicalItems: {\n name: `${MODULENAME}.SETTINGS.npcMystifyAllPhysicalMagicalItems.name`,\n hint: `${MODULENAME}.SETTINGS.npcMystifyAllPhysicalMagicalItems.hint`,\n scope: \"world\",\n default: \"no\",\n type: String,\n choices: {\n no: game.i18n.localize(`${MODULENAME}.SETTINGS.npcMystifyAllPhysicalMagicalItems.no`),\n onScene: game.i18n.localize(`${MODULENAME}.SETTINGS.npcMystifyAllPhysicalMagicalItems.onScene`),\n onZeroHp: game.i18n.localize(`${MODULENAME}.SETTINGS.npcMystifyAllPhysicalMagicalItems.onZeroHp`),\n },\n onChange: () => updateHooks(),\n requiresReload: true,\n },\n npcMystifyAllPhysicalMagicalItemsOfThisLevelOrGreaterUsingPartyLevel: {\n name: `${MODULENAME}.SETTINGS.npcMystifyAllPhysicalMagicalItemsOfThisLevelOrGreaterUsingPartyLevel.name`,\n hint: `${MODULENAME}.SETTINGS.npcMystifyAllPhysicalMagicalItemsOfThisLevelOrGreaterUsingPartyLevel.hint`,\n scope: \"world\",\n default: false,\n type: Boolean,\n },\n ...WorkbenchItemMystificationSettings.thresholdSettings(\"Pl\", buildPlThresholdChoices),\n ...WorkbenchItemMystificationSettings.thresholdSettings(\"Abs\", buildAbsThresholdChoices),\n };\n }\n\n private static thresholdSettings(\n suffix: \"Pl\" | \"Abs\",\n choicesBuilder: () => Record,\n ): Record {\n const choices = choicesBuilder();\n const result: Record = {};\n for (const rarity of RARITIES) {\n const cap = capitalize(rarity);\n result[`mystifyThreshold${cap}${suffix}`] = {\n name: `${MODULENAME}.SETTINGS.mystifyThreshold.name${suffix}${cap}`,\n hint: `${MODULENAME}.SETTINGS.mystifyThreshold.hint${suffix}`,\n scope: \"world\",\n default: NOT_MYSTIFIED_VALUE,\n type: String,\n choices,\n };\n }\n return result;\n }\n\n override async _onRender(context: object, options: object): Promise {\n await super._onRender(context, options);\n\n const absSettingKey = \"npcMystifyAllPhysicalMagicalItemsOfThisLevelOrGreaterUsingPartyLevel\";\n\n const applyAbsVisibility = (usingPartyLevel: boolean): void => {\n for (const rarity of RARITIES) {\n const cap = capitalize(rarity);\n const absForm = this.element.querySelector(\n `.form-group:has(.form-fields [name=\"mystifyThreshold${cap}Abs\"])`,\n );\n SettingsMenuPF2eWorkbench.hideForm(absForm, !usingPartyLevel);\n }\n };\n\n applyAbsVisibility(getModuleSetting(absSettingKey));\n\n const checkbox = this.element.querySelector(`.form-fields [name=\"${absSettingKey}\"]`);\n checkbox?.addEventListener(\"change\", () => applyAbsVisibility(checkbox.checked));\n\n for (const rarity of RARITIES) {\n const cap = capitalize(rarity);\n const plSelect = this.element.querySelector(\n `.form-fields [name=\"mystifyThreshold${cap}Pl\"]`,\n );\n if (plSelect) {\n sortPlThresholdOptions(plSelect);\n }\n }\n }\n}\n","import { SettingsMenuPF2eWorkbench } from \"./menu.ts\";\nimport { updateHooks } from \"../xdy-pf2e-workbench.ts\";\nimport { MODULENAME } from \"../constants.ts\";\nimport { SettingRegistration } from \"foundry/client/helpers/client-settings.mts\";\n\nexport class WorkbenchRemindersSettings extends SettingsMenuPF2eWorkbench {\n static override namespace = \"remindersSettings\";\n\n public static override get settings(): Record {\n return {\n reminderCannotAttack: {\n name: `${MODULENAME}.SETTINGS.reminderCannotAttack.name`,\n hint: `${MODULENAME}.SETTINGS.reminderCannotAttack.hint`,\n scope: \"world\",\n config: true,\n default: false,\n type: String,\n choices: {\n no: game.i18n.localize(`${MODULENAME}.SETTINGS.reminderCannotAttack.no`),\n reminder: game.i18n.localize(`${MODULENAME}.SETTINGS.reminderCannotAttack.reminder`),\n cancelAttack: game.i18n.localize(`${MODULENAME}.SETTINGS.reminderCannotAttack.cancelAttack`),\n },\n onChange: () => updateHooks(),\n requiresReload: true,\n },\n reminderCannotAttackIgnoreDeadEidolon: {\n name: `${MODULENAME}.SETTINGS.reminderCannotAttackIgnoreDeadEidolon.name`,\n hint: `${MODULENAME}.SETTINGS.reminderCannotAttackIgnoreDeadEidolon.hint`,\n scope: \"world\",\n config: true,\n default: false,\n type: Boolean,\n onChange: () => updateHooks(),\n requiresReload: true,\n },\n reminderTargeting: {\n name: `${MODULENAME}.SETTINGS.reminderTargeting.name`,\n hint: `${MODULENAME}.SETTINGS.reminderTargeting.hint`,\n scope: \"world\",\n config: true,\n default: \"no\",\n type: String,\n choices: {\n no: game.i18n.localize(`${MODULENAME}.SETTINGS.reminderTargeting.no`),\n reminder: game.i18n.localize(`${MODULENAME}.SETTINGS.reminderTargeting.reminder`),\n mustTarget: game.i18n.localize(`${MODULENAME}.SETTINGS.reminderTargeting.mustTarget`),\n },\n onChange: () => updateHooks(),\n requiresReload: true,\n },\n actionsReminderAllow: {\n name: `${MODULENAME}.SETTINGS.actionsReminderAllow.name`,\n hint: `${MODULENAME}.SETTINGS.actionsReminderAllow.hint`,\n scope: \"world\",\n config: true,\n default: \"none\",\n type: String,\n choices: {\n none: game.i18n.localize(`${MODULENAME}.SETTINGS.actionsReminderAllow.none`),\n all: game.i18n.localize(`${MODULENAME}.SETTINGS.actionsReminderAllow.all`),\n gm: game.i18n.localize(`${MODULENAME}.SETTINGS.actionsReminderAllow.gm`),\n players: game.i18n.localize(`${MODULENAME}.SETTINGS.actionsReminderAllow.players`),\n },\n onChange: () => updateHooks(),\n requiresReload: true,\n },\n reminderBreathWeapon: {\n name: `${MODULENAME}.SETTINGS.reminderBreathWeapon.name`,\n hint: `${MODULENAME}.SETTINGS.reminderBreathWeapon.hint`,\n scope: \"world\",\n config: true,\n default: false,\n type: Boolean,\n onChange: () => updateHooks(),\n requiresReload: true,\n },\n reminderBreathWeaponHidden: {\n name: `${MODULENAME}.SETTINGS.reminderBreathWeaponHidden.name`,\n hint: `${MODULENAME}.SETTINGS.reminderBreathWeaponHidden.hint`,\n scope: \"world\",\n config: true,\n default: false,\n type: Boolean,\n onChange: () => updateHooks(),\n requiresReload: true,\n },\n heroPointHandler: {\n name: `${MODULENAME}.SETTINGS.heroPointHandler.name`,\n hint: `${MODULENAME}.SETTINGS.heroPointHandler.hint`,\n scope: \"world\",\n config: true,\n default: false,\n type: Boolean,\n onChange: () => updateHooks(),\n requiresReload: true,\n },\n heropointHandlerNotificationChat: {\n name: `${MODULENAME}.SETTINGS.heropointHandlerNotificationChat.name`,\n hint: `${MODULENAME}.SETTINGS.heropointHandlerNotificationChat.hint`,\n scope: \"world\",\n config: true,\n default: true,\n type: Boolean,\n onChange: () => updateHooks(),\n requiresReload: true,\n },\n heroPointHandlerStartTimerOnReady: {\n name: `${MODULENAME}.SETTINGS.heroPointHandlerStartTimerOnReady.name`,\n hint: `${MODULENAME}.SETTINGS.heroPointHandlerStartTimerOnReady.hint`,\n scope: \"world\",\n config: true,\n default: false,\n type: Boolean,\n onChange: () => updateHooks(),\n requiresReload: true,\n },\n heroPointHandlerDefaultTimeoutMinutes: {\n name: `${MODULENAME}.SETTINGS.heroPointHandlerDefaultTimeoutMinutes.name`,\n hint: `${MODULENAME}.SETTINGS.heroPointHandlerDefaultTimeoutMinutes.hint`,\n scope: \"world\",\n config: true,\n default: 60,\n type: Number,\n onChange: () => updateHooks(),\n requiresReload: true,\n },\n heropointHandlerNotification: {\n name: `${MODULENAME}.SETTINGS.heropointHandlerNotification.name`,\n hint: `${MODULENAME}.SETTINGS.heropointHandlerNotification.hint`,\n scope: \"world\",\n config: true,\n default: false,\n type: Boolean,\n onChange: () => updateHooks(),\n requiresReload: true,\n },\n heropointHandlerRandomization: {\n name: `${MODULENAME}.SETTINGS.heropointHandlerRandomization.name`,\n hint: `${MODULENAME}.SETTINGS.heropointHandlerRandomization.hint`,\n scope: \"world\",\n config: true,\n default: \"random\",\n type: String,\n choices: {\n none: game.i18n.localize(`${MODULENAME}.SETTINGS.heropointHandlerRandomization.none`),\n random: game.i18n.localize(`${MODULENAME}.SETTINGS.heropointHandlerRandomization.random`),\n randomPartymemberThatHasNotReceivedAHeropoint: game.i18n.localize(\n `${MODULENAME}.SETTINGS.heropointHandlerRandomization.randomPartymemberThatHasNotReceivedAHeropoint`,\n ),\n },\n onChange: () => updateHooks(),\n requiresReload: true,\n },\n };\n }\n}\n","import { updateHooks } from \"../xdy-pf2e-workbench.ts\";\nimport { MODULENAME } from \"../constants.ts\";\nimport { HideListTemplateData, SettingsMenuPF2eWorkbench } from \"./menu.ts\";\nimport { SettingRegistration } from \"foundry/client/helpers/client-settings.mts\";\n\nexport class WorkbenchWorldAutomationSettings extends SettingsMenuPF2eWorkbench {\n static override namespace = \"automationWorldSettings\";\n static override readonly hidelist: HideListTemplateData = {\n autoGainDyingAtZeroHP: {\n type: \"select\",\n falsy: \"no\",\n list: [\n \"nonLethalIsNotLethal\",\n \"autoGainDyingAtZeroHPIfCriticallyHitOneMore\",\n \"autoGainDyingIfTakingDamageWhenAlreadyDying\",\n \"autoGainDyingIgnoresTargeting\",\n ],\n },\n };\n\n public static override get settings(): Record {\n return {\n enableAutomaticMove: {\n name: `${MODULENAME}.SETTINGS.enableAutomaticMove.name`,\n hint: `${MODULENAME}.SETTINGS.enableAutomaticMove.hint`,\n scope: \"world\",\n config: true,\n default: \"noAutomation\",\n type: String,\n choices: {\n noAutomation: game.i18n.localize(`${MODULENAME}.SETTINGS.enableAutomaticMove.noAutomation`),\n reaching0HP: game.i18n.localize(`${MODULENAME}.SETTINGS.enableAutomaticMove.reaching0HP`),\n reaching0HPCharactersOnly: game.i18n.localize(\n `${MODULENAME}.SETTINGS.enableAutomaticMove.reaching0HPCharactersOnly`,\n ),\n },\n onChange: () => updateHooks(),\n requiresReload: true,\n },\n autoRollDamageAllow: {\n name: `${MODULENAME}.SETTINGS.autoRollDamageAllow.name`,\n hint: `${MODULENAME}.SETTINGS.autoRollDamageAllow.hint`,\n scope: \"world\",\n config: true,\n default: \"none\",\n type: String,\n choices: {\n none: game.i18n.localize(`${MODULENAME}.SETTINGS.autoRollDamageAllow.none`),\n all: game.i18n.localize(`${MODULENAME}.SETTINGS.autoRollDamageAllow.all`),\n gm: game.i18n.localize(`${MODULENAME}.SETTINGS.autoRollDamageAllow.gm`),\n players: game.i18n.localize(`${MODULENAME}.SETTINGS.autoRollDamageAllow.players`),\n },\n onChange: () => updateHooks(),\n requiresReload: true,\n },\n experimentalToolbeltSaveIntegration: {\n name: `${MODULENAME}.SETTINGS.experimentalToolbeltSaveIntegration.name`,\n hint: `${MODULENAME}.SETTINGS.experimentalToolbeltSaveIntegration.hint`,\n scope: \"world\",\n config: true,\n default: false,\n type: Boolean,\n onChange: () => updateHooks(),\n requiresReload: true,\n },\n applyPersistentDamage: {\n name: `${MODULENAME}.SETTINGS.applyPersistentDamage.name`,\n hint: `${MODULENAME}.SETTINGS.applyPersistentDamage.hint`,\n scope: \"world\",\n config: true,\n default: false,\n type: Boolean,\n onChange: () => updateHooks(),\n requiresReload: true,\n },\n applyPersistentDamageRecoveryRoll: {\n name: `${MODULENAME}.SETTINGS.applyPersistentDamageRecoveryRoll.name`,\n hint: `${MODULENAME}.SETTINGS.applyPersistentDamageRecoveryRoll.hint`,\n scope: \"world\",\n config: true,\n default: false,\n type: Boolean,\n onChange: () => updateHooks(),\n requiresReload: true,\n },\n applyPersistentHealing: {\n name: `${MODULENAME}.SETTINGS.applyPersistentHealing.name`,\n hint: `${MODULENAME}.SETTINGS.applyPersistentHealing.hint`,\n scope: \"world\",\n config: true,\n default: false,\n type: Boolean,\n onChange: () => updateHooks(),\n requiresReload: true,\n },\n handleDyingRecoveryRollAllow: {\n name: `${MODULENAME}.SETTINGS.handleDyingRecoveryRollAllow.name`,\n hint: `${MODULENAME}.SETTINGS.handleDyingRecoveryRollAllow.hint`,\n scope: \"world\",\n config: true,\n default: \"none\",\n type: String,\n choices: {\n none: game.i18n.localize(`${MODULENAME}.SETTINGS.handleDyingRecoveryRollAllow.none`),\n all: game.i18n.localize(`${MODULENAME}.SETTINGS.handleDyingRecoveryRollAllow.all`),\n gm: game.i18n.localize(`${MODULENAME}.SETTINGS.handleDyingRecoveryRollAllow.gm`),\n players: game.i18n.localize(`${MODULENAME}.SETTINGS.handleDyingRecoveryRollAllow.players`),\n },\n onChange: () => updateHooks(),\n requiresReload: true,\n },\n autoReduceStunned: {\n name: `${MODULENAME}.SETTINGS.autoReduceStunned.name`,\n hint: `${MODULENAME}.SETTINGS.autoReduceStunned.hint`,\n scope: \"world\",\n config: true,\n default: false,\n type: Boolean,\n onChange: () => updateHooks(),\n requiresReload: true,\n },\n giveUnconsciousIfDyingRemovedAt0HP: {\n name: `${MODULENAME}.SETTINGS.giveUnconsciousIfDyingRemovedAt0HP.name`,\n hint: `${MODULENAME}.SETTINGS.giveUnconsciousIfDyingRemovedAt0HP.hint`,\n scope: \"world\",\n config: true,\n default: false,\n type: Boolean,\n onChange: () => updateHooks(),\n requiresReload: true,\n },\n autoRemoveUnconsciousAtGreaterThanZeroHP: {\n name: `${MODULENAME}.SETTINGS.autoRemoveUnconsciousAtGreaterThanZeroHP.name`,\n hint: `${MODULENAME}.SETTINGS.autoRemoveUnconsciousAtGreaterThanZeroHP.hint`,\n scope: \"world\",\n config: true,\n default: false,\n type: Boolean,\n onChange: () => updateHooks(),\n requiresReload: true,\n },\n giveWoundedWhenDyingRemoved: {\n name: `${MODULENAME}.SETTINGS.giveWoundedWhenDyingRemoved.name`,\n hint: `${MODULENAME}.SETTINGS.giveWoundedWhenDyingRemoved.hint`,\n scope: \"world\",\n config: true,\n default: false,\n type: Boolean,\n onChange: () => updateHooks(),\n requiresReload: true,\n },\n autoGainDyingAtZeroHP: {\n name: `${MODULENAME}.SETTINGS.autoGainDyingAtZeroHP.name`,\n hint: `${MODULENAME}.SETTINGS.autoGainDyingAtZeroHP.hint`,\n scope: \"world\",\n config: true,\n default: \"no\",\n type: String,\n choices: {\n no: game.i18n.localize(`${MODULENAME}.SETTINGS.autoGainDyingAtZeroHP.no`),\n addOne: game.i18n.localize(`${MODULENAME}.SETTINGS.autoGainDyingAtZeroHP.addOne`),\n addWoundedLevel: game.i18n.localize(`${MODULENAME}.SETTINGS.autoGainDyingAtZeroHP.addWoundedLevel`),\n addOneForCharacters: game.i18n.localize(\n `${MODULENAME}.SETTINGS.autoGainDyingAtZeroHP.addOneForCharacters`,\n ),\n addWoundedLevelForCharacters: game.i18n.localize(\n `${MODULENAME}.SETTINGS.autoGainDyingAtZeroHP.addWoundedLevelForCharacters`,\n ),\n },\n onChange: () => updateHooks(),\n requiresReload: true,\n },\n nonLethalIsNotLethal: {\n name: `${MODULENAME}.SETTINGS.nonLethalIsNotLethal.name`,\n hint: `${MODULENAME}.SETTINGS.nonLethalIsNotLethal.hint`,\n scope: \"world\",\n config: true,\n default: \"no\",\n type: String,\n choices: {\n no: game.i18n.localize(`${MODULENAME}.SETTINGS.nonLethalIsNotLethal.no`),\n unconscious: game.i18n.localize(`${MODULENAME}.SETTINGS.nonLethalIsNotLethal.unconscious`),\n unconsciousForCharacters: game.i18n.localize(\n `${MODULENAME}.SETTINGS.nonLethalIsNotLethal.unconsciousForCharacters`,\n ),\n },\n onChange: () => updateHooks(),\n requiresReload: true,\n },\n autoGainDyingAtZeroHPIfCriticallyHitOneMore: {\n name: `${MODULENAME}.SETTINGS.autoGainDyingAtZeroHPIfCriticallyHitOneMore.name`,\n hint: `${MODULENAME}.SETTINGS.autoGainDyingAtZeroHPIfCriticallyHitOneMore.hint`,\n scope: \"world\",\n config: true,\n default: \"no\",\n type: String,\n choices: {\n no: game.i18n.localize(`${MODULENAME}.SETTINGS.autoGainDyingAtZeroHPIfCriticallyHitOneMore.no`),\n add: game.i18n.localize(`${MODULENAME}.SETTINGS.autoGainDyingAtZeroHPIfCriticallyHitOneMore.add`),\n addForCharacters: game.i18n.localize(\n `${MODULENAME}.SETTINGS.autoGainDyingAtZeroHPIfCriticallyHitOneMore.addForCharacters`,\n ),\n },\n },\n autoGainDyingIfTakingDamageWhenAlreadyDying: {\n name: `${MODULENAME}.SETTINGS.autoGainDyingIfTakingDamageWhenAlreadyDying.name`,\n hint: `${MODULENAME}.SETTINGS.autoGainDyingIfTakingDamageWhenAlreadyDying.hint`,\n scope: \"world\",\n config: true,\n default: \"no\",\n type: String,\n choices: {\n no: game.i18n.localize(`${MODULENAME}.SETTINGS.autoGainDyingIfTakingDamageWhenAlreadyDying.no`),\n add: game.i18n.localize(`${MODULENAME}.SETTINGS.autoGainDyingIfTakingDamageWhenAlreadyDying.add`),\n addForCharacters: game.i18n.localize(\n `${MODULENAME}.SETTINGS.autoGainDyingIfTakingDamageWhenAlreadyDying.addForCharacters`,\n ),\n },\n },\n autoGainDyingIgnoresTargeting: {\n name: `${MODULENAME}.SETTINGS.autoGainDyingIgnoresTargeting.name`,\n hint: `${MODULENAME}.SETTINGS.autoGainDyingIgnoresTargeting.hint`,\n scope: \"world\",\n config: true,\n default: false,\n type: Boolean,\n onChange: () => updateHooks(),\n requiresReload: true,\n },\n autoRemoveDyingAtGreaterThanZeroHP: {\n name: `${MODULENAME}.SETTINGS.autoRemoveDyingAtGreaterThanZeroHP.name`,\n hint: `${MODULENAME}.SETTINGS.autoRemoveDyingAtGreaterThanZeroHP.hint`,\n scope: \"world\",\n config: true,\n default: \"no\",\n type: String,\n choices: {\n no: game.i18n.localize(`${MODULENAME}.SETTINGS.autoRemoveDyingAtGreaterThanZeroHP.no`),\n remove: game.i18n.localize(`${MODULENAME}.SETTINGS.autoRemoveDyingAtGreaterThanZeroHP.removeDying`),\n removeForCharacters: game.i18n.localize(\n `${MODULENAME}.SETTINGS.autoRemoveDyingAtGreaterThanZeroHP.removeDyingForCharacters`,\n ),\n },\n onChange: () => updateHooks(),\n requiresReload: true,\n },\n dropHeldItemsOnBecomingUnconscious: {\n name: `${MODULENAME}.SETTINGS.dropHeldItemsOnBecomingUnconscious.name`,\n hint: `${MODULENAME}.SETTINGS.dropHeldItemsOnBecomingUnconscious.hint`,\n scope: \"world\",\n config: true,\n default: false,\n type: Boolean,\n onChange: () => updateHooks(),\n requiresReload: true,\n },\n sheatheHeldItemsAfterEncounter: {\n name: `${MODULENAME}.SETTINGS.sheatheHeldItemsAfterEncounter.name`,\n hint: `${MODULENAME}.SETTINGS.sheatheHeldItemsAfterEncounter.hint`,\n scope: \"world\",\n config: true,\n default: false,\n type: Boolean,\n onChange: () => updateHooks(),\n requiresReload: true,\n },\n sheatheHeldItemsAfterEncounterTypes: {\n name: `${MODULENAME}.SETTINGS.sheatheHeldItemsAfterEncounterTypes.name`,\n hint: `${MODULENAME}.SETTINGS.sheatheHeldItemsAfterEncounterTypes.hint`,\n scope: \"world\",\n config: true,\n default: \"weapon\",\n type: String,\n onChange: () => updateHooks(),\n requiresReload: true,\n },\n };\n }\n}\n","import { updateHooks } from \"../xdy-pf2e-workbench.ts\";\nimport { MODULENAME } from \"../constants.ts\";\nimport { SettingsMenuPF2eWorkbench } from \"./menu.ts\";\nimport { SettingRegistration } from \"foundry/client/helpers/client-settings.mts\";\n\nexport class WorkbenchClientAutomationSettings extends SettingsMenuPF2eWorkbench {\n static override namespace = \"automationClientSettings\";\n\n static override DEFAULT_OPTIONS = fu.mergeObject(super.DEFAULT_OPTIONS, {\n height: \"fit-content\",\n });\n\n public static override get settings(): Record {\n return {\n // NOTE Do NOT rename this without talking to Symon S, his macros for Spellstrike and Eldritch shot parse for workbench and its settings to avoid double rolling damage.\n autoRollDamageForStrike: {\n name: `${MODULENAME}.SETTINGS.autoRollDamageForStrike.name`,\n hint: `${MODULENAME}.SETTINGS.autoRollDamageForStrike.hint`,\n scope: \"client\",\n config: true,\n default: false,\n type: Boolean,\n onChange: () => updateHooks(),\n requiresReload: true,\n },\n autoRollDamageForSpellAttack: {\n name: `${MODULENAME}.SETTINGS.autoRollDamageForSpellAttack.name`,\n hint: `${MODULENAME}.SETTINGS.autoRollDamageForSpellAttack.hint`,\n scope: \"client\",\n config: true,\n default: false,\n type: Boolean,\n onChange: () => updateHooks(),\n requiresReload: true,\n },\n autoRollDamageForSpellWhenNotAnAttack: {\n name: `${MODULENAME}.SETTINGS.autoRollDamageForSpellWhenNotAnAttack.name`,\n hint: `${MODULENAME}.SETTINGS.autoRollDamageForSpellWhenNotAnAttack.hint`,\n scope: \"client\",\n config: true,\n default: false,\n type: String,\n choices: {\n no: game.i18n.localize(`${MODULENAME}.SETTINGS.autoRollDamageForSpellWhenNotAnAttack.no`),\n anySpell: game.i18n.localize(\n `${MODULENAME}.SETTINGS.autoRollDamageForSpellWhenNotAnAttack.anySpell`,\n ),\n saveSpell: game.i18n.localize(\n `${MODULENAME}.SETTINGS.autoRollDamageForSpellWhenNotAnAttack.saveSpell`,\n ),\n nonSaveSpell: game.i18n.localize(\n `${MODULENAME}.SETTINGS.autoRollDamageForSpellWhenNotAnAttack.nonSaveSpell`,\n ),\n },\n onChange: () => updateHooks(),\n requiresReload: true,\n },\n autoRollDamageNotifyOnSpellCardNotFound: {\n name: `${MODULENAME}.SETTINGS.autoRollDamageNotifyOnSpellCardNotFound.name`,\n hint: `${MODULENAME}.SETTINGS.autoRollDamageNotifyOnSpellCardNotFound.hint`,\n scope: \"client\",\n config: true,\n default: true,\n type: Boolean,\n },\n handleDyingRecoveryRoll: {\n name: `${MODULENAME}.SETTINGS.handleDyingRecoveryRoll.name`,\n hint: `${MODULENAME}.SETTINGS.handleDyingRecoveryRoll.hint`,\n scope: \"client\",\n config: true,\n default: false,\n type: Boolean,\n onChange: () => updateHooks(),\n requiresReload: true,\n },\n decreaseFrightenedConditionEachTurn: {\n name: `${MODULENAME}.SETTINGS.decreaseFrightenedConditionEachTurn.name`,\n hint: `${MODULENAME}.SETTINGS.decreaseFrightenedConditionEachTurn.hint`,\n scope: \"client\",\n config: true,\n default: false,\n type: Boolean,\n onChange: () => updateHooks(),\n requiresReload: true,\n },\n };\n }\n}\n","import { updateHooks } from \"../xdy-pf2e-workbench.ts\";\nimport { MODULENAME } from \"../constants.ts\";\nimport { HideListTemplateData, SettingsMenuPF2eWorkbench } from \"./menu.ts\";\nimport { SettingRegistration } from \"foundry/client/helpers/client-settings.mts\";\n\nexport class WorkbenchQolWorldSettings extends SettingsMenuPF2eWorkbench {\n static override namespace = \"qolWorldSettings\";\n static override readonly hidelist: HideListTemplateData = {\n castPrivateSpell: {\n list: [\n \"castPrivateSpellAutoRevealIfKnown\",\n \"castPrivateSpellAutoRevealPartyMembersThatKnowSpell\",\n \"castPrivateSpellAlwaysFor\",\n \"castPrivateSpellAutoRevealOverrideGMRollMode\",\n ],\n },\n castPrivateSpellWithPublicMessage: {\n list: [\"castPrivateSpellWithPublicMessageShowToGM\", \"castPrivateSpellWithPublicMessageShowTraits\"],\n },\n castPrivateSpellWithPublicMessageShowTraits: {\n list: [\"castPrivateSpellWithPublicMessageTraitsBlocklist\"],\n },\n sheatheHeldItemsAfterEncounter: {\n list: [\"sheatheHeldItemsAfterEncounterTypes\"],\n },\n };\n\n public static override get settings(): Record {\n return {\n npcScaler: {\n name: `${MODULENAME}.SETTINGS.npcScaler.name`,\n hint: `${MODULENAME}.SETTINGS.npcScaler.hint`,\n scope: \"world\",\n config: true,\n default: false,\n type: Boolean,\n onChange: () => updateHooks(),\n requiresReload: true,\n },\n npcRoller: {\n name: `${MODULENAME}.SETTINGS.npcRoller.name`,\n hint: `${MODULENAME}.SETTINGS.npcRoller.hint`,\n scope: \"world\",\n config: true,\n default: false,\n type: Boolean,\n onChange: () => updateHooks(),\n requiresReload: true,\n },\n castPrivateSpell: {\n name: `${MODULENAME}.SETTINGS.castPrivateSpell.name`,\n hint: `${MODULENAME}.SETTINGS.castPrivateSpell.hint`,\n scope: \"world\",\n config: true,\n default: false,\n type: Boolean,\n onChange: () => updateHooks(),\n requiresReload: true,\n },\n castPrivateSpellAutoRevealIfKnown: {\n name: `${MODULENAME}.SETTINGS.castPrivateSpellAutoRevealIfKnown.name`,\n hint: `${MODULENAME}.SETTINGS.castPrivateSpellAutoRevealIfKnown.hint`,\n scope: \"world\",\n config: true,\n default: true,\n type: Boolean,\n onChange: () => updateHooks(),\n requiresReload: true,\n },\n castPrivateSpellAutoRevealOverrideGMRollMode: {\n name: `${MODULENAME}.SETTINGS.castPrivateSpellAutoRevealOverrideGMRollMode.name`,\n hint: `${MODULENAME}.SETTINGS.castPrivateSpellAutoRevealOverrideGMRollMode.hint`,\n scope: \"world\",\n config: true,\n default: false,\n type: Boolean,\n onChange: () => updateHooks(),\n requiresReload: true,\n },\n castPrivateSpellAutoRevealPartyMembersThatKnowSpell: {\n name: `${MODULENAME}.SETTINGS.castPrivateSpellAutoRevealPartyMembersThatKnowSpell.name`,\n hint: `${MODULENAME}.SETTINGS.castPrivateSpellAutoRevealPartyMembersThatKnowSpell.hint`,\n scope: \"world\",\n config: true,\n default: false,\n type: Boolean,\n onChange: () => updateHooks(),\n requiresReload: true,\n },\n castPrivateSpellAlwaysFor: {\n name: `${MODULENAME}.SETTINGS.castPrivateSpellAlwaysFor.name`,\n hint: `${MODULENAME}.SETTINGS.castPrivateSpellAlwaysFor.hint`,\n scope: \"world\",\n config: true,\n default: \"none\",\n type: String,\n choices: {\n none: game.i18n.localize(`${MODULENAME}.SETTINGS.castPrivateSpellAlwaysFor.none`),\n nonAllies: game.i18n.localize(`${MODULENAME}.SETTINGS.castPrivateSpellAlwaysFor.nonAllies`),\n nonPartymembers: game.i18n.localize(\n `${MODULENAME}.SETTINGS.castPrivateSpellAlwaysFor.nonPartymembers`,\n ),\n npcs: game.i18n.localize(`${MODULENAME}.SETTINGS.castPrivateSpellAlwaysFor.npcs`),\n },\n onChange: () => updateHooks(),\n requiresReload: true,\n },\n castPrivateSpellWithPublicMessage: {\n name: `${MODULENAME}.SETTINGS.castPrivateSpellWithPublicMessage.name`,\n hint: `${MODULENAME}.SETTINGS.castPrivateSpellWithPublicMessage.hint`,\n scope: \"world\",\n config: true,\n default: false,\n type: Boolean,\n onChange: () => updateHooks(),\n requiresReload: true,\n },\n castPrivateSpellWithPublicMessageShowToGM: {\n name: `${MODULENAME}.SETTINGS.castPrivateSpellWithPublicMessageShowToGM.name`,\n hint: `${MODULENAME}.SETTINGS.castPrivateSpellWithPublicMessageShowToGM.hint`,\n scope: \"world\",\n config: true,\n default: false,\n type: Boolean,\n onChange: () => updateHooks(),\n requiresReload: true,\n },\n castPrivateSpellWithPublicMessageShowTraits: {\n name: `${MODULENAME}.SETTINGS.castPrivateSpellWithPublicMessageShowTraits.name`,\n hint: `${MODULENAME}.SETTINGS.castPrivateSpellWithPublicMessageShowTraits.hint`,\n scope: \"world\",\n config: true,\n default: false,\n type: Boolean,\n onChange: () => updateHooks(),\n requiresReload: true,\n },\n castPrivateSpellWithPublicMessageTraitsBlocklist: {\n name: `${MODULENAME}.SETTINGS.castPrivateSpellWithPublicMessageTraitsBlocklist.name`,\n hint: `${MODULENAME}.SETTINGS.castPrivateSpellWithPublicMessageTraitsBlocklist.hint`,\n scope: \"world\",\n config: true,\n default: \"\",\n type: String,\n onChange: () => updateHooks(),\n requiresReload: true,\n },\n playerFeatsPrerequisiteHint: {\n name: `${MODULENAME}.SETTINGS.playerFeatsPrerequisiteHint.name`,\n hint: `${MODULENAME}.SETTINGS.playerFeatsPrerequisiteHint.hint`,\n scope: \"world\",\n config: true,\n default: false,\n type: Boolean,\n onChange: () => updateHooks(),\n },\n playerFeatsRarityColour: {\n name: `${MODULENAME}.SETTINGS.playerFeatsRarityColour.name`,\n hint: `${MODULENAME}.SETTINGS.playerFeatsRarityColour.hint`,\n scope: \"world\",\n config: true,\n default: false,\n type: Boolean,\n onChange: () => updateHooks(),\n },\n playerAbcdRarityColour: {\n name: `${MODULENAME}.SETTINGS.playerAbcdRarityColour.name`,\n hint: `${MODULENAME}.SETTINGS.playerAbcdRarityColour.hint`,\n scope: \"world\",\n config: true,\n default: false,\n type: Boolean,\n onChange: () => updateHooks(),\n },\n playerCraftingRarityColour: {\n name: `${MODULENAME}.SETTINGS.playerCraftingRarityColour.name`,\n hint: `${MODULENAME}.SETTINGS.playerCraftingRarityColour.hint`,\n scope: \"world\",\n config: true,\n default: false,\n type: Boolean,\n onChange: () => updateHooks(),\n },\n playerSpellsRarityColour: {\n name: `${MODULENAME}.SETTINGS.playerSpellsRarityColour.name`,\n hint: `${MODULENAME}.SETTINGS.playerSpellsRarityColour.hint`,\n scope: \"world\",\n config: true,\n default: false,\n type: Boolean,\n onChange: () => updateHooks(),\n },\n playerSpellsChangeSendToChat: {\n name: `${MODULENAME}.SETTINGS.playerSpellsChangeSendToChat.name`,\n hint: `${MODULENAME}.SETTINGS.playerSpellsChangeSendToChat.hint`,\n scope: \"world\",\n config: true,\n default: false,\n type: Boolean,\n onChange: () => updateHooks(),\n },\n showItemLicenseTags: {\n name: `${MODULENAME}.SETTINGS.showItemLicenseTags.name`,\n hint: `${MODULENAME}.SETTINGS.showItemLicenseTags.hint`,\n scope: \"world\",\n config: true,\n default: false,\n type: Boolean,\n onChange: () => updateHooks(),\n },\n showCharacterOglTag: {\n name: `${MODULENAME}.SETTINGS.showCharacterOglTag.name`,\n hint: `${MODULENAME}.SETTINGS.showCharacterOglTag.hint`,\n scope: \"world\",\n config: true,\n default: false,\n type: Boolean,\n onChange: () => updateHooks(),\n },\n enableGeneralLearnSpell: {\n name: `${MODULENAME}.SETTINGS.enableGeneralLearnSpell.name`,\n hint: `${MODULENAME}.SETTINGS.enableGeneralLearnSpell.hint`,\n scope: \"world\",\n config: true,\n default: false,\n type: Boolean,\n onChange: () => updateHooks(),\n },\n learnSpellDcAdjustment: {\n name: `${MODULENAME}.SETTINGS.learnSpellDcAdjustment.name`,\n hint: `${MODULENAME}.SETTINGS.learnSpellDcAdjustment.hint`,\n scope: \"world\",\n config: true,\n default: 0,\n type: Number,\n },\n learnSpellDestroyScroll: {\n name: `${MODULENAME}.SETTINGS.learnSpellDestroyScroll.name`,\n hint: `${MODULENAME}.SETTINGS.learnSpellDestroyScroll.hint`,\n scope: \"world\",\n config: true,\n default: false,\n type: Boolean,\n onChange: () => updateHooks(),\n },\n allowDebtItems: {\n name: `${MODULENAME}.SETTINGS.allowDebtItems.name`,\n hint: `${MODULENAME}.SETTINGS.allowDebtItems.hint`,\n scope: \"world\",\n config: true,\n default: true,\n type: Boolean,\n },\n };\n }\n}\n","import { updateHooks } from \"../xdy-pf2e-workbench.ts\";\nimport { MODULENAME } from \"../constants.ts\";\nimport { SettingsMenuPF2eWorkbench } from \"./menu.ts\";\nimport { SettingRegistration } from \"foundry/client/helpers/client-settings.mts\";\n\nexport class WorkbenchHouseRulesSettings extends SettingsMenuPF2eWorkbench {\n static override namespace = \"houseRulesSettings\";\n\n static override DEFAULT_OPTIONS = fu.mergeObject(super.DEFAULT_OPTIONS, {\n height: \"fit-content\",\n });\n\n public static override get settings(): Record {\n return {\n heroPointRules: {\n name: `${MODULENAME}.SETTINGS.heroPointRules.name`,\n hint: `${MODULENAME}.SETTINGS.heroPointRules.hint`,\n scope: \"world\",\n default: \"no\",\n type: String,\n choices: {\n no: game.i18n.localize(`${MODULENAME}.SETTINGS.heroPointRules.no`),\n keeleysHeroPointRule: game.i18n.localize(\n `${MODULENAME}.SETTINGS.heroPointRules.keeleysHeroPointRule`,\n ),\n useHighestHeroPointRoll: game.i18n.localize(\n `${MODULENAME}.SETTINGS.heroPointRules.useHighestHeroPointRoll`,\n ),\n heroicRerolls: game.i18n.localize(`${MODULENAME}.SETTINGS.heroPointRules.heroicRerolls`),\n },\n onChange: () => updateHooks(),\n requiresReload: true,\n },\n legacyVariantRuleAncestryParagon: {\n name: `${MODULENAME}.SETTINGS.legacyVariantRuleAncestryParagon.name`,\n hint: `${MODULENAME}.SETTINGS.legacyVariantRuleAncestryParagon.hint`,\n scope: \"world\",\n config: true,\n default: false,\n type: Boolean,\n onChange: () => {\n game.settings.set(\n \"pf2e\",\n \"campaignFeatSections\",\n game.settings\n .get(\"pf2e\", \"campaignFeatSections\")\n .filter((section) => section.id !== \"xdy_ancestryparagon\"),\n );\n updateHooks();\n },\n },\n legacyVariantRuleDualClass: {\n name: `${MODULENAME}.SETTINGS.legacyVariantRuleDualClass.name`,\n hint: `${MODULENAME}.SETTINGS.legacyVariantRuleDualClass.hint`,\n scope: \"world\",\n config: true,\n default: false,\n type: Boolean,\n onChange: () => {\n game.settings.set(\n \"pf2e\",\n \"campaignFeatSections\",\n game.settings\n .get(\"pf2e\", \"campaignFeatSections\")\n .filter((section) => section.id !== \"xdy_dualclass\"),\n );\n updateHooks();\n },\n },\n housepatcher: {\n name: `${MODULENAME}.SETTINGS.housepatcher.name`,\n hint: `${MODULENAME}.SETTINGS.housepatcher.hint`,\n scope: \"world\",\n config: true,\n default: \"\",\n type: String,\n },\n };\n }\n}\n","import { updateHooks } from \"../xdy-pf2e-workbench.ts\";\nimport { MODULENAME } from \"../constants.ts\";\nimport { SettingsMenuPF2eWorkbench } from \"./menu.ts\";\nimport { SettingRegistration } from \"foundry/client/helpers/client-settings.mts\";\n\nexport class WorkbenchCanvasFeaturesSettings extends SettingsMenuPF2eWorkbench {\n static override namespace = \"canvasFeaturesSettings\";\n\n public static override get settings(): Record {\n return {\n canvasPointer: {\n name: `${MODULENAME}.SETTINGS.canvasPointer.name`,\n hint: `${MODULENAME}.SETTINGS.canvasPointer.hint`,\n scope: \"world\",\n config: true,\n default: false,\n type: Boolean,\n },\n canvasPointerIcon: {\n name: `${MODULENAME}.SETTINGS.canvasPointerIcon.name`,\n hint: `${MODULENAME}.SETTINGS.canvasPointerIcon.hint`,\n scope: \"world\",\n config: true,\n default: \"fa-regular fa-hand-point-down\",\n type: String,\n },\n canvasPointerBroadcastInterval: {\n name: `${MODULENAME}.SETTINGS.canvasPointerBroadcastInterval.name`,\n hint: `${MODULENAME}.SETTINGS.canvasPointerBroadcastInterval.hint`,\n scope: \"world\",\n config: true,\n default: 10,\n type: Number,\n // @ts-expect-error TODO Fix typing\n range: { min: 1, max: 1000, step: 1 },\n },\n canvasPointerPingMode: {\n name: `${MODULENAME}.SETTINGS.canvasPointerPingMode.name`,\n hint: `${MODULENAME}.SETTINGS.canvasPointerPingMode.hint`,\n scope: \"world\",\n config: true,\n default: \"none\",\n type: String,\n choices: {\n none: game.i18n.localize(`${MODULENAME}.SETTINGS.canvasPointerPingMode.none`),\n visual: game.i18n.localize(`${MODULENAME}.SETTINGS.canvasPointerPingMode.visual`),\n sound: game.i18n.localize(`${MODULENAME}.SETTINGS.canvasPointerPingMode.sound`),\n visualAndSound: game.i18n.localize(`${MODULENAME}.SETTINGS.canvasPointerPingMode.visualAndSound`),\n },\n },\n canvasPointerPingSound: {\n name: `${MODULENAME}.SETTINGS.canvasPointerPingSound.name`,\n hint: `${MODULENAME}.SETTINGS.canvasPointerPingSound.hint`,\n scope: \"world\",\n config: true,\n default: \"\",\n type: String,\n // @ts-expect-error - filePicker property not yet in foundry-pf2e types\n filePicker: \"audio\",\n },\n canvasPointerPingVolume: {\n name: `${MODULENAME}.SETTINGS.canvasPointerPingVolume.name`,\n hint: `${MODULENAME}.SETTINGS.canvasPointerPingVolume.hint`,\n scope: \"client\",\n config: true,\n default: 0.2,\n type: Number,\n // @ts-expect-error TODO Fix typing\n range: { min: 0, max: 1, step: 0.1 },\n },\n tokenAnimation: {\n name: `${MODULENAME}.SETTINGS.tokenAnimation.name`,\n hint: `${MODULENAME}.SETTINGS.tokenAnimation.hint`,\n scope: \"world\",\n config: true,\n default: false,\n type: Boolean,\n onChange: () => updateHooks(),\n requiresReload: true,\n },\n tokenAnimationSpeed: {\n name: `${MODULENAME}.SETTINGS.tokenAnimationSpeed.name`,\n hint: `${MODULENAME}.SETTINGS.tokenAnimationSpeed.hint`,\n scope: \"world\",\n config: true,\n default: 6,\n type: Number,\n onChange: () => updateHooks(),\n requiresReload: true,\n },\n customPauseImage: {\n name: `${MODULENAME}.SETTINGS.customPauseImage.name`,\n hint: `${MODULENAME}.SETTINGS.customPauseImage.hint`,\n scope: \"world\",\n config: true,\n default: \"\",\n type: String,\n // @ts-expect-error - filePicker property not yet in foundry-pf2e types\n filePicker: \"imagevideo\",\n onChange: () => updateHooks(),\n },\n customPauseText: {\n name: `${MODULENAME}.SETTINGS.customPauseText.name`,\n hint: `${MODULENAME}.SETTINGS.customPauseText.hint`,\n scope: \"world\",\n config: true,\n default: \"\",\n type: String,\n onChange: () => updateHooks(),\n },\n pauseImageNoSpin: {\n name: `${MODULENAME}.SETTINGS.pauseImageNoSpin.name`,\n hint: `${MODULENAME}.SETTINGS.pauseImageNoSpin.hint`,\n scope: \"world\",\n config: true,\n default: false,\n type: Boolean,\n onChange: () => updateHooks(),\n },\n };\n }\n}\n","import { updateHooks } from \"../xdy-pf2e-workbench.ts\";\nimport { MODULENAME } from \"../constants.ts\";\nimport { WorkbenchNpcMystificationSettings } from \"./npc-mystification.ts\";\nimport { WorkbenchItemMystificationSettings } from \"./item-mystification.ts\";\nimport { WorkbenchRemindersSettings } from \"./reminders.ts\";\nimport { WorkbenchWorldAutomationSettings } from \"./automation-world.ts\";\nimport { WorkbenchClientAutomationSettings } from \"./automation-client.ts\";\nimport { WorkbenchQolWorldSettings } from \"./qol-world.ts\";\nimport { logInfo } from \"../utils/logging.ts\";\nimport { WorkbenchHouseRulesSettings } from \"./houseRules.ts\";\nimport { WorkbenchCanvasFeaturesSettings } from \"./canvas-features.ts\";\n\nfunction collapseChoices(settingKey: string): Record {\n return {\n noCollapse: game.i18n.localize(`${MODULENAME}.SETTINGS.${settingKey}.noCollapse`),\n collapsedDefault: game.i18n.localize(`${MODULENAME}.SETTINGS.${settingKey}.collapsedDefault`),\n nonCollapsedDefault: game.i18n.localize(`${MODULENAME}.SETTINGS.${settingKey}.nonCollapsedDefault`),\n };\n}\n\nexport function registerWorkbenchSettings(): void {\n logInfo(`${MODULENAME} | registerSettings`);\n\n WorkbenchNpcMystificationSettings.registerSettingsAndCreateMenu(\"fa-solid fa-eye-slash\");\n WorkbenchItemMystificationSettings.registerSettingsAndCreateMenu(\"fa-solid fa-mask\");\n WorkbenchRemindersSettings.registerSettingsAndCreateMenu(\"fa-solid fa-bell\");\n WorkbenchQolWorldSettings.registerSettingsAndCreateMenu(\"fa-solid fa-smile\");\n WorkbenchWorldAutomationSettings.registerSettingsAndCreateMenu(\"fa-solid fa-robot\");\n WorkbenchClientAutomationSettings.registerSettingsAndCreateMenu(\"fa-solid fa-magic\", false);\n WorkbenchHouseRulesSettings.registerSettingsAndCreateMenu(\"fa-solid fa-house\");\n WorkbenchCanvasFeaturesSettings.registerSettingsAndCreateMenu(\"fa-solid fa-compass\");\n\n for (const key of [\n \"autoCollapseItemChatCardContent\",\n \"autoCollapseItemActionChatCardContent\",\n \"autoCollapseItemAttackChatCardContent\",\n ] as const) {\n game.settings.register(MODULENAME, key, {\n name: `${MODULENAME}.SETTINGS.${key}.name`,\n hint: `${MODULENAME}.SETTINGS.${key}.hint`,\n scope: \"client\",\n config: true,\n default: \"noCollapse\",\n type: String,\n choices: collapseChoices(key),\n onChange: () => updateHooks(),\n });\n }\n\n game.settings.register(MODULENAME, \"autoCollapseItemChatCardMoveEffectLinks\", {\n name: `${MODULENAME}.SETTINGS.autoCollapseItemChatCardMoveEffectLinks.name`,\n hint: `${MODULENAME}.SETTINGS.autoCollapseItemChatCardMoveEffectLinks.hint`,\n scope: \"client\",\n config: true,\n default: false,\n type: Boolean,\n onChange: () => updateHooks(),\n });\n\n game.settings.register(MODULENAME, \"autoExpandDamageRolls\", {\n name: `${MODULENAME}.SETTINGS.autoExpandDamageRolls.name`,\n hint: `${MODULENAME}.SETTINGS.autoExpandDamageRolls.hint`,\n scope: \"client\",\n config: true,\n default: \"collapsedDefault\",\n type: String,\n choices: {\n collapsedAll: game.i18n.localize(`${MODULENAME}.SETTINGS.autoExpandDamageRolls.collapsedAll`),\n expandedAll: game.i18n.localize(`${MODULENAME}.SETTINGS.autoExpandDamageRolls.expandedAll`),\n expandedNew: game.i18n.localize(`${MODULENAME}.SETTINGS.autoExpandDamageRolls.expandedNew`),\n expandedNewest: game.i18n.localize(`${MODULENAME}.SETTINGS.autoExpandDamageRolls.expandedNewest`),\n },\n onChange: () => updateHooks(),\n });\n\n game.settings.register(MODULENAME, \"basicActionMacroShowBestBonus\", {\n name: `${MODULENAME}.macros.basicActionMacros.settings.showBestBonus.name`,\n hint: `${MODULENAME}.macros.basicActionMacros.settings.showBestBonus.hint`,\n scope: \"world\",\n config: true,\n default: true,\n type: Boolean,\n });\n\n game.settings.register(MODULENAME, \"bamShowUnusable\", {\n name: `${MODULENAME}.macros.basicActionMacros.bamShowUnusable.name`,\n hint: `${MODULENAME}.macros.basicActionMacros.bamShowUnusable.hint`,\n scope: \"client\",\n config: true,\n default: false,\n type: Boolean,\n onChange: () => updateHooks(),\n });\n\n game.settings.register(MODULENAME, \"bamTabview\", {\n name: `${MODULENAME}.macros.basicActionMacros.bamTabview.name`,\n hint: `${MODULENAME}.macros.basicActionMacros.bamTabview.hint`,\n scope: \"client\",\n config: true,\n default: true,\n type: Boolean,\n onChange: () => updateHooks(),\n });\n\n game.settings.register(MODULENAME, \"rkBreakdown\", {\n name: `${MODULENAME}.macros.recallKnowledge.breakdown.name`,\n hint: `${MODULENAME}.macros.recallKnowledge.breakdown.hint`,\n scope: \"world\",\n config: true,\n default: \"all\",\n type: String,\n choices: {\n all: game.i18n.localize(`${MODULENAME}.macros.recallKnowledge.breakdown.all`),\n extra: game.i18n.localize(`${MODULENAME}.macros.recallKnowledge.breakdown.extra`),\n none: game.i18n.localize(`${MODULENAME}.macros.recallKnowledge.breakdown.none`),\n },\n });\n\n game.settings.register(MODULENAME, \"logLevel\", {\n name: `${MODULENAME}.SETTINGS.logLevel.name`,\n hint: `${MODULENAME}.SETTINGS.logLevel.hint`,\n scope: \"client\",\n config: true,\n default: 2,\n type: Number,\n choices: {\n 0: game.i18n.localize(`${MODULENAME}.SETTINGS.logLevel.trace`),\n 1: game.i18n.localize(`${MODULENAME}.SETTINGS.logLevel.debug`),\n 2: game.i18n.localize(`${MODULENAME}.SETTINGS.logLevel.info`),\n 3: game.i18n.localize(`${MODULENAME}.SETTINGS.logLevel.warn`),\n 4: game.i18n.localize(`${MODULENAME}.SETTINGS.logLevel.error`),\n 5: game.i18n.localize(`${MODULENAME}.SETTINGS.logLevel.off`),\n },\n onChange: () => updateHooks(),\n });\n\n game.settings.register(MODULENAME, \"workbenchVersion\", {\n name: `${MODULENAME}.SETTINGS.workbenchVersion.name`,\n hint: `${MODULENAME}.SETTINGS.workbenchVersion.hint`,\n scope: \"world\",\n config: true,\n default: \"3.34.0\",\n type: String,\n onChange: () => updateHooks(),\n });\n}\n","// types: [all, action, bestiary, campaignFeature, equipment, feat, hazard, spell] (compendium browser divisions + 'all')\n// if you need to find effects like this, too bad I guess\n// fields: document fields required to index for provided filter\n// filter: a function that takes one argument, returns bool, for .filter()\n// strictSourcing: if true, will suppress documents with missing source information, if false they're let through\n// fetch: if true, return full documents instead of the filtered index\n\nimport type { CompendiumIndexData } from \"foundry/client/documents/collections/compendium-collection.mjs\";\n\ninterface PackInfo {\n load: boolean;\n name: string;\n}\n\ninterface SourceInfo {\n load: boolean;\n name: string;\n}\n\ntype BrowserSettings = Record>;\n\ninterface GetAllFromAllowedPacksParams {\n type?: string;\n fields?: string[];\n filter?: ((d: CompendiumIndexData) => boolean) | null;\n strictSourcing?: boolean;\n fetch?: boolean;\n}\n\n/**\n * Retrieves all items from allowed packs based on the provided parameters.\n *\n * @param {GetAllFromAllowedPacksParams} [params] - Optional parameters to customize the retrieval.\n * @param {string} [params.type=\"equipment\"] - The type of items to retrieve.\n * @param {string[]} [params.fields=[]] - The fields to include in the retrieved items.\n * @param {Function} [params.filter=null] - A filter function to apply to the retrieved items.\n * @param {boolean} [params.strictSourcing=true] - Whether to apply strict sourcing rules.\n * @param {boolean} [params.fetch=false] - Whether to fetch the full documents of the retrieved items.\n * @return {any[]} - An array of the retrieved items.\n */\nexport async function getAllFromAllowedPacks({\n type = \"equipment\",\n fields = [],\n filter = null,\n strictSourcing = true,\n fetch = false,\n}: GetAllFromAllowedPacksParams = {}): Promise {\n const FUNC = \"getAllFromAllowedPacks\";\n const browser = game.pf2e.compendiumBrowser;\n const validTypes = Object.keys(browser.settings);\n validTypes.push(\"all\");\n const aliases: Record = {\n actor: \"bestiary\",\n npc: \"bestiary\",\n ability: \"action\",\n };\n\n const originalType = type;\n if (!validTypes.includes(type) && !validTypes.includes((type = aliases[type] ?? \"\"))) {\n ui.notifications.error(`${FUNC}: invalid type ${originalType}`);\n return null;\n }\n if (!Array.isArray(fields) || (fields.length && fields.some(() => false))) {\n ui.notifications.error(`${FUNC}: fields must be an array of only strings`);\n return null;\n }\n if (filter && typeof filter !== \"function\") {\n ui.notifications.error(`${FUNC}: provided filter must be a function`);\n return null;\n }\n\n // initialize the sources list if it hasn't been set\n if (!Object.keys(browser.packLoader.sourcesSettings.sources).length) {\n await browser.packLoader.updateSources(browser.loadedPacksAll());\n }\n const packList: [string, PackInfo][] =\n type === \"all\"\n ? Object.values(browser.settings).flatMap((t: Record) =>\n Object.entries(t).filter((entry): entry is [string, PackInfo] => entry[1] !== undefined),\n )\n : Object.entries((browser.settings as BrowserSettings)[type] ?? {}).filter(\n (entry): entry is [string, PackInfo] => entry[1] !== undefined,\n );\n\n const loadablePacks = packList.filter(([, p]) => p.load).map(([pack]) => pack);\n // const unloadablePacks = packList.filter(([_, p]) => !p.load).map(([pack]) => pack);\n const sources = browser.packLoader.sourcesSettings.sources;\n const values = Object.values(sources);\n const loadableSources = values\n .filter((s): s is SourceInfo => s !== undefined && s.load)\n .map((s) =>\n s.name.slugify({\n strict: true,\n }),\n );\n fields.push(\"system.details.publication\", \"system.publication\", \"system.source\", \"system.details.source\");\n\n const out: CompendiumIndexData[] = [];\n const sourceFilter = (d: CompendiumIndexData) => {\n const slug = (\n d?.system?.details?.publication?.title ??\n d?.system?.publication?.title ??\n d?.system?.details?.source?.value ??\n d?.system?.source?.value ??\n \"\"\n ).slugify({\n strict: true,\n });\n if (!slug) return !strictSourcing;\n return loadableSources.includes(slug);\n };\n\n for (const packName of loadablePacks) {\n const pack = game.packs.get(packName);\n const initialDocs = await pack?.getIndex({\n fields,\n });\n const sourcedDocs = initialDocs?.filter(sourceFilter);\n let filteredDocs: CompendiumIndexData[] | undefined;\n try {\n filteredDocs = filter ? sourcedDocs?.filter(filter) : sourcedDocs;\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n ui.notifications.error(`Error in provided filter: ${message}`);\n return null;\n }\n\n if (fetch) {\n const documents = await pack?.getDocuments({\n _id__in: filteredDocs?.map((d) => d._id),\n });\n out.push(...((documents ?? []) as CompendiumIndexData[]));\n } else {\n out.push(...(filteredDocs ?? []));\n }\n }\n return out;\n}\n","import { ActorPF2e } from \"foundry-pf2e\";\nimport { MODULENAME } from \"../../constants.ts\";\n\nasync function increaseFocusPoints(actor: ActorPF2e, value: number) {\n const focus = (actor.system as Record)[\"resources\"].focus;\n const current = focus.value;\n const result = Math.min(current + value, focus.max);\n await actor.update({ \"system.resources.focus.value\": result });\n await ChatMessage.create({\n style: CONST.CHAT_MESSAGE_STYLES.EMOTE,\n speaker: ChatMessage.getSpeaker(actor),\n flavor: `\"Passive\"Refocus`,\n content: game.i18n.format(`${MODULENAME}.macros.refocus.regains`, { focus: result - current }),\n });\n}\n\n/**\n * Executes the \"refocus\" action.\n *\n * @return {Promise} - A promise that resolves when the action is complete.\n */\nexport async function refocus(actors: any = canvas.tokens.controlled.map((token) => token.actor) ?? []): Promise {\n if (actors.length === 1) {\n const actor = canvas.tokens.controlled[0].actor;\n let regain = 1;\n if (actor) {\n // @ts-expect-error iterable in pf2e, but not typed to allow map\n const feats = actor.feats?.map((x) => x.feats).flat();\n if (\n feats?.find((i: any) => {\n return [\n \"bloodline-focus\",\n \"bonded-focus\",\n \"conflux-focus\",\n \"devoted-focus\",\n \"domain-focus\",\n \"hex-focus\",\n \"inspirational-focus\",\n \"link-focus\",\n \"meditative-focus\",\n \"primal-focus\",\n \"wardens-focus\",\n ].includes(i.feat?.system?.slug);\n })\n ) {\n regain = (actor.system as Record)[\"resources\"].focus.max;\n }\n increaseFocusPoints(actor, regain);\n }\n } else {\n ui.notifications.warn(game.i18n.localize(`${MODULENAME}.macros.refocus.selectOneActor`));\n }\n}\n\n// refocus();\n","// Basic support for the Hypercognition and Incredible Recollection feats as well as the Hypercognition spell.\n// This macro runs Recall Knowledge multiple times and analyzes the results\n\nimport { TokenPF2e } from \"foundry-pf2e\";\nimport { logWarn } from \"../../utils/logging.ts\";\n\nexport async function hypercognition(token: TokenPF2e) {\n // Verify we have a target and get the actor\n if (game.user.targets.size !== 1) {\n ui.notifications.error(\"Please select exactly one target\");\n return;\n }\n\n const actor = token?.actor;\n if (!actor) {\n ui.notifications.error(\"No actor found\");\n return;\n }\n\n const hasHypercognition = actor.itemTypes.spell.find((spell) => [\"hypercognition\"].includes(spell.slug));\n const hasTrueHypercognition = actor.itemTypes.feat.find((feat) =>\n [\"true-hypercognition\"].includes(feat.slug),\n );\n const hasIncredibleRecollection = actor.itemTypes.feat.find((feat) =>\n [\"incredible-recollection\"].includes(feat.slug),\n );\n if (!hasHypercognition && !hasTrueHypercognition && !hasIncredibleRecollection) {\n ui.notifications.error(\n \"Selected actor has neither Hypercognition, Incredible Recollection nor True Hypercognition!\",\n );\n return;\n }\n\n const results: {\n criticalSuccess: { count: number; rolls: any[] };\n success: { count: number; rolls: any[] };\n failure: { count: number; rolls: any[] };\n criticalFailure: { count: number; rolls: any[] };\n } = {\n criticalSuccess: { count: 0, rolls: [] },\n success: { count: 0, rolls: [] },\n failure: { count: 0, rolls: [] },\n criticalFailure: { count: 0, rolls: [] },\n };\n\n // Find the Recall Knowledge macro\n const recallKnowledgeMacro = game.macros.find((m) => m.name === \"Recall_Knowledge\");\n if (!recallKnowledgeMacro) {\n ui.notifications.error(\"Could not find the Recall_Knowledge macro\");\n return;\n }\n\n // Get skill information before running the checks\n const SKILL_OPTIONS = [\"arcana\", \"crafting\", \"medicine\", \"nature\", \"occultism\", \"religion\", \"society\"];\n const skillInfo = SKILL_OPTIONS.map((skillId) => {\n const skill = actor.skills?.[skillId];\n return {\n name: skill?.label,\n rank: skill?.rank,\n modifier: (skill as Record)?.[\"totalModifier\"],\n wasUsed: false,\n actualModifier: 0,\n };\n });\n\n // Get lore skill information\n // @ts-expect-error actor.skills index signature not typed to allow arbitrary lore skill keys\n const loreInfo: any = Object.values(actor.skills)\n .filter((s: any) => s.lore)\n .map((skill: any) => ({\n name: skill.label,\n rank: skill.rank,\n modifier: skill.totalModifier,\n wasUsed: false,\n actualModifier: null,\n }));\n\n // Run Recall Knowledge several times\n const numberOfUses = hasHypercognition ? 6 : 5;\n for (let i = 0; i < numberOfUses; i++) {\n // Run the Recall Knowledge macro\n await recallKnowledgeMacro.execute();\n\n // Wait for the new message to appear\n await new Promise((resolve) => setTimeout(resolve, 100));\n\n // Get the latest message\n const messages = game.messages?.contents;\n if (!messages?.length) continue;\n\n const latestMessage = messages[messages.length - 1];\n if (!latestMessage?.content) continue;\n\n // Create a temporary div to parse the HTML content\n const tempDiv = document.createElement(\"div\");\n tempDiv.innerHTML = latestMessage.content;\n\n // Find all tables\n const tables = tempDiv.querySelectorAll(\"table\");\n if (tables.length === 0) continue;\n\n // Get the d20 roll from the header once for this message\n const rollMatch = tempDiv.innerHTML.match(/Roll: ]*>(\\d+)<\\/span>/);\n const d20Roll = rollMatch ? parseInt(rollMatch[1]) : null;\n\n // Process primary skills (first table)\n const primaryTable = tables[0];\n const primaryRows = primaryTable.querySelectorAll(\"tr\");\n\n // Track the best result for this roll\n let bestResult: string | undefined;\n\n primaryRows.forEach((row) => {\n const cells = row.querySelectorAll(\"td, th\");\n if (cells.length >= 3) {\n const skillName = cells[0].textContent?.trim();\n\n // For primary skills, look for the roll result (which includes the modifier)\n const rollResult = cells[2]?.querySelector(\"span\")?.textContent;\n const rollNumber = rollResult ? parseInt(rollResult) : null;\n\n // Calculate modifier if we have both numbers\n const calculatedMod = rollNumber !== null && d20Roll !== null ? rollNumber - d20Roll : null;\n\n // Update skillInfo if this is a primary skill\n const primarySkill = skillInfo.find((s) => s.name === skillName);\n if (primarySkill) {\n primarySkill.wasUsed = true;\n if (calculatedMod !== null) {\n primarySkill.actualModifier = calculatedMod;\n }\n }\n\n // Check for degree of success in this row\n const rowText = row.textContent;\n const successMatch = rowText?.match(/(CrSuc|Suc|Fail|CrFail)/);\n if (successMatch) {\n const result = successMatch[1];\n // Update bestResult if this is better than current best\n if (\n !bestResult ||\n result === \"CrSuc\" ||\n (result === \"Suc\" && bestResult !== \"CrSuc\") ||\n (result === \"Fail\" && bestResult === \"CrFail\")\n ) {\n bestResult = result;\n }\n }\n }\n });\n\n // Process lore skills (last table)\n const loreTable = tables[tables.length - 2]; // Second to last table (last one is potential modifiers)\n if (loreTable) {\n const loreRows = loreTable.querySelectorAll(\"tr\");\n loreRows.forEach((row) => {\n const cells = row.querySelectorAll(\"td, th\");\n if (cells.length >= 3) {\n const skillName = cells[0].textContent?.trim();\n // For lore skills, the modifier is explicitly shown in the Mod column\n const modText = cells[2]?.textContent?.trim();\n const modMatch = modText?.match(/[+-]\\d+/);\n\n // Update loreInfo if this is a lore skill\n const loreSkill = loreInfo.find((s: any) => s.name === skillName);\n if (loreSkill && modMatch) {\n loreSkill.wasUsed = true;\n loreSkill.actualModifier = parseInt(modMatch[0]);\n }\n }\n });\n }\n\n // Count only the best result for this roll and store the d20 value\n if (bestResult && d20Roll !== null) {\n switch (bestResult) {\n case \"CrSuc\":\n results.criticalSuccess.count++;\n results.criticalSuccess.rolls.push(d20Roll);\n break;\n case \"Suc\":\n results.success.count++;\n results.success.rolls.push(d20Roll);\n break;\n case \"Fail\":\n results.failure.count++;\n results.failure.rolls.push(d20Roll);\n break;\n case \"CrFail\":\n results.criticalFailure.count++;\n results.criticalFailure.rolls.push(d20Roll);\n break;\n }\n }\n\n // Delete the message\n try {\n await latestMessage.delete();\n } catch (error) {\n logWarn(\"Could not delete message:\", error);\n }\n }\n\n // Create a summary message with skill information\n const RANK_NAMES = [\"UNTRAINED\", \"TRAINED\", \"EXPERT\", \"MASTER\", \"LEGENDARY\"];\n const RANK_COLORS = [\"#443730\", \"#171f69\", \"#3c005e\", \"#5e4000\", \"#5e0000\"];\n const DOS_COLORS = [\"red\", \"orange\", \"royalblue\", \"green\"];\n\n const formatResultLine = (category: string, result: { count: number; rolls: any[] }, colorIndex: number) => {\n if (result.count === 0) return `${category}: 0`;\n return `${category}: ${result.count} (Rolls: ${result.rolls.join(\", \")})`;\n };\n\n let summary = `${token.name} ponders the true nature of ${game.user.targets?.first()?.name} (${numberOfUses} Recall Knowledge rolls)
    \n
    \n ${formatResultLine(\"Critical Successes\", results.criticalSuccess, 3)}
    \n ${formatResultLine(\"Successes\", results.success, 2)}
    \n ${formatResultLine(\"Failures\", results.failure, 1)}
    \n ${formatResultLine(\"Critical Failures\", results.criticalFailure, 0)}

    `;\n\n // Get used primary skills\n const usedPrimarySkills = skillInfo.filter((skill) => skill.wasUsed);\n if (usedPrimarySkills.length > 0) {\n summary += \"Used Skills:
    \";\n summary +=\n '';\n for (const skill of usedPrimarySkills) {\n const modifier = skill.actualModifier !== null ? skill.actualModifier : skill.modifier;\n // @ts-expect-error TODO Fix typing\n summary += ``;\n }\n summary += \"
    SkillProficiencyModifier
    ${skill.name}
    ${RANK_NAMES[skill.rank]}
    ${modifier !== null ? (modifier >= 0 ? \"+\" : \"\") + modifier : \"\"}

    \";\n }\n\n // Get used lore skills\n const usedLoreSkills = loreInfo.filter((lore: any) => lore.wasUsed);\n if (usedLoreSkills.length > 0) {\n summary += \"Used Lore Skills:
    \";\n summary +=\n '';\n for (const lore of usedLoreSkills) {\n const modifier = lore.actualModifier !== null ? lore.actualModifier : lore.modifier;\n summary += ``;\n }\n summary += \"
    LoreProficiencyModifier
    ${lore.name}
    ${RANK_NAMES[lore.rank]}
    ${modifier !== null ? (modifier >= 0 ? \"+\" : \"\") + modifier : \"\"}
    \";\n }\n\n await ChatMessage.create({\n content: summary,\n });\n}\n\n// Run the analysis\n// hypercognition(token);\n","import { scaleNPCToLevel } from \"../cr-scaler/NPCScaler.ts\";\nimport { MODULENAME } from \"../../constants.ts\";\nimport { NPCPF2e } from \"foundry-pf2e\";\n\nexport async function npcScaler(): Promise {\n const controlled = canvas.tokens.controlled.flatMap((token) => token.actor ?? []);\n if (controlled.length === 0 && game.user.character) controlled.push(game.user.character);\n const actor = controlled[0];\n\n const supportedActorTypes = [\"npc\"];\n if (!actor || !supportedActorTypes.includes(actor.type)) {\n ui.notifications.warn(game.i18n.localize(`${MODULENAME}.macros.basicActionMacros.noActorSelected`));\n return;\n }\n\n // const oldLevel = actor.system.details.level.value;\n const oldLevel = 24;\n\n await foundry.applications.api.DialogV2.wait({\n window: {\n title: \"Scale NPC\",\n },\n content:\n `

    Scale a creature to a range of levels, creating the creature at each level in the range. The min level must be less than or ` +\n `equal to the max level. To only scale to a single level, set both equal to the desired level.

    ` +\n `
    ` +\n `
    `,\n buttons: [\n {\n icon: '',\n label: \"Scale\",\n action: \"scale\",\n default: true,\n callback: async (_event, button, _dialog) => {\n ui.notifications?.info(`Scaling NPC... please wait.`);\n const startLevel = parseInt(\n (button?.form?.elements.namedItem(\"startLevel\") as HTMLInputElement).value,\n );\n const endLevel = parseInt((button?.form?.elements.namedItem(\"endLevel\") as HTMLInputElement).value);\n\n for (let i = startLevel; i <= endLevel; i++) {\n await scaleNPCToLevel(actor, i);\n }\n ui.notifications?.info(`Scaled ${actor.name} to levels ${startLevel} - ${endLevel}.`);\n },\n },\n ],\n });\n}\n\n// npcScaler();\n","export function registerHandlebarsHelpers(): void {\n Handlebars.registerHelper(\"xdy_includes\", function (array: any[], value: any, options: any) {\n if (array.includes(value)) {\n // @ts-expect-error TODO fix typing\n return options.fn(this);\n } else {\n // @ts-expect-error TODO fix typing\n return options.inverse(this);\n }\n });\n Handlebars.registerHelper(\"xdy_ifeq\", function (v1, v2, options) {\n // @ts-expect-error TODO fix typing\n if (v1 === v2) return options.fn(this);\n else return options.inverse();\n });\n Handlebars.registerHelper(\"xdy_ifne\", function (v1, v2, options) {\n // @ts-expect-error TODO fix typing\n if (v1 !== v2) return options.fn(this);\n else return options.inverse();\n });\n\n Handlebars.registerHelper(\"xdy_isNaN\", function (context, options) {\n if (isNaN(context) && !(typeof context === \"string\")) {\n // @ts-expect-error TODO fix typing\n return options.fn(this);\n } else {\n // @ts-expect-error TODO fix typing\n return options.inverse(this);\n }\n });\n\n Handlebars.registerHelper(\"xdy_undefined\", function () {\n return undefined;\n });\n\n Handlebars.registerHelper(\"xdy_hasKey\", function (context, key) {\n for (const prop of context) {\n if (Object.hasOwn(prop, key)) {\n return true;\n }\n }\n return false;\n });\n}\n","/**\n * Entrypoint for xdy-pf2e-workbench.\n * Author: xdy (Jonas Karlsson)\n * Content License: See LICENSE and README.md for license details\n * Software License: Apache 2.0\n */\n\nimport { preloadTemplates } from \"./preloadTemplates.ts\";\nimport \"../styles/xdy-pf2e-workbench.scss\";\n\n// TODO Make it so holding shift pops up a dialog where one can change the name of the mystified creature\n// TODO Add an option to have the 'demystify' button post a message to chat/pop up a dialog with demystification details (e.g. pretty much the recall knowledge macro), with the chat button doing the actual demystification.\n// TODO Make the button post a chat message with a properly set up RK roll that players can click, as well as a gm-only button on the message that the gm can use to actually unmystify.\nimport { registerWorkbenchKeybindings } from \"./keybinds.ts\";\nimport { ActorPF2e } from \"foundry-pf2e\";\nimport { fireAndForget, getModuleSetting, isFirstGM } from \"./utils.js\";\nimport { logInfo } from \"./utils/logging.js\";\nimport * as systems from \"./utils/systems.ts\";\nimport {\n enableNpcRollerButton,\n NpcRoller,\n registerNpcRollerHandlebarsTemplates,\n} from \"./feature/npc-roller/NpcRoller.ts\";\nimport { scaleNPCToLevelFromActor } from \"./feature/cr-scaler/NPCScaler.ts\";\nimport { generateNameFromTraitsForToken } from \"./feature/tokenMystificationHandler/traits-name-generator.ts\";\nimport { basicActionMacros, registerBasicActionMacrosHandlebarsTemplates } from \"./feature/macros/basicActionMacros.ts\";\nimport { buildNpcSpellbookJournal } from \"./feature/macros/buildNpcSpellbookJournal.ts\";\nimport {\n combatStartHook,\n createChatMessageHook,\n createTokenHook,\n deleteCombatHook,\n deleteItemHook,\n pf2eEndTurnHook,\n pf2eRerollHook,\n pf2eStartTurnHook,\n pf2eSystemReadyHook,\n pf2eToolbeltRollSaveHook,\n preCreateChatMessageHook,\n preCreateItemHook,\n preUpdateActorHook,\n preUpdateTokenHook,\n readyHook,\n renderActorSheetHook,\n renderChatMessageHook,\n renderGamePauseHook,\n renderItemSheetHook,\n renderTokenHUDHook,\n updateCombatHook,\n} from \"./hooks.ts\";\nimport { onScaleNPCContextHook } from \"./feature/cr-scaler/NPCScalerSetup.ts\";\nimport {\n addHeroPoints,\n calcRemainingMinutes,\n callHeroPointHandler,\n createRemainingTimeMessage,\n resetHeroPoints,\n startTimer,\n} from \"./feature/heroPointHandler/index.ts\";\nimport { moveSelectedAheadOfCurrent } from \"./feature/initiativeHandler/index.ts\";\nimport { doMystificationFromToken } from \"./feature/tokenMystificationHandler/index.ts\";\nimport { autoRollDamage, noOrSuccessfulFlatcheck } from \"./feature/damageHandler/index.ts\";\nimport { registerWorkbenchSettings } from \"./settings/index.ts\";\nimport { mystifyNpcItemsByRarity } from \"./feature/qolHandler/index.ts\";\nimport { getAllFromAllowedPacks } from \"./feature/api/getAllFromAllowedPacks.ts\";\n\nimport { refocus } from \"./feature/macros/refocus.ts\";\nimport { followTheExpert } from \"./feature/macros/follow-the-expert.ts\";\nimport { hypercognition } from \"./feature/macros/hypercognition.ts\";\nimport { npcScaler } from \"./feature/macros/npcScaler.ts\";\nimport { initCanvasPointer } from \"./feature/canvas-pointer/index.ts\";\nimport { registerHandlebarsHelpers } from \"./utils/handlebarsHelpers.ts\";\nimport { registerToolbeltWrappers } from \"./feature/damageHandler/toolbeltIntegration.ts\";\nimport { MODULENAME } from \"./constants.ts\";\nimport { phase, Phase, setPhase } from \"./lifecycle.ts\";\n\nexport { Phase } from \"./lifecycle.ts\";\n\nexport const NPC_TYPE = \"npc\";\nexport const CHARACTER_TYPE = \"character\";\n\nconst activeHooks = new Set();\n\nfunction handle(\n hookName: string,\n shouldBeOn: unknown,\n hookFunction: (...args: unknown[]) => boolean | void | Promise,\n once = false,\n): void {\n if (!activeHooks.has(hookName)) {\n if (shouldBeOn) {\n if (once) {\n Hooks.once(hookName, hookFunction);\n } else {\n Hooks.on(hookName, hookFunction);\n }\n activeHooks.add(hookName);\n }\n } else {\n if (!shouldBeOn) {\n Hooks.off(hookName, hookFunction);\n activeHooks.delete(hookName);\n }\n }\n}\n\nexport function updateHooks(cleanSlate = false): void {\n if (phase > Phase.SETUP && game.user.isGM) {\n game.socket.emit(\"module.\" + MODULENAME, { operation: \"updateHooks\" });\n }\n if (cleanSlate) {\n activeHooks.clear();\n }\n\n const autoRollDamageAllow = getModuleSetting(\"autoRollDamageAllow\");\n const experimentalToolbeltSaveIntegration = getModuleSetting(\"experimentalToolbeltSaveIntegration\");\n const autoRollDamageForStrike = getModuleSetting(\"autoRollDamageForStrike\");\n const autoRollDamageForSpellAttack = getModuleSetting(\"autoRollDamageForSpellAttack\");\n const autoRollDamageForSpellWhenNotAnAttack = getModuleSetting(\"autoRollDamageForSpellWhenNotAnAttack\");\n const castPrivateSpell = getModuleSetting(\"castPrivateSpell\");\n const reminderTargeting = getModuleSetting(\"reminderTargeting\");\n const reminderCannotAttack = getModuleSetting(\"reminderCannotAttack\");\n const applyPersistentDamage = getModuleSetting(\"applyPersistentDamage\");\n const applyPersistentHealing = getModuleSetting(\"applyPersistentHealing\");\n const reminderBreathWeapon = getModuleSetting(\"reminderBreathWeapon\");\n const autoGainDyingIfTakingDamageWhenAlreadyDying = getModuleSetting(\n \"autoGainDyingIfTakingDamageWhenAlreadyDying\",\n );\n const autoCollapseItemChatCardContent = getModuleSetting(\"autoCollapseItemChatCardContent\");\n const autoCollapseItemActionChatCardContent = getModuleSetting(\"autoCollapseItemActionChatCardContent\");\n const autoCollapseItemAttackChatCardContent = getModuleSetting(\"autoCollapseItemAttackChatCardContent\");\n const autoExpandDamageRolls = getModuleSetting(\"autoExpandDamageRolls\");\n const heroPointRules = getModuleSetting(\"heroPointRules\");\n const npcScaler = getModuleSetting(\"npcScaler\");\n const npcRoller = getModuleSetting(\"npcRoller\");\n const dropHeldItemsOnBecomingUnconscious = getModuleSetting(\"dropHeldItemsOnBecomingUnconscious\");\n const housepatcher = getModuleSetting(\"housepatcher\");\n const decreaseFrightenedConditionEachTurn = getModuleSetting(\"decreaseFrightenedConditionEachTurn\");\n const actionsReminderAllow = getModuleSetting(\"actionsReminderAllow\");\n const autoReduceStunned = getModuleSetting(\"autoReduceStunned\");\n const npcMystifier = getModuleSetting(\"npcMystifier\");\n const enableAutomaticMove = getModuleSetting(\"enableAutomaticMove\");\n const autoGainDyingAtZeroHP = getModuleSetting(\"autoGainDyingAtZeroHP\");\n const nonLethalIsNotLethal = getModuleSetting(\"nonLethalIsNotLethal\");\n const autoRemoveDyingAtGreaterThanZeroHP = getModuleSetting(\"autoRemoveDyingAtGreaterThanZeroHP\");\n const autoRemoveUnconsciousAtGreaterThanZeroHP = getModuleSetting(\n \"autoRemoveUnconsciousAtGreaterThanZeroHP\",\n );\n const npcMystifyAllPhysicalMagicalItems = getModuleSetting(\"npcMystifyAllPhysicalMagicalItems\");\n const tokenAnimation = getModuleSetting(\"tokenAnimation\");\n const playerFeatsRarityColour = getModuleSetting(\"playerFeatsRarityColour\");\n const playerFeatsPrerequisiteHint = getModuleSetting(\"playerFeatsPrerequisiteHint\");\n const playerSpellsRarityColour = getModuleSetting(\"playerSpellsRarityColour\");\n const playerAbcdRarityColour = getModuleSetting(\"playerAbcdRarityColour\");\n const playerSpellsChangeSendToChat = getModuleSetting(\"playerSpellsChangeSendToChat\");\n const sheatheHeldItemsAfterEncounter = getModuleSetting(\"sheatheHeldItemsAfterEncounter\");\n const showItemLicenseTags = getModuleSetting(\"showItemLicenseTags\");\n const showCharacterOglTag = getModuleSetting(\"showCharacterOglTag\");\n const enableGeneralLearnSpell = getModuleSetting(\"enableGeneralLearnSpell\");\n\n const handleDyingRecoveryRoll = getModuleSetting(\"handleDyingRecoveryRoll\");\n const giveWoundedWhenDyingRemoved = getModuleSetting(\"giveWoundedWhenDyingRemoved\");\n const giveUnconsciousIfDyingRemovedAt0HP = getModuleSetting(\"giveUnconsciousIfDyingRemovedAt0HP\");\n\n handle(\"getActorContextOptions\", npcScaler, onScaleNPCContextHook);\n handle(\"renderJournalDirectory\", npcRoller, enableNpcRollerButton);\n handle(\"controlToken\", npcRoller, NpcRoller.onControlToken);\n\n handle(\n \"preCreateChatMessage\",\n castPrivateSpell ||\n reminderTargeting !== \"no\" ||\n reminderCannotAttack === \"cancelAttack\" ||\n applyPersistentDamage ||\n applyPersistentHealing,\n preCreateChatMessageHook,\n );\n\n handle(\n \"createChatMessage\",\n (autoRollDamageAllow &&\n (autoRollDamageForStrike ||\n autoRollDamageForSpellAttack ||\n autoRollDamageForSpellWhenNotAnAttack !== \"no\")) ||\n reminderBreathWeapon ||\n reminderCannotAttack === \"reminder\" ||\n !autoGainDyingIfTakingDamageWhenAlreadyDying.startsWith(\"no\"),\n createChatMessageHook,\n );\n\n const toolbeltSaveSpellActive =\n experimentalToolbeltSaveIntegration &&\n autoRollDamageAllow &&\n [\"saveSpell\", \"anySpell\"].includes(autoRollDamageForSpellWhenNotAnAttack) &&\n !!game.modules.get(\"pf2e-toolbelt\")?.active;\n\n handle(\"pf2e-toolbelt.rollSave\", toolbeltSaveSpellActive, pf2eToolbeltRollSaveHook);\n\n handle(\"combatStart\", toolbeltSaveSpellActive, combatStartHook);\n handle(\"updateCombat\", toolbeltSaveSpellActive, updateCombatHook);\n handle(\"deleteCombat\", sheatheHeldItemsAfterEncounter || toolbeltSaveSpellActive, deleteCombatHook);\n\n handle(\"renderTokenHUD\", npcMystifier, renderTokenHUDHook);\n\n handle(\n \"renderChatMessageHTML\",\n castPrivateSpell ||\n [\"collapsedDefault\", \"nonCollapsedDefault\"].includes(autoCollapseItemChatCardContent) ||\n [\"collapsedDefault\", \"nonCollapsedDefault\"].includes(autoCollapseItemActionChatCardContent) ||\n [\"collapsedDefault\", \"nonCollapsedDefault\"].includes(autoCollapseItemAttackChatCardContent) ||\n [\"expandedAll\", \"expandedNew\", \"expandedNewest\"].includes(autoExpandDamageRolls) ||\n handleDyingRecoveryRoll /* Deprecated */ ||\n heroPointRules !== \"no\",\n renderChatMessageHook,\n );\n\n handle(\"preCreateItem\", enableGeneralLearnSpell || dropHeldItemsOnBecomingUnconscious, preCreateItemHook);\n\n handle(\"deleteItem\", giveWoundedWhenDyingRemoved || giveUnconsciousIfDyingRemovedAt0HP, deleteItemHook);\n\n handle(\"pf2e.systemReady\", housepatcher !== \"\", pf2eSystemReadyHook, true);\n\n handle(\"pf2e.endTurn\", decreaseFrightenedConditionEachTurn, pf2eEndTurnHook);\n\n handle(\"pf2e.startTurn\", actionsReminderAllow !== \"none\" || autoReduceStunned, pf2eStartTurnHook);\n\n handle(\n \"pf2e.reroll\",\n heroPointRules === \"keeleysHeroPointRule\" ||\n heroPointRules === \"useHighestHeroPointRoll\" ||\n heroPointRules === \"heroicRerolls\",\n pf2eRerollHook,\n );\n\n handle(\"renderTokenHUD\", npcMystifier, renderTokenHUDHook);\n\n handle(\n \"preUpdateActor\",\n enableAutomaticMove.startsWith(\"reaching0HP\") ||\n !autoGainDyingAtZeroHP.startsWith(\"no\") ||\n !nonLethalIsNotLethal.startsWith(\"no\") ||\n !autoRemoveDyingAtGreaterThanZeroHP.startsWith(\"no\") ||\n autoRemoveUnconsciousAtGreaterThanZeroHP ||\n (systems.getSystemSetting(\"automation\", \"lootableNPCs\") &&\n npcMystifyAllPhysicalMagicalItems === \"onZeroHp\"),\n preUpdateActorHook,\n );\n\n handle(\"preUpdateToken\", tokenAnimation, preUpdateTokenHook);\n\n handle(\n \"createToken\",\n npcMystifier ||\n (systems.getSystemSetting(\"automation\", \"lootableNPCs\") &&\n npcMystifyAllPhysicalMagicalItems === \"onScene\"),\n createTokenHook,\n );\n\n handle(\n \"renderActorSheet\",\n playerFeatsRarityColour ||\n playerFeatsPrerequisiteHint ||\n playerSpellsRarityColour ||\n playerAbcdRarityColour ||\n castPrivateSpell ||\n playerSpellsChangeSendToChat ||\n showCharacterOglTag,\n renderActorSheetHook,\n );\n\n handle(\"renderItemSheet\", showItemLicenseTags, renderItemSheetHook);\n\n const customPauseImage = getModuleSetting(\"customPauseImage\");\n const customPauseText = getModuleSetting(\"customPauseText\");\n const pauseImageNoSpin = getModuleSetting(\"pauseImageNoSpin\");\n handle(\n \"renderGamePause\",\n customPauseImage !== \"\" || customPauseText !== \"\" || pauseImageNoSpin,\n renderGamePauseHook,\n );\n\n handle(\n \"ready\",\n getModuleSetting(\"legacyVariantRuleAncestryParagon\") ||\n getModuleSetting(\"legacyVariantRuleDualClass\"),\n readyHook,\n true,\n );\n}\n\n// Initialize module\nHooks.once(\"init\", async (_actor: ActorPF2e) => {\n logInfo(`${MODULENAME} | Initializing xdy-pf2e-workbench`);\n setPhase(Phase.INIT);\n\n registerWorkbenchSettings();\n registerWorkbenchKeybindings();\n\n await preloadTemplates();\n fireAndForget(registerNpcRollerHandlebarsTemplates(), \"registerNpcRollerHandlebarsTemplates\");\n\n fireAndForget(registerBasicActionMacrosHandlebarsTemplates(), \"registerBasicActionMacrosHandlebarsTemplates\");\n\n registerHandlebarsHelpers();\n\n initCanvasPointer();\n\n // Hooks that always run\n // None currently\n\n // Hooks that run once, if a setting is enabled. Manual refresh will still be needed for these.\n\n // Hooks that only run if a setting that needs it has been enabled\n updateHooks();\n\n // Register custom sheets (if any)\n});\n\n// Setup module\nHooks.once(\"setup\", async () => {\n logInfo(`${MODULENAME} | Setting up`);\n setPhase(Phase.SETUP);\n // Do anything after initialization but before ready\n\n // General module setup\n});\n\n// When ready\nHooks.once(\"ready\", () => {\n // Do anything once the module is ready\n logInfo(`${MODULENAME} | Ready`);\n setPhase(Phase.READY);\n\n // Must be in ready\n\n // Make some functions available for macros\n // noinspection UnnecessaryLocalVariableJS,JSUnusedGlobalSymbols\n const api = {\n resetHeroPoints: resetHeroPoints, // game.PF2eWorkbench.resetHeroPoints(1)\n addHeroPoints: addHeroPoints, // game.PF2eWorkbench.addHeroPoints(1, \"ALL\") OR game.PF2eWorkbench.addHeroPoints(1, _token.actor.id)\n scaleNPCToLevelFromActor: scaleNPCToLevelFromActor, // game.PF2eWorkbench.scaleNPCToLevelFromActor(_token.actor.id, 24);\n moveSelectedAheadOfCurrent: moveSelectedAheadOfCurrent, // await game.PF2eWorkbench.moveSelectedAheadOfCurrent(await game.combat?.getCombatantsByToken(_token.id)[0].id)\n doMystificationFromToken: doMystificationFromToken, // await game.PF2eWorkbench.doMystificationFromToken(_token.id, true) OR await game.PF2eWorkbench.doMystificationFromToken(_token.id, false)\n generateNameFromTraitsFromTokenId: generateNameFromTraitsForToken, // await game.PF2eWorkbench.generateNameFromTraitsFromTokenId(_token.id)\n noOrSuccessfulFlatcheck: noOrSuccessfulFlatcheck, // await game.PF2eWorkbench.noOrSuccessfulFlatcheck(game.messages.get(\"messageId\"))\n basicActionMacros: basicActionMacros, // await game.PF2eWorkbench.basicActionMacros()\n refocus: refocus, // await game.PF2eWorkbench.refocus()\n followTheExpert: followTheExpert, // await game.PF2eWorkbench.followTheExpert()\n hypercognition: hypercognition, // await game.PF2eWorkbench.followTheExpert()\n buildNpcSpellbookJournal: buildNpcSpellbookJournal, // await game.PF2eWorkbench.buildNpcSpellbookJournal()\n callHeroPointHandler: callHeroPointHandler, // await game.PF2eWorkbench.callHeroPointHandler()\n mystifyNpcItemsByRarity: mystifyNpcItemsByRarity, // await game.PF2eWorkbench.mystifyNpcItemsByRarity(actor, usingPartyLevel?, thresholds?)\n getAllFromAllowedPacks: getAllFromAllowedPacks, // await game.PF2eWorkbench.getAllFromAllowedPacks({ type, fields, filter, strictSourcing, fetch})\n npcScaler: npcScaler, // await game.PF2eWorkbench.npcScaler()\n autoRollDamage: autoRollDamage, // await game.PF2eWorkbench.autoRollDamage(message)\n };\n // @ts-expect-error Adding new field to game global\n game.PF2eWorkbench = api;\n // @ts-expect-error Adding new field to game global\n console.debug(`${MODULENAME} | game.PF2eWorkbench registered`, !!game.PF2eWorkbench);\n\n const autoRollSpell = getModuleSetting(\"autoRollDamageForSpellWhenNotAnAttack\");\n if (game.modules.get(\"pf2e-toolbelt\")?.active && (autoRollSpell === \"anySpell\" || autoRollSpell === \"saveSpell\")) {\n registerToolbeltWrappers();\n }\n\n if (game.modules.get(\"pf2e-sheet-skill-actions\")?.active) {\n ui.notifications.error(game.i18n.localize(`${MODULENAME}.modules.pf2e-sheet-skill-actions`));\n }\n\n if (game.modules.get(\"pf2e-toolbox\")?.active) {\n ui.notifications.error(game.i18n.localize(`${MODULENAME}.modules.pf2e-toolbox`));\n }\n\n const ta = getModuleSetting(\"tokenAnimation\");\n const mlt = game.modules.get(\"multilevel-tokens\");\n if (ta && mlt?.active) {\n ui.notifications.error(game.i18n.localize(`${MODULENAME}.modules.multilevel-tokens`));\n }\n\n updateHooks();\n\n // TODO Instead of opening immediately, add a handler that hooks onto the *first* unpause, and starts then.\n // TODO Check if more than 'timer max' minutes have passed, if so assume new start and reset to 'timer max' minutes.\n if (isFirstGM() && getModuleSetting(\"heroPointHandler\")) {\n let remainingMinutes = calcRemainingMinutes(false);\n if (remainingMinutes > 0 || getModuleSetting(\"heroPointHandlerStartTimerOnReady\")) {\n remainingMinutes = calcRemainingMinutes(true);\n startTimer(remainingMinutes).then(() => {\n createRemainingTimeMessage(remainingMinutes);\n });\n }\n }\n\n game.socket.on(\"module.\" + MODULENAME, (operation) => {\n switch (operation?.operation) {\n case \"updateHooks\":\n if (!game.user.isGM) {\n updateHooks();\n }\n break;\n case \"notification\":\n if (!game.user.isGM) {\n const type = operation.args[0];\n const message = operation.args[1];\n ui.notifications.notify(message, type);\n }\n break;\n default:\n break;\n }\n });\n\n setPhase(Phase.ACTIVE);\n Hooks.callAll(`${MODULENAME}.moduleReady`);\n});\n"],"x_google_ignoreList":[23,24,25],"mappings":"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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;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"}