{"version":3,"file":"token-action-hud-core.min.mjs","sources":["../module/core/constants.mjs","../module/core/utils.mjs","../module/handlers/data-handler.mjs","../module/managers/migration-manager.mjs","../module/handlers/character-handler.mjs","../module/handlers/layout-handler.mjs","../module/handlers/tooltip-handler.mjs","../module/handlers/group-handler.mjs","../module/managers/hud-manager.mjs","../module/dialogs/reset-layout.mjs","../module/applications/form-app.mjs","../module/applications/form-app-helper.mjs","../module/applications/add-subgroup-app.mjs","../module/applications/add-action-app.mjs","../module/handlers/group-resizer.mjs","../module/applications/token-action-hud.mjs","../module/core/sockets.mjs","../module/handlers/action-handlers/generic-action-handler.mjs","../module/handlers/action-handlers/compendium-action-handler.mjs","../module/handlers/action-handlers/macro-action-handler.mjs","../module/handlers/action-handlers/action-handler.mjs","../module/handlers/action-handlers/action-handler-extender.mjs","../module/handlers/roll-handlers/roll-handler.mjs","../module/handlers/roll-handlers/pre-roll-handler.mjs","../module/handlers/roll-handlers/roll-handler-extender.mjs","../module/applications/custom-style-form.mjs","../module/dialogs/reset-all-layouts.mjs","../module/applications/settings-form.mjs","../module/core/settings.mjs","../module/handlers/action-handlers/item-macro-extender.mjs","../module/managers/system-manager.mjs","../module/core/api.mjs","../module/main.mjs"],"sourcesContent":["/**\n * Module-based constants\n */\nexport const MODULE = {\n ID: \"token-action-hud-core\",\n NAME: \"Token Action HUD\"\n};\n\n\n/* -------------------------------------------- */\n\n/**\n * Template directory\n */\nconst TEMPLATE_DIR = `modules/${MODULE.ID}/templates`;\n\n/* -------------------------------------------- */\n\n/**\n * Templates\n */\nexport const TEMPLATE = {\n action: `${TEMPLATE_DIR}/action.hbs`,\n addPopover: `${TEMPLATE_DIR}/add-popover.hbs`,\n customStyleForm: `${TEMPLATE_DIR}/custom-style-form.hbs`,\n group: `${TEMPLATE_DIR}/group.hbs`,\n hud: `${TEMPLATE_DIR}/hud.hbs`,\n listSubgroup: `${TEMPLATE_DIR}/list-subgroup.hbs`,\n settings: `${TEMPLATE_DIR}/settings.hbs`,\n tabSubgroup: `${TEMPLATE_DIR}/tab-subgroup.hbs`,\n formHud: `${TEMPLATE_DIR}/form-hud.hbs`,\n formGroup: `${TEMPLATE_DIR}/form-group.hbs`,\n formSubgroup: `${TEMPLATE_DIR}/form-subgroup.hbs`\n};\n\n/* -------------------------------------------- */\n\n/**\n * Delimiter character\n */\nexport const DELIMITER = \"|\";\n\n/* -------------------------------------------- */\n\n/**\n * Action types\n */\nexport const ACTION_TYPE = {\n compendiumEntry: \"tokenActionHud.compendiumEntry\",\n compendiumMacro: \"tokenActionHud.compendiumMacro\",\n compendiumPlaylist: \"tokenActionHud.compendiumPlaylist\",\n macro: \"tokenActionHud.macro\"\n};\n\n/* -------------------------------------------- */\n\n/**\n * Compendium action types\n */\nexport const COMPENDIUM_ACTION_TYPES = [\"compendiumEntry\", \"compendiumMacro\", \"compendiumPlaylist\", \"macro\"];\n\n/* -------------------------------------------- */\n\n/**\n * Compendium pack types\n */\nexport const COMPENDIUM_PACK_TYPES = [\"JournalEntry\", \"Macro\", \"RollTable\"];\n\n/* -------------------------------------------- */\n\n/**\n * CSS styles\n */\nexport const CSS_STYLE = {\n foundryVTT: {\n class: \"tah-style-foundry-vtt-dark\",\n file: \"tah-foundry-vtt-dark\",\n moduleId: MODULE.ID,\n name: \"Foundry VTT Dark\",\n primaryColor: \"#dddddd\",\n secondaryColor: \"#dddddd80\",\n tertiaryColor: \"#ff6400\"\n },\n compact: {\n class: \"tah-style-foundry-vtt-dark-compact\",\n file: \"tah-foundry-vtt-dark-compact\",\n moduleId: MODULE.ID,\n name: \"Foundry VTT Dark Compact\",\n primaryColor: \"#dddddd\",\n secondaryColor: \"#dddddd80\",\n tertiaryColor: \"#ff6400\"\n },\n dockedLeft: {\n class: \"tah-style-docked-left\",\n file: \"tah-docked-left\",\n moduleId: MODULE.ID,\n name: \"Foundry VTT Dark Docked Left\",\n primaryColor: \"#dddddd\",\n secondaryColor: \"#dddddd80\",\n tertiaryColor: \"#ff6400\",\n isDocked: true,\n dockPosition: \"left\"\n },\n dockedCenterRight: {\n class: \"tah-style-docked-right\",\n file: \"tah-docked-right\",\n moduleId: MODULE.ID,\n name: \"Foundry VTT Dark Docked Center-Right\",\n primaryColor: \"#dddddd\",\n secondaryColor: \"#dddddd80\",\n tertiaryColor: \"#ff6400\",\n collapseIcon: \"fa-caret-right\",\n expandIcon: \"fa-caret-left\",\n isDocked: true,\n dockPosition: \"center-right\"\n },\n dockedRight: {\n class: \"tah-style-docked-right\",\n file: \"tah-docked-right\",\n moduleId: MODULE.ID,\n name: \"Foundry VTT Dark Docked Right\",\n primaryColor: \"#dddddd\",\n secondaryColor: \"#dddddd80\",\n tertiaryColor: \"#ff6400\",\n collapseIcon: \"fa-caret-right\",\n expandIcon: \"fa-caret-left\",\n isDocked: true,\n dockPosition: \"right\"\n },\n foundryVttLight: {\n class: \"tah-style-foundry-vtt-light\",\n file: \"tah-foundry-vtt-light\",\n moduleId: MODULE.ID,\n name: \"Foundry VTT Light\",\n primaryColor: \"#dddddd\",\n secondaryColor: \"#dddddd80\",\n tertiaryColor: \"#ff6400\"\n },\n pathfinder: {\n class: \"tah-style-pathfinder\",\n file: \"tah-pathfinder\",\n moduleId: MODULE.ID,\n name: \"Pathfinder\"\n },\n highContrast: {\n class: \"tah-style-high-contrast\",\n file: \"tah-high-contrast\",\n moduleId: MODULE.ID,\n name: \"High Contrast\",\n primaryColor: \"#ffff00\",\n secondaryColor: \"#ffff00\",\n tertiaryColor: \"#0C7BDC\"\n },\n custom: {\n class: \"tah-style-custom\",\n file: \"tah-custom\",\n moduleId: MODULE.ID,\n name: \"Custom\"\n }\n};\n\n/* -------------------------------------------- */\n\n/**\n * Custom styles\n */\nexport const CUSTOM_STYLE = {\n backgroundColor: { cssProperty: \"--tah-background-color\", type: String, default: \"#00000000\" },\n buttonHeight: { cssProperty: \"--tah-button-height-editable\", type: Number, default: 32 },\n buttonBackgroundColor: { cssProperty: \"--tah-button-background-color-editable\", type: String, default: \"#000000b3\" },\n buttonBorderPrimaryColor: { cssProperty: \"--tah-button-border-primary-color-editable\", type: String, default: \"#0C0C0CFF\" },\n buttonBorderSecondaryColor: { cssProperty: \"--tah-button-border-secondary-color-editable\", type: String, default: \"#060606FF\" },\n buttonTextColor: { cssProperty: \"--tah-button-text-color-editable\", type: String, default: \"#DDDDDDFF\" },\n buttonHoverBorderPrimaryColor: { cssProperty: \"--tah-button-hover-border-primary-color-editable\", type: String, default: \"#FF6400FF\" },\n buttonHoverBorderSecondaryColor: { cssProperty: \"--tah-button-hover-border-secondary-color-editable\", type: String, default: \"#FF0000FF\" },\n buttonHoverBackgroundColor: { cssProperty: \"--tah-button-hover-background-color-editable\", type: String, default: \"#000000B3\" },\n buttonHoverTextColor: { cssProperty: \"--tah-button-hover-text-color-editable\", type: String, default: \"#FFFFFFFF\" },\n buttonToggleActiveBackgroundColor: { cssProperty: \"--tah-button-toggle-active-background-color-editable\", type: String, default: \"#3C0078BF\" },\n buttonToggleActiveBorderPrimaryColor: { cssProperty: \"--tah-button-toggle-active-border-primary-color-editable\", type: String, default: \"#9B8DFFFF\" },\n buttonToggleActiveBorderSecondaryColor: { cssProperty: \"--tah-button-toggle-active-border-secondary-color-editable\", type: String, default: \"#9B8DFFFF\" },\n buttonToggleActiveTextColor: { cssProperty: \"--tah-button-toggle-active-text-color-editable\", type: String, default: \"#FFFFFFFF\" },\n buttonToggleHoverBackgroundColor: { cssProperty: \"--tah-button-toggle-hover-background-color-editable\", type: String, default: \"#3C0078BF\" },\n buttonToggleHoverBorderPrimaryColor: { cssProperty: \"--tah-button-toggle-hover-border-primary-color-editable\", type: String, default: \"#9B8DFFFF\" },\n buttonToggleHoverBorderSecondaryColor: { cssProperty: \"--tah-button-toggle-hover-secondary-color-editable\", type: String, default: \"#9B8DFFFF\" },\n buttonToggleHoverTextColor: { cssProperty: \"--tah-button-toggle-hover-text-color-editable\", type: String, default: \"#FFFFFFFF\" },\n textPrimaryColor: { cssProperty: \"--tah-text-primary-color-editable\", type: String, default: \"#DDDDDDFF\" },\n textSecondaryColor: { cssProperty: \"--tah-text-secondary-color-editable\", type: String, default: \"#DDDDDD80\" },\n textTertiaryColor: { cssProperty: \"--tah-text-tertiary-color-editable\", type: String, default: \"#FF6400FF\" },\n textHoverPrimaryColor: { cssProperty: \"--tah-text-hover-primary-color-editable\", type: String, default: \"#DDDDDDFF\" },\n textHoverSecondaryColor: { cssProperty: \"--tah-text-hover-secondary-color-editable\", type: String, default: \"#DDDDDD80\" },\n textHoverTertiaryColor: { cssProperty: \"--tah-text-tertiary-color-editable\", type: String, default: \"#FF6400FF\" }\n};\n\n/* -------------------------------------------- */\n\n/**\n * Group types\n */\nexport const GROUP_TYPE = {\n COMPENDIUM: \"compendium\",\n CUSTOM: \"custom\",\n SYSTEM: \"system\",\n SYSTEM_DERIVED: \"system-derived\"\n};\n\n/* -------------------------------------------- */\n\n/**\n * HUD\n */\nexport const HUD = {\n DEFAULT_HEIGHT: 200,\n DEFAULT_WIDTH: 20,\n DEFAULT_LEFT_POS: 150,\n DEFAULT_TOP_POS: 80,\n DEFAULT_SCALE: 1,\n DEFAULT_ZINDEX: 100\n};\n\n/* -------------------------------------------- */\n\n/**\n * Item Macro icon\n */\nexport const ITEM_MACRO_ICON = {\n ICON: \"fas fa-sd-card\",\n TOOLTIP: \"Item Macro\"\n};\n\n/* -------------------------------------------- */\n\n/**\n * Layout settings\n */\nexport const LAYOUT_SETTING = {\n customLayout: {\n hint: \"tokenActionHud.settings.customLayout.hint\",\n name: \"tokenActionHud.settings.customLayout.name\",\n inputType: \"filePicker\",\n filePickerType: \"json\",\n dtype: \"String\",\n scope: \"world\"\n },\n userCustomLayout: {\n hint: \"tokenActionHud.settings.userCustomLayout.hint\",\n name: \"tokenActionHud.settings.userCustomLayout.name\",\n inputType: \"filePicker\",\n filePickerType: \"json\",\n dtype: \"String\",\n scope: \"user\"\n },\n exportLayout: {\n hint: \"tokenActionHud.settings.exportLayout.hint\",\n label: \"tokenActionHud.settings.exportLayout.label\",\n name: \"tokenActionHud.settings.exportLayout.name\",\n inputType: \"button\",\n icon: \"fa-solid fa-file-export\",\n action: \"exportLayout\"\n },\n resetLayout: {\n hint: \"tokenActionHud.settings.resetLayout.hint\",\n label: \"tokenActionHud.settings.resetLayout.label\",\n name: \"tokenActionHud.settings.resetLayout.name\",\n inputType: \"button\",\n icon: \"fa-solid fa-arrow-rotate-left\",\n action: \"resetLayout\",\n scope: \"client\"\n },\n resetAllLayouts: {\n hint: \"tokenActionHud.settings.resetAllLayouts.hint\",\n label: \"tokenActionHud.settings.resetAllLayouts.label\",\n name: \"tokenActionHud.settings.resetAllLayouts.name\",\n inputType: \"button\",\n icon: \"fa-solid fa-bomb\",\n action: \"resetAllLayouts\",\n scope: \"world\"\n }\n};\n\n/* -------------------------------------------- */\n\n/**\n * Settings\n */\nexport const SETTING = {\n activeCssAsText: { classes: [\"TokenActionHud\"], cache: true },\n allow: { classes: [\"TokenActionHud\"], cache: true },\n alwaysShowHud: { classes: [\"TokenActionHud\"], cache: true },\n backgroundColor: {},\n buttonBackgroundColor: {},\n buttonBorderPrimaryColor: {},\n buttonBorderSecondaryColor: {},\n buttonHeight: {},\n buttonHoverBorderPrimaryColor: {},\n buttonHoverBorderSecondaryColor: {},\n buttonHoverBackgroundColor: {},\n buttonHoverTextColor: {},\n buttonTextColor: {},\n buttonToggleActiveBackgroundColor: {},\n buttonToggleActiveBorderPrimaryColor: {},\n buttonToggleActiveBorderSecondaryColor: {},\n buttonToggleActiveTextColor: {},\n buttonToggleHoverBackgroundColor: {},\n buttonToggleHoverBorderPrimaryColor: {},\n buttonToggleHoverBorderSecondaryColor: {},\n buttonToggleHoverTextColor: {},\n clickOpenCategory: { classes: [\"TokenActionHud\"], cache: true },\n customLayout: { classes: [\"ActionHandler\"], cache: true },\n customStyle: {},\n debug: { classes: [\"TokenActionHud\"], cache: true },\n direction: { classes: [\"TokenActionHud\"], cache: true },\n displayCharacterName: { classes: [\"TokenActionHud\"], cache: true },\n displayIcons: { classes: [\"TokenActionHud\"], cache: true },\n drag: { classes: [\"TokenActionHud\"], cache: true },\n enable: { classes: [\"TokenActionHud\"], cache: true },\n enableCustomization: { classes: [\"ActionHandler\", \"TokenActionHud\"], cache: true },\n grid: { classes: [\"TokenActionHud\"], cache: true },\n itemMacro: {},\n migrationVersion: {},\n reset: {},\n renderItemOnRightClick: {},\n rollHandler: { default: \"core\" },\n scale: { classes: [\"TokenActionHud\"], cache: true },\n sortActions: { classes: [\"ActionHandler\"], cache: true },\n startup: {},\n style: { classes: [\"TokenActionHud\"], cache: true },\n tooltips: { classes: [\"ActionHandler\"], cache: true },\n textPrimaryColor: {},\n textSecondaryColor: {},\n textTertiaryColor: {},\n textHoverPrimaryColor: {},\n textHoverSecondaryColor: {},\n textHoverTertiaryColor: {},\n userCustomLayout: { classes: [\"ActionHandler\"], cache: true }\n};\n","import { CSS_STYLE, CUSTOM_STYLE, MODULE } from \"./constants.mjs\";\n\n/**\n * A class responsible for logging messages to the console.\n */\nexport class Logger {\n /**\n * Log an info message to the console. If 'notify' is true, also send a notification.\n * @param {string} message\n * @param {boolean} notify Whether to send a notification\n */\n static info(message, notify = false) {\n if (notify) ui.notifications.info(`Token Action HUD | ${message}`);\n else console.log(`Token Action HUD Info | ${message}`);\n }\n\n /* -------------------------------------------- */\n\n /**\n * Log an error message to the console. If 'notify' is true, also send a notification.\n * @param {string} message\n * @param {boolean} notify Whether to send a notification\n */\n static error(message, notify = false) {\n if (notify) ui.notifications.error(`Token Action HUD | ${message}`, { permanent: true });\n else console.error(`Token Action HUD Error | ${message}`);\n }\n\n /* -------------------------------------------- */\n\n /**\n * Log a debug message and, optionally, data to the console.\n * @param {string} message\n * @param {object|null} data\n */\n static debug(message, data = null) {\n const isDebug = game.tokenActionHud?.setting?.debug ?? Utils.getSetting(\"debug\");\n if (isDebug) {\n if (!data) {\n console.log(`Token Action HUD Debug | ${message}`);\n return;\n }\n const dataClone = Utils.deepClone(data);\n console.log(`Token Action HUD Debug | ${message}`, dataClone);\n }\n }\n}\n\n/* -------------------------------------------- */\n\n/**\n * A class responsible for setting and aborting timers.\n */\nexport class Timer {\n constructor(milliseconds) {\n this.milliseconds = milliseconds;\n this.timer = null;\n }\n\n async start() {\n if (this.timer) this.abort();\n return new Promise(resolve => {\n this.timer = setTimeout(() => { resolve(); }, this.milliseconds ?? 100);\n });\n }\n\n async abort() {\n clearTimeout(this.timer);\n this.timer = null;\n }\n}\n\n/* -------------------------------------------- */\n\n/**\n * A class of helper functions.\n */\nexport class Utils {\n\n /* -------------------------------------------- */\n /* HELPERS */\n /* -------------------------------------------- */\n\n /**\n * Whether the user is allowed to use the HUD.\n * @public\n * @param {number} userRole\n * @param {number} allowSetting Allow setting value\n * @returns {boolean} Whether the user is allowed to use the HUD\n */\n static checkAllow(userRole, allowSetting) {\n return userRole >= allowSetting;\n }\n\n /* -------------------------------------------- */\n\n /**\n * Capitalize the first letter of every word.\n * @param {string} value\n * @returns {string} Capitalized value\n */\n static capitalize(value) {\n return value.replace(\n /\\w\\S*/g,\n text => text.charAt(0).toUpperCase() + text.substring(1).toLowerCase()\n );\n }\n\n /* -------------------------------------------- */\n\n /**\n * Foundry VTT's deepClone function wrapped here to avoid code error highlighting due to missing definition.\n * @public\n * @param {object} original Original object\n * @param {object} options\n * @returns {object} Cloned object\n */\n static deepClone(original, options) {\n // eslint-disable-next-line no-undef\n return foundry.utils.deepClone(original, options);\n }\n\n /* -------------------------------------------- */\n /* GETTERS */\n /* -------------------------------------------- */\n\n /**\n * Get actor from the token or actor.\n * @public\n * @param {string} actorId\n * @param {string} tokenId\n * @returns {object} Actor\n */\n static getActor(actorId, tokenId) {\n let token = null;\n if (tokenId) token = canvas.tokens.placeables.find(token => token.id === tokenId);\n if (token) return token.actor;\n return game.actors.get(actorId);\n }\n\n /**\n * Get closest group to the event target.\n * @param {Event} event\n * @returns {object} Closest group element\n */\n static getClosestGroupElement(event) {\n if (!event) return null;\n return event.target.closest(\"[data-part=\\\"subgroup\\\"]\") || event.target.closest(\"[data-part=\\\"group\\\"]\");\n }\n\n /* -------------------------------------------- */\n\n /**\n * Get actors of controlled tokens.\n * @public\n * @returns {Array} List of actors\n */\n static getControlledActors() {\n const tokens = game.canvas.tokens?.controlled ?? [];\n return tokens.map(token => token.actor);\n }\n\n /* -------------------------------------------- */\n\n /**\n * Get status effect from actor based on the status ID.\n * @param {object} actor\n * @param {string} statusId\n * @returns {object} Status effect\n */\n static getStatusEffect(actor, statusId) {\n return actor.effects.find(effect => effect.statuses.every(status => status === statusId));\n }\n\n /* -------------------------------------------- */\n\n /**\n * Get image from the entity.\n * @public\n * @param {object} entity Actor, item\n * @param {Array} defaultImages List of default images to exclude\n * @returns {string} Image URL\n */\n static getImage(entity, defaultImages = []) {\n defaultImages.push(\"icons/svg/mystery-man.svg\");\n let result = \"\";\n if (game.tokenActionHud?.setting?.displayIcons) {\n result = (typeof entity === \"string\")\n ? entity\n : entity?.img ?? entity?.icon ?? \"\";\n }\n return !defaultImages.includes(result) ? result : \"\";\n }\n\n /* -------------------------------------------- */\n\n /**\n * Get item from the actor.\n * @public\n * @param {object} actor\n * @param {string} itemId\n * @returns {object} Item\n */\n static getItem(actor, itemId) {\n return actor.items.get(itemId);\n }\n\n /* -------------------------------------------- */\n\n /**\n * Get token.\n * @public\n * @param {string} tokenId\n * @returns {object} Token\n */\n static getToken(tokenId) {\n return canvas.tokens.placeables.find(token => token.id === tokenId);\n }\n\n /* -------------------------------------------- */\n\n /**\n * Get controlled tokens.\n * @public\n * @returns {Array} List of controlled tokens\n */\n static getControlledTokens() {\n return game.canvas.tokens?.controlled ?? [];\n }\n\n /* -------------------------------------------- */\n\n /**\n * Get first controlled tokens.\n * @public\n * @returns {object|null} First controlled token\n */\n static getFirstControlledToken() {\n const controlledToken = game.canvas.tokens.controlled[0];\n if (controlledToken) {\n return controlledToken;\n }\n\n const character = game.user?.character;\n if (character) {\n return canvas.tokens.placeables.find(token => token.actor?.id === character.id);\n }\n\n return null;\n }\n\n /* -------------------------------------------- */\n /* SETTINGS / FLAGS */\n /* -------------------------------------------- */\n\n /**\n * Get setting value.\n * @public\n * @param {string} key Setting key\n * @param {string=null} defaultValue Setting default value\n * @returns {*} Setting value\n */\n static getSetting(key, defaultValue = null) {\n let value = defaultValue ?? null;\n try {\n value = game.settings.get(MODULE.ID, key);\n } catch{\n Logger.debug(`Setting '${key}' not found`);\n }\n return value;\n }\n\n /* -------------------------------------------- */\n\n /**\n * Set setting value.\n * @public\n * @param {string} key Setting key\n * @param {string} value Setting value\n */\n static async setSetting(key, value) {\n if (game.settings.settings.get(`${MODULE.ID}.${key}`)) {\n await game.settings.set(MODULE.ID, key, value);\n Logger.debug(`Setting '${key}' set to '${value}'`);\n } else if (key !== \"debug\") {\n Logger.debug(`Setting '${key}' not found`);\n }\n }\n\n /* -------------------------------------------- */\n\n /**\n * Get module actor flag.\n * @public\n * @param {string} key Flag key\n * @returns {*} Flag value\n */\n static getActorFlag(key) {\n return game.tokenActionHud.actor.getFlag(MODULE.ID, key);\n }\n\n /* -------------------------------------------- */\n\n /**\n * Set module actor flag.\n * @public\n * @param {string} key Flag key\n * @param {*} value Flag value\n */\n static async setActorFlag(key, value) {\n await game.tokenActionHud.actor.setFlag(MODULE.ID, key, value);\n }\n\n /* -------------------------------------------- */\n\n /**\n * Unset module actor flag.\n * @public\n * @param {string} key Flag key\n */\n static async unsetActorFlag(key) {\n await game.tokenActionHud.actor.unsetFlag(MODULE.ID, key);\n }\n\n /* -------------------------------------------- */\n\n /**\n * Get module user flag.\n * @public\n * @param {string} key Flag key\n * @returns {*} Flag value\n */\n static getUserFlag(key) {\n return game.user.getFlag(MODULE.ID, key);\n }\n\n /* -------------------------------------------- */\n\n /**\n * Set module user flag.\n * @public\n * @param {string} key Flag key\n * @param {*} value Flag value\n */\n static async setUserFlag(key, value) {\n await game.user.setFlag(MODULE.ID, key, value);\n }\n\n /* -------------------------------------------- */\n\n /**\n * Unset module user flag.\n * @public\n * @param {string} key Flag key\n */\n static async unsetUserFlag(key) {\n await game.user.unsetFlag(MODULE.ID, key);\n }\n\n /* -------------------------------------------- */\n /* ENVIRONMENT */\n /* -------------------------------------------- */\n\n /**\n * Language translation.\n * @public\n * @param {string} toTranslate Value to translate\n * @returns {string} Translated value\n */\n static i18n(toTranslate) {\n return game.i18n.localize(toTranslate);\n }\n\n /* -------------------------------------------- */\n\n /**\n * Whether a GM is active.\n * @public\n * @returns {boolean} Whether a GM is active\n */\n static isGmActive() {\n return game.users.some(user => user.isGM && user.active);\n }\n\n /* -------------------------------------------- */\n\n /**\n * Whether the given module is active.\n * @public\n * @param {string} moduleId\n * @returns {boolean} Whether the given module is active\n */\n static isModuleActive(moduleId) {\n const module = game.modules.get(moduleId);\n return module && module.active;\n }\n\n /* -------------------------------------------- */\n\n /**\n * Get the given module's title.\n * @public\n * @param {string} moduleId\n * @returns {string} Module title\n */\n static getModuleTitle(moduleId) {\n return game.modules.get(moduleId)?.title ?? \"\";\n }\n\n /* -------------------------------------------- */\n\n /**\n * Get the given module's version.\n * @public\n * @param {string} moduleId\n * @returns {string} Module version\n */\n static getModuleVersion(moduleId) {\n return game.modules.get(moduleId)?.version ?? \"\";\n }\n\n /* -------------------------------------------- */\n\n /**\n * Humanize keybinding.\n * @param {object} key Keybinding key\n * @returns {string} Humanized keybinding\n */\n static humanizeBinding(key) {\n const keyboardManager = foundry?.helpers?.interaction?.KeyboardManager ?? KeyboardManager;\n const binding = game.keybindings.get(MODULE.ID, key);\n if (!binding) return \"\";\n const stringParts = binding[0].modifiers.reduce((parts, part) => {\n if (keyboardManager.MODIFIER_CODES[part]?.includes(binding[0].key)) return parts;\n parts.unshift(keyboardManager.getKeycodeDisplayString(part));\n return parts;\n }, [keyboardManager.getKeycodeDisplayString(binding[0].key)]);\n return stringParts.join(\" + \");\n }\n\n /* -------------------------------------------- */\n /* MATHS */\n /* -------------------------------------------- */\n\n /**\n * Get the median.\n * @public\n * @param {Array} numbers List of numbers\n * @returns {number} Median\n */\n static median(numbers) {\n const mid = Math.floor(numbers.length / 2);\n const nums = [...numbers].sort((a, b) => a - b);\n return numbers.length % 2 !== 0 ? nums[mid] : (nums[mid - 1] + nums[mid]) / 2;\n }\n\n /* -------------------------------------------- */\n\n /**\n * Get upper quartile average.\n * @param {Array} numbers List of numbers\n * @returns {number} Upper quartile average\n */\n static getUpperQuartileAverage(numbers) {\n const sortedNumbers = numbers.slice().sort((a, b) => a - b);\n const length = sortedNumbers.length;\n const startIndex = Math.ceil(length * 0.75);\n const endIndex = length - 1;\n\n let sum = 0;\n let count = 0;\n\n for (let i = startIndex; i <= endIndex; i++) {\n sum += sortedNumbers[i];\n count++;\n }\n\n const upperQuartileAverage = sum / count;\n\n return upperQuartileAverage;\n }\n\n /* -------------------------------------------- */\n\n /**\n * Get modifier (e.g., +5) from number.\n * @param {number} num\n * @returns {string} Modifier\n */\n static getModifier(num) {\n if (!num && num !== 0) return \"\";\n const sign = (num >= 0) ? \"+\" : \"\";\n return `${sign}${num}`;\n }\n\n /* -------------------------------------------- */\n /* SORTING */\n /* -------------------------------------------- */\n\n /**\n * Sort items.\n * @public\n * @param {object} items\n * @returns {object} Sorted items\n */\n static sortItems(items) {\n return new Map([...items.entries()].sort((a, b) => a[1].sort.localeCompare(b[1].sort)));\n }\n\n /* -------------------------------------------- */\n\n /**\n * Sort items by name.\n * @public\n * @param {object} items\n * @returns {object} Sorted items\n */\n static sortItemsByName(items) {\n return new Map([...items.entries()].sort((a, b) => a[1].name.localeCompare(b[1].name)));\n }\n\n /* -------------------------------------------- */\n /* CSS */\n /* -------------------------------------------- */\n\n /**\n * Enable stylesheet based on setting and disable all other stylesheets.\n * @public\n * @param {string} style Style setting value\n */\n static switchCSS(style) {\n const tahElement = document.querySelector(\"#token-action-hud-app\");\n if (tahElement) {\n if (!CSS_STYLE[style]) style = \"foundryVTT\";\n const styleClass = foundry.utils.isNewerVersion(game.version, \"12.999\") && [\"dockedLeft\", \"dockedCenterRight\", \"dockedRight\"].includes(style)\n ? `${CSS_STYLE[style].class}-v13`\n : CSS_STYLE[style].class;\n\n if (tahElement.classList.contains(styleClass)) return;\n\n const PRESERVE = new Set([\"tah-expanded\", \"faded-ui\"]);\n const classesToRemove = [...tahElement.classList].filter(c => !PRESERVE.has(c));\n if (classesToRemove.length) tahElement.classList.remove(classesToRemove);\n tahElement.classList.add(styleClass);\n\n if (style === \"custom\") {\n Utils.applyCustomStyles(tahElement);\n } else {\n Utils.removeCustomStyles(tahElement);\n }\n }\n }\n\n /* -------------------------------------------- */\n\n /**\n * Apply saved custom style CSS properties to the HUD element.\n * @public\n * @param {HTMLElement} element HUD element\n */\n static applyCustomStyles(element) {\n for (const [key, value] of Object.entries(CUSTOM_STYLE)) {\n const saved = Utils.getSetting(key);\n if (saved != null) {\n element.style.setProperty(value.cssProperty, saved);\n }\n }\n }\n\n /* -------------------------------------------- */\n\n /**\n * Remove custom style CSS properties from the HUD element.\n * @public\n * @param {HTMLElement} element HUD element\n */\n static removeCustomStyles(element) {\n for (const value of Object.values(CUSTOM_STYLE)) {\n element.style.removeProperty(value.cssProperty);\n }\n }\n\n /* -------------------------------------------- */\n /* HANDLEBARS */\n /* -------------------------------------------- */\n\n /**\n * Register Handlebar helpers.\n * @public\n */\n static registerHandlebars() {\n // Capitalise first character\n Handlebars.registerHelper(\"tokenActionHudCoreCap\", function(string) {\n if (!string || string.length < 1) return \"\";\n return string[0].toUpperCase() + string.slice(1);\n });\n const reduceOp = function(args, reducer) {\n args = Array.from(args);\n args.pop(); // => options\n const first = args.shift();\n return args.reduce(reducer, first);\n };\n\n // Support operators\n Handlebars.registerHelper({\n tokenActionHudCoreTrue: function() { return reduceOp(arguments, a => a); }\n });\n\n // Add asterisk to toggleable actions\n Handlebars.registerHelper(\"tokenActionHudCoreActiveText\", function(block) {\n if (game.tokenActionHud?.setting?.activeCssAsText) {\n return block.fn(this);\n }\n return block.inverse(this);\n });\n }\n\n /* -------------------------------------------- */\n /* VERSIONING */\n /* -------------------------------------------- */\n\n /**\n * Get the major, minor and patch parts of the module version.\n * @public\n * @param {string} moduleVersion\n * @returns {object|null} Module version parts\n */\n static getModuleVersionParts(moduleVersion) {\n if (!moduleVersion) {\n Logger.debug(\"Module version not retrieved\", { trigger: \"getModuleVersionParts\" });\n return null;\n }\n const moduleVersionParts = moduleVersion.split(\".\");\n return {\n major: moduleVersionParts[0],\n minor: moduleVersionParts[1],\n patch: moduleVersionParts[2]\n };\n }\n\n /* -------------------------------------------- */\n\n /**\n * Whether the system module is compatible with the core module version.\n * @public\n * @param {string} requiredCoreModuleVersion\n * @returns {boolean} Whether the system module is compatible with the core module version\n */\n static isSystemModuleCompatible(requiredCoreModuleVersion) {\n if (!requiredCoreModuleVersion) return true;\n\n // Get core module version in parts\n const requiredCoreModuleVersionParts = this.getModuleVersionParts(requiredCoreModuleVersion);\n const coreModuleVersionParts = this.getModuleVersionParts(game.modules.get(MODULE.ID).version);\n\n if (coreModuleVersionParts.major !== requiredCoreModuleVersionParts.major\n || (requiredCoreModuleVersionParts.minor && coreModuleVersionParts.minor !== requiredCoreModuleVersionParts.minor)\n || (requiredCoreModuleVersionParts.patch && coreModuleVersionParts.patch !== requiredCoreModuleVersionParts.patch)\n ) {\n const requiredVersion = `${requiredCoreModuleVersionParts.major}.${requiredCoreModuleVersionParts.minor ?? \"X\"}.${requiredCoreModuleVersionParts.patch ?? \"X\"}`;\n const installedVersion = game.modules.get(MODULE.ID).version;\n ui.notifications.error(\n `The installed Token Action HUD system module requires Token Action HUD Core module version ${requiredVersion}, but version ${installedVersion} is installed. Install Token Action HUD Core module version ${requiredVersion} to continue using Token Action HUD. Earlier versions of Token Action HUD Core are available on the module's package page on the Foundry VTT site.`,\n { permanent: true }\n );\n return false;\n }\n return true;\n }\n\n /* -------------------------------------------- */\n /* GROUP TRAVERSAL */\n /* -------------------------------------------- */\n\n /**\n * Get nested groups by criteria.\n * @public\n * @param {object} groups\n * @param {object} data Search data\n * @returns {object|null} Nested groups\n */\n static getNestedGroups(groups, data = {}) {\n let order = 0;\n if (!groups) return null;\n const groupId = data?.id;\n const groupType = data?.type;\n groups = (Array.isArray(groups)) ? groups : Object.values(groups);\n const foundGroups = {};\n for (const group of groups) {\n if ((!groupId || group.id === groupId) && (!groupType || group.type === groupType)) {\n order++;\n const level = group.nestId.split(\"_\").length;\n foundGroups[group.nestId] = { ...group, order, level };\n }\n if (group.groups?.length > 0) {\n const groups = this.getNestedGroups(group.groups, data);\n if (groups) Object.assign(foundGroups, groups);\n }\n }\n return (Object.keys(foundGroups).length > 0) ? foundGroups : null;\n }\n\n /* -------------------------------------------- */\n\n /**\n * Get group by nest ID.\n * @public\n * @param {object} groups\n * @param {string} data Search data\n * @returns {object|null} Group\n */\n static async getGroupByNestId(groups, data = {}) {\n const nestId = (typeof data === \"string\" ? data : data?.nestId);\n const groupType = data?.type;\n if (!nestId) return null;\n\n const parts = nestId.split(\"_\");\n return await findGroup(groups, parts);\n\n /* -------------------------------------------- */\n\n /**\n * Find group.\n * @param {object} groups\n * @param {Array} parts nestId parts\n * @returns {object} Group\n */\n async function findGroup(groups, parts) {\n if (!groups) return null;\n groups = (Array.isArray(groups)) ? groups : Object.values(groups);\n for (const group of groups) {\n if (group.id === parts[0]) {\n if (parts.length === 1) {\n if (!group.type || !groupType || group.type === groupType) return group;\n return;\n }\n parts.shift();\n if (!group.groups) continue;\n for (const groupStyle of Object.values(group.groups)) {\n if (groupStyle.length === 0) continue;\n const foundGroup = await findGroup(groupStyle, parts);\n if (foundGroup) return foundGroup;\n }\n }\n }\n }\n }\n\n /* -------------------------------------------- */\n\n /**\n * Delete group by nest ID.\n * @public\n * @param {object} groups\n * @param {string} data Search data\n */\n static async deleteGroupByNestId(groups, data = {}) {\n const nestId = (typeof data === \"string\" ? data : data?.nestId);\n if (!nestId) return;\n\n const parts = nestId.split(\"_\");\n await findAndDeleteGroup(groups, parts);\n }\n\n /* -------------------------------------------- */\n\n /**\n * Find and delete a group.\n * @param {object} groups\n * @param {Array} parts nestId parts\n */\n static async findAndDeleteGroup(groups, parts) {\n groups = (Array.isArray(groups)) ? groups : Object.values(groups);\n for (const [index, group] of groups.entries()) {\n if (group.id === parts[0]) {\n if (parts.length === 1) {\n groups.splice(index, 1);\n return;\n }\n if (group.groups.length === 0) return;\n parts.shift();\n const foundGroup = await findAndDeleteGroup(group.groups, parts);\n if (foundGroup) return;\n }\n }\n }\n\n /* -------------------------------------------- */\n\n /**\n * Delete groups by ID\n * @public\n * @param {object} groups\n * @param {string} data Search data\n */\n static async deleteGroupsById(groups, data = {}) {\n const id = (typeof data === \"string\" ? data : data?.id);\n if (!id) return;\n\n for (let i = groups.length - 1; i >= 0; i--) {\n if (groups[i].id === id) {\n groups.splice(i, 1);\n } else if (groups[i].groups?.length > 0) {\n deleteGroupsById(groups[i].groups, data);\n }\n }\n }\n}\n","import { MODULE } from \"../core/constants.mjs\";\nimport { Logger, Utils } from \"../core/utils.mjs\";\n\n/* -------------------------------------------- */\n\nconst filePicker = foundry?.applications?.apps?.FilePicker?.implementation ?? FilePicker;\n\n/**\n * A class responsible for handling data-related activities.\n */\nexport class DataHandler {\n constructor(socket) {\n this.socket = socket;\n }\n\n /* -------------------------------------------- */\n /* INITIALISE */\n /* -------------------------------------------- */\n\n /**\n * Initialise the data handler.\n */\n async init() {\n await this.#createDirectories();\n await Promise.all([\n this.private = await this.isPrivate(),\n this.fileMap = await this.getFilePathsAsGm()\n ]);\n }\n\n /* -------------------------------------------- */\n\n /**\n * Whether persistent storage can be used.\n * @returns {boolean} Whether persistent storage can be used\n */\n get isPersistentStorage() {\n return (foundry.utils.isNewerVersion(game.version, \"11.305\") && typeof ForgeVTT === \"undefined\");\n }\n\n /* -------------------------------------------- */\n\n /**\n * Create directories for storage of files.\n * @private\n */\n async #createDirectories() {\n if (!game.user.isGM || !Utils.getSetting(\"enableCustomization\")) return;\n\n const DATA_FOLDER = \"data\";\n const moduleDirectory = (this.isPersistentStorage)\n ? `modules/${MODULE.ID}/storage`\n : MODULE.ID;\n\n const directoriesToCreate = [\n moduleDirectory,\n `${moduleDirectory}/${game.world.id}`,\n `${moduleDirectory}/${game.world.id}/actor`,\n `${moduleDirectory}/${game.world.id}/user`\n ];\n\n for (const directory of directoriesToCreate) {\n await filePicker.browse(DATA_FOLDER, directory).catch(async _ => {\n if (!(await filePicker.createDirectory(DATA_FOLDER, directory, {}))) {\n Logger.debug(`Failed to create directory: ${directory}`);\n }\n });\n }\n }\n\n /* -------------------------------------------- */\n /* PATHS */\n /* -------------------------------------------- */\n\n /**\n * Get base path to the layout files.\n * @returns {string} Storage path\n */\n get path() {\n return (this.isPersistentStorage)\n ? `modules/${MODULE.ID}/storage/${game.world.id}/`\n : `${MODULE.ID}/${game.world.id}/`;\n }\n\n /* -------------------------------------------- */\n\n /**\n * Get file parts.\n * @param {string} file\n * @returns {object} File parts\n */\n getFileParts(file) {\n const parts = file.split(\"/\");\n const filename = parts.pop();\n const folder = parts.join(\"/\");\n const id = filename.split(\".\")[0];\n return { folder, filename, id };\n }\n\n /* -------------------------------------------- */\n\n /**\n * Whether the module directory is set to private.\n * @returns {boolean} Whether the module directory is set to private\n */\n async isPrivate() {\n if (game.user.isGM) return false;\n\n if (game.user.hasPermission(\"FILES_BROWSE\")) {\n try {\n await filePicker.browse(\"data\", this.path);\n return false;\n } catch{\n return true;\n }\n }\n return true;\n }\n\n /* -------------------------------------------- */\n\n /**\n * Get file paths as GM.\n * @returns {object} File paths\n */\n async getFilePathsAsGm() {\n if ((!game.user.hasPermission(\"FILES_BROWSE\") || this.private) && !Utils.isGmActive()) {\n Logger.info(\"Cannot get file paths without a GM present\", false);\n return new Map(); // Return an empty map if no permissions and no GM\n }\n\n const files = game.user.hasPermission(\"FILES_BROWSE\") && !this.private\n ? await this.getFilePaths()\n : await this.socket.executeAsGM(\"getFilePaths\");\n\n return new Map(files.map(file => {\n const { id } = this.getFileParts(file);\n return [id, file];\n }));\n }\n\n /**\n * Get file paths using socket.\n * @returns {Array} File paths\n */\n static async getFilePathsWithSocket() {\n return await game.tokenActionHud?.dataHandler?.getFilePaths() ?? [];\n }\n\n /* -------------------------------------------- */\n\n /**\n * Get file paths.\n * @returns {Array} File paths\n */\n async getFilePaths() {\n const [actorFiles, userFiles] = await Promise.all([\n filePicker.browse(\"data\", `${this.path}actor/`),\n filePicker.browse(\"data\", `${this.path}user/`)\n ]);\n\n return [...(actorFiles?.files ?? []), ...(userFiles?.files ?? [])];\n }\n\n /* -------------------------------------------- */\n /* SAVE DATA */\n /* -------------------------------------------- */\n\n /**\n * Whether the user can save data.\n * @returns {boolean} Whether the user can save data\n */\n get canSaveData() {\n return ((game.user.hasPermission(\"FILES_UPLOAD\") && !this.private) || Utils.isGmActive());\n }\n\n /* -------------------------------------------- */\n\n /**\n * Save data the GM.\n * @public\n * @param {string} type Actor or user\n * @param {string} id Actor or user ID\n * @param {object} data Data to save\n */\n async saveDataAsGm(type, id, data) {\n if (game.user.hasPermission(\"FILES_UPLOAD\") && !this.private) {\n await this.saveData(type, id, data);\n }\n\n if (!Utils.isGmActive()) {\n Logger.info(\"Cannot save data without a GM present\", false);\n return;\n }\n\n await this.socket.executeAsGM(\"saveData\", type, id, data);\n }\n\n /* -------------------------------------------- */\n\n static async saveDataWithSocket(type, id, data) {\n return await game.tokenActionHud.dataHandler.saveData(type, id, data);\n }\n\n /* -------------------------------------------- */\n\n /**\n * Save data.\n * @param {string} type Actor or user\n * @param {string} id Actor or user ID\n * @param {object} data Data to save\n */\n async saveData(type, id, data) {\n try {\n // Get the folder path\n const folder = `${this.path}${type}`;\n\n // Generate the system-safe filename\n const fileName = encodeURI(`${id}.json`);\n\n // Create the file and contents\n const file = new File([JSON.stringify(data, null, \"\")], fileName, { type: \"application/json\" });\n\n // Upload the file\n const response = await filePicker.upload(\"data\", folder, file, {}, { notify: false });\n\n if (response.path) {\n if (!this.fileMap.has(id)) {\n this.fileMap.set(id, response.path);\n }\n } else {\n Logger.debug(`Failed to save data to: ${fileName}\\nReason: ${response.error || \"Unknown error\"}`);\n }\n } catch(error) {\n Logger.error(`An error occurred while saving data for ${id}.json: ${error.message}`);\n }\n }\n\n /* -------------------------------------------- */\n /* GET DATA */\n /* -------------------------------------------- */\n\n /**\n * Whether the user can get data.\n * @returns {boolean} Whether the user can get data\n */\n get canGetData() {\n return ((game.user.hasPermission(\"FILES_BROWSE\") && !this.private) || Utils.isGmActive());\n }\n\n /* -------------------------------------------- */\n\n /**\n * Get data as GM.\n * @public\n * @param {object} options { file, type, id }\n * @returns {object} Retrieved data\n */\n async getDataAsGm(options) {\n try {\n if ((!game.user.hasPermission(\"FILES_BROWSE\") || this.private) && !Utils.isGmActive()) {\n Logger.info(\"Cannot get data without a GM present\", false);\n return;\n }\n\n const data = (game.user.hasPermission(\"FILES_BROWSE\"))\n ? await this.getData(options)\n : await this.socket.executeAsGM(\"getData\", options);\n\n return data;\n } catch(error) {\n Logger.error(`An error occurred while getting data: ${error.message}`);\n return null;\n }\n }\n\n /* -------------------------------------------- */\n\n static async getDataWithSocket(options) {\n return await game.tokenActionHud.dataHandler.getData(options);\n }\n\n /* -------------------------------------------- */\n\n /**\n * Get data.\n * @param {string} options { file, type, id }\n * @returns {object} Retrieved data\n */\n async getData(options) {\n const { id, file } = options;\n\n // Check if the file is available in the fileMap\n let foundFile = this.fileMap.get(id) ?? null;\n\n // If not found, try to browse, otherwise return null\n if (!foundFile) {\n if (!file) return null;\n const { folder, filename } = this.getFileParts(file);\n const foundFolder = await filePicker.browse(\"data\", folder);\n foundFile = foundFolder.files.find(file => file.endsWith(filename));\n if (!foundFile) return null;\n }\n\n try {\n const ms = Date.now();\n const response = await fetch(`${foundFile}?ms=${ms}`);\n\n // Check if the fetch was successful\n if (!response.ok) return null;\n\n const text = await response.text();\n if (!text) return null;\n return JSON.parse(text);\n } catch(error) {\n console.error(error);\n return null;\n }\n }\n\n /* -------------------------------------------- */\n\n /**\n * Get data.\n * @param {string} type Actor or user\n * @param {string} id Actor or user ID\n * @returns {object} Retrieved data\n */\n async getDataMigrate(type, id) {\n const folderPath = `${MODULE.ID}/${game.world.id}/${type}`;\n const fileName = encodeURI(`${id}.json`);\n try {\n const foundFolderPath = await filePicker.browse(\"data\", folderPath);\n const foundFilePath = foundFolderPath.files.find(file => file.endsWith(fileName));\n if (foundFilePath) {\n const ms = Date.now();\n return await fetch(`${foundFilePath}?ms=${ms}`)\n .then(response => {\n if (response.ok) {\n return response.json();\n } else {\n return null;\n }\n })\n .catch(error => {\n console.error(error);\n });\n } else {\n return null;\n }\n } catch{\n return null;\n }\n }\n}\n","import { MODULE } from \"../core/constants.mjs\";\nimport { Logger, Utils } from \"../core/utils.mjs\";\n\n/**\n * Manages migrations between module versions.\n */\nexport class MigrationManager {\n constructor(dataHandler, socket) {\n this.dataHandler = dataHandler;\n this.socket = socket;\n }\n\n /* -------------------------------------------- */\n\n /**\n * Initialise migrations.\n * @public\n */\n async init() {\n if (!game.user.isGM) return;\n\n const moduleVersion = game.modules.get(MODULE.ID).version;\n const migrationVersion = Utils.getSetting(\"migrationVersion\");\n if (moduleVersion === migrationVersion) return;\n\n let isSuccess = true;\n isSuccess = (!migrationVersion || foundry.utils.isNewerVersion(\"1.4.10\", migrationVersion))\n ? await this.#unsetOldFlags()\n : true;\n isSuccess = (this.dataHandler.isPersistentStorage && (!migrationVersion || foundry.utils.isNewerVersion(\"1.4.11\", migrationVersion)))\n ? await this.#migrateFiles()\n : true;\n\n if (isSuccess) {\n Utils.setSetting(\"migrationVersion\", moduleVersion);\n }\n }\n\n /* -------------------------------------------- */\n\n /**\n * Unset old flags.\n * @private\n * @returns {boolean} Whether the old flags were unset\n */\n async #unsetOldFlags() {\n try {\n const users = game.users.filter(user => user.getFlag(MODULE.ID, \"categories\"));\n for (const user of users) {\n user.unsetFlag(MODULE.ID, \"categories\");\n user.unsetFlag(MODULE.ID, \"defaults\");\n }\n\n const actors = game.actors.filter(actor => actor.getFlag(MODULE.ID, \"categories\"));\n for (const actor of actors) {\n actor.unsetFlag(MODULE.ID, \"categories\");\n }\n\n const tokens = game.canvas.tokens.objects.children.filter(token => token.actor?.getFlag(MODULE.ID, \"categories\"));\n for (const token of tokens) {\n token.actor?.unsetFlag(MODULE.ID, \"categories\");\n }\n\n for (const scene of game.scenes) {\n const tokens = scene.tokens.filter(token => token.actor?.getFlag(MODULE.ID, \"categories\"));\n for (const token of tokens) {\n token.actor?.unsetFlag(MODULE.ID, \"categories\");\n }\n }\n\n return true;\n } catch(err) {\n Logger.debug(err.message, err);\n\n return false;\n }\n }\n\n /* -------------------------------------------- */\n\n /**\n * Migrate files to storage.\n * @returns {boolean} Whether the files were migrated to storage\n */\n async #migrateFiles() {\n try {\n Logger.info(\"Migrating files to persistent storage...\", true);\n for (const user of game.users) {\n const data = await this.dataHandler.getDataMigrate(\"user\", user.id);\n if (data) {\n await this.dataHandler.saveData(\"user\", user.id, data);\n }\n }\n\n for (const actor of game.actors) {\n const data = await this.dataHandler.getDataMigrate(\"actor\", actor.id);\n if (data) {\n await this.dataHandler.saveData(\"actor\", actor.id, data);\n }\n }\n Logger.info(\"Successfully migrated files to persistent storage\", true);\n return true;\n } catch{\n Logger.info(\"Failed to migrate files to persistent storage\", true);\n return false;\n }\n }\n}\n","import { Utils } from \"../core/utils.mjs\";\n\nexport class CharacterHandler {\n constructor(hudManager) {\n this.hudManager = hudManager;\n this.groupHandler = hudManager.groupHandler;\n this.actionHandler = hudManager.actionHandler;\n this.rollHandler = hudManager.rollHandler;\n }\n\n /**\n * Initialise Character Handler.\n */\n init() {\n this.previousActorId = this.actor?.id;\n this.setCharacter();\n }\n\n /* -------------------------------------------- */\n\n /**\n * Whether there is a character.\n * @returns {boolean} Whether there is a character\n */\n get isCharacter() {\n return this.actor || this.isMultipleTokens;\n }\n\n /* -------------------------------------------- */\n\n /**\n * Whether there is multiple tokens.\n * @returns {boolean} Whether there is multiple tokens\n */\n get isMultipleTokens() {\n const controlledTokens = Utils.getControlledTokens();\n return controlledTokens.length > 1 && !this.actor;\n }\n\n /* -------------------------------------------- */\n\n /**\n * Whether the current actor is the same actor.\n * @returns {boolean} Whether the current actor is the same actor\n */\n get isSameActor() {\n return this.previousActorId !== this.actor?.id;\n }\n\n /* -------------------------------------------- */\n\n /**\n * Set character based on controlled tokens.\n * @private\n */\n setCharacter() {\n this.resetCharacter();\n const controlledTokens = Utils.getControlledTokens();\n if (controlledTokens.length > 1) {\n this.#handleMultipleTokens(controlledTokens);\n } else {\n this.#handleSingleToken(controlledTokens);\n }\n }\n\n /* -------------------------------------------- */\n\n /**\n * Reset actor and token properties.\n */\n resetCharacter() {\n this.token = null;\n this.actor = null;\n this.tokens = [];\n this.actors = [];\n }\n\n /* -------------------------------------------- */\n\n /**\n * Handle multiple controlled tokens.\n * @param {Array} controlledTokens List of controlled tokens\n */\n #handleMultipleTokens(controlledTokens) {\n this.characterName = game.i18n.localize(\"tokenActionHud.multiple\");\n\n // Empty singulars\n this.token = null;\n this.actor = null;\n\n // Set multiples\n this.tokens = controlledTokens;\n this.actors = Utils.getControlledActors();\n }\n\n /* -------------------------------------------- */\n\n /**\n * Handle a single controlled token.\n * @private\n * @param {Array} controlledTokens List of controlled tokens\n */\n #handleSingleToken(controlledTokens) {\n const character = { token: null, actor: null };\n\n if (controlledTokens.length === 1 && this.#isValidCharacter(controlledTokens[0])) {\n character.token = controlledTokens[0];\n character.actor = character.token?.actor;\n } else if (controlledTokens.length === 0 && game.user.character && Utils.getSetting(\"alwaysShowHud\")) {\n character.actor = game.user.character;\n character.token = canvas.tokens?.placeables.find(t => t.actor?.id === character.actor.id) ?? null;\n }\n\n if (!character.actor) return;\n\n this.characterName = character.token?.name ?? character.actor.name;\n\n // Set in this class\n this.token = character.token;\n this.actor = character.actor;\n this.tokens = [character.token];\n this.actors = [character.actor];\n }\n\n /* -------------------------------------------- */\n\n /**\n * Whether the character is a valid selection for the current user,\n * @private\n * @param {object} [token = {}]\n * @returns {boolean} Whether the character is a valid selection for the current user\n */\n #isValidCharacter(token = {}) {\n return game.user.isGM || token.actor?.testUserPermission(game.user, \"OWNER\");\n }\n\n}\n","import { Utils } from \"../core/utils.mjs\";\n\n/**\n * Handler for the HUD layout.\n */\nexport class LayoutHandler {\n constructor(systemManager, dataHandler) {\n this.systemManager = systemManager;\n this.dataHandler = dataHandler;\n this.defaultLayout = null;\n this.customLayout = null;\n }\n\n /* -------------------------------------------- */\n /* INITIALISE */\n /* -------------------------------------------- */\n\n /**\n * Initialise the HUD layout.\n */\n async init() {\n await Promise.all([\n this.#setDefaultLayout(),\n this.#setCustomLayout()\n ]);\n }\n\n /* -------------------------------------------- */\n\n /**\n * Set the default layout.\n * @private\n */\n async #setDefaultLayout() {\n if (this.defaultLayout) return;\n const defaultLayout = this.systemManager.defaults?.layout;\n if (!defaultLayout) { this.defaultLayout = null; return; }\n this.defaultLayout = await Utils.getNestedGroups(defaultLayout);\n }\n\n /* -------------------------------------------- */\n\n /**\n * Set custom layout.\n * @private\n */\n async #setCustomLayout() {\n if (this.customLayout) return;\n const file = Utils.getUserFlag(\"userCustomLayout\") || Utils.getSetting(\"customLayout\") || null;\n this.customLayout = (file) ? await this.dataHandler.getDataAsGm({ file }) : null;\n }\n\n /* -------------------------------------------- */\n /* RESET */\n /* -------------------------------------------- */\n\n /**\n * Soft reset variables.\n */\n softReset() {\n this.defaultLayout = null;\n }\n\n /* -------------------------------------------- */\n\n /**\n * Hard reset variables.\n */\n hardReset() {\n this.softReset();\n this.customLayout = null;\n }\n\n /* -------------------------------------------- */\n /* EXPORT */\n /* -------------------------------------------- */\n\n /**\n * Export layout to file.\n * @public\n */\n async exportLayout() {\n const data = await this.dataHandler.getDataAsGm({ type: \"user\", id: game.userId }) ?? this.customLayout ?? this.defaultLayout;\n if (data) {\n saveDataToFile(JSON.stringify(data, null, 2), \"text/json\", \"token-action-hud-layout.json\");\n }\n }\n\n /* -------------------------------------------- */\n /* STATE */\n /* -------------------------------------------- */\n\n /**\n * Get the layout.\n * @returns {object} The layout\n */\n get layout() {\n return this.customLayout ?? this.defaultLayout;\n }\n}\n","import { Utils } from \"../core/utils.mjs\";\n\n/**\n * Get tooltip based on module setting.\n * @param {object|string} tooltip\n * @param {string} name\n * @returns {object} Tooltip\n */\nexport function getTooltip(tooltip, name) {\n const setting = game.tokenActionHud?.setting?.tooltips ?? Utils.getSetting(\"tooltips\");\n\n if (setting === \"none\") return null;\n if (setting === \"nameOnly\" || !tooltip) return name;\n\n if (typeof tooltip !== \"object\") {\n tooltip = { content: tooltip };\n }\n\n if (!tooltip.content.includes(\"tah-tooltip-wrapper\")) {\n tooltip.content = `
${game.i18n.localize(\"tokenActionHud.dialog.resetLayout.content\")}
`,\n modal: true,\n yes: {\n label: game.i18n.localize(\"tokenActionHud.dialog.button.yes\"),\n callback: async () => resetLayout()\n },\n no: {\n label: game.i18n.localize(\"tokenActionHud.dialog.button.no\")\n }\n });\n}\n\n/* -------------------------------------------- */\n\n/**\n * Reset user layout.\n */\nasync function resetLayout() {\n if (!game?.tokenActionHud) return;\n\n const customLayoutElement = document.querySelector(\"#token-action-hud-core-settings input[name=customLayout]\");\n if (customLayoutElement) {\n await game.tokenActionHud.updateCachedSettings(\"customLayout\", customLayoutElement?.value ?? \"\");\n await Utils.setSetting(\"customLayout\", customLayoutElement?.value ?? \"\");\n }\n\n const userCustomLayoutElement = document.querySelector(\"#token-action-hud-core-settings input[name=userCustomLayout]\");\n if (userCustomLayoutElement) {\n await game.tokenActionHud.updateCachedSettings(\"userCustomLayout\", userCustomLayoutElement?.value ?? \"\");\n await Utils.setUserFlag(\"userCustomLayout\", userCustomLayoutElement?.value ?? \"\");\n }\n\n await game.tokenActionHud.resetLayout();\n Logger.info(\"Layout reset\", true);\n}\n","import { MODULE, TEMPLATE } from \"../core/constants.mjs\";\nimport { resetLayoutDialog } from \"../dialogs/reset-layout.mjs\";\n\nconst { ApplicationV2, HandlebarsApplicationMixin } = foundry.applications.api;\n\n/**\n * Base settings form for HUD / group / subgroup edit dialogs.\n */\nexport class FormApp extends HandlebarsApplicationMixin(ApplicationV2) {\n constructor(data) {\n super(data);\n this.content = data.content;\n this.submit = data.submit;\n this.options.window.title = data.title;\n }\n\n /* -------------------------------------------- */\n\n static DEFAULT_OPTIONS = {\n actions: {\n resetActions: FormApp.resetActions,\n resetLayout: FormApp.resetLayout\n },\n classes: [`${MODULE.ID}-app`, \"tah-dialog\", \"sheet\"],\n id: \"token-action-hud-dialog\",\n form: {\n closeOnSubmit: true,\n handler: FormApp.submit\n },\n position: {\n width: 540,\n height: \"auto\"\n },\n tag: \"form\",\n window: {\n minimizable: true,\n resizable: true\n }\n };\n\n /* -------------------------------------------- */\n\n async _prepareContext() {\n return this.content;\n }\n\n /* -------------------------------------------- */\n\n /**\n * Reset the actor's HUD data. Only used by the HUD dialog's Reset Actions button.\n * @private\n */\n static async resetActions() {\n await foundry.applications.api.DialogV2.confirm({\n window: {\n title: game.i18n.localize(\"tokenActionHud.dialog.resetActions.title\")\n },\n content: `${game.i18n.localize(\"tokenActionHud.dialog.resetActions.content\")}
`,\n modal: true,\n yes: {\n label: game.i18n.localize(\"tokenActionHud.dialog.button.yes\"),\n callback: async () => {\n await game.tokenActionHud.resetActorData();\n }\n },\n no: {\n label: game.i18n.localize(\"tokenActionHud.dialog.button.no\")\n }\n });\n }\n\n /* -------------------------------------------- */\n\n /**\n * Reset the user's HUD layout to the default. Only used by the HUD\n * dialog's Reset Layout button.\n * @private\n */\n static async resetLayout() {\n await resetLayoutDialog();\n }\n\n /* -------------------------------------------- */\n\n /**\n * Handle form submission.\n * @param {Event} event\n * @param {object} form\n * @param {object} formData\n */\n static async submit(event, form, formData) {\n await this.submit(formData.object);\n }\n}\n\n/* -------------------------------------------- */\n\nexport class HudFormApp extends FormApp {\n static DEFAULT_OPTIONS = {\n window: { icon: \"fa-solid fa-pen-to-square\" }\n };\n\n static PARTS = {\n form: {\n template: TEMPLATE.formHud\n }\n };\n}\n\n/* -------------------------------------------- */\n\nexport class GroupFormApp extends FormApp {\n static DEFAULT_OPTIONS = {\n window: { icon: \"fa-solid fa-layer-group\" }\n };\n\n static PARTS = {\n form: {\n template: TEMPLATE.formGroup\n }\n };\n}\n\n/* -------------------------------------------- */\n\nexport class SubgroupFormApp extends FormApp {\n static DEFAULT_OPTIONS = {\n window: { icon: \"fa-solid fa-list\" }\n };\n\n static PARTS = {\n form: {\n template: TEMPLATE.formSubgroup\n }\n };\n}\n","import { HudFormApp, GroupFormApp, SubgroupFormApp } from \"./form-app.mjs\";\nimport { Utils } from \"../core/utils.mjs\";\n\n/**\n * Opens settings forms for the HUD, groups, and subgroups, and performs\n * group/action deletion.\n */\nexport class FormAppHelper {\n /**\n * Show the HUD dialog\n * @public\n * @param {GroupHandler} groupHandler\n */\n static async openEditHudApp(groupHandler) {\n const grid = await Utils.getSetting(\"grid\");\n\n const dialogData = {\n title: game.i18n.localize(\"tokenActionHud.form.hud.hudTitle\"),\n content: { settings: { grid } },\n submit: async formData => {\n await Utils.setSetting(\"grid\", formData?.grid);\n Hooks.callAll(\"forceUpdateTokenActionHud\");\n }\n };\n\n new HudFormApp(dialogData).render(true);\n }\n\n /* -------------------------------------------- */\n\n /**\n * Show group dialog.\n * @public\n * @param {GroupHandler} groupHandler\n * @param {object} groupData\n */\n static async openEditGroupApp(groupHandler, groupData) {\n const { nestId, name } = groupData;\n const currentSettings = await groupHandler.getGroupSettings(groupData) ?? {};\n\n const dialogData = {\n title: `${game.i18n.localize(\"tokenActionHud.form.hud.groupTitle\")}: ${name}`,\n content: {\n settings: { ...currentSettings, name }\n },\n submit: async formData => {\n const group = groupHandler.getGroup({ nestId });\n if (!group) return;\n const newName = (formData?.name ?? \"\").trim();\n if (newName) {\n group.name = newName;\n group.listName = newName;\n }\n group.settings = {\n ...group.settings,\n characterCount: formData?.characterCount,\n customWidth: formData?.customWidth,\n grid: formData?.grid,\n image: formData?.image,\n showTitle: formData?.showTitle,\n sort: formData?.sort\n };\n await groupHandler.saveGroups({ saveActor: true, saveUser: true });\n Hooks.callAll(\"forceUpdateTokenActionHud\");\n }\n };\n\n new GroupFormApp(dialogData).render(true);\n }\n\n /* -------------------------------------------- */\n\n /**\n * Show dialog to add a new top-level group at a specific position.\n * @public\n * @param {GroupHandler} groupHandler\n * @param {number} position\n */\n static async openAddGroupApp(groupHandler, position) {\n const dialogData = {\n title: game.i18n.localize(\"tokenActionHud.form.newGroup.title\"),\n content: {\n settings: {\n name: \"\",\n showTitle: true,\n image: \"\",\n customWidth: null,\n grid: false,\n characterCount: null\n }\n },\n submit: async formData => {\n const name = (formData?.name ?? \"\").trim();\n if (!name) return;\n\n const baseId = name.slugify({ replacement: \"-\", strict: true }) || \"group\";\n const existingIds = new Set(\n Object.values(groupHandler.groups)\n .filter(g => g.level === 1)\n .map(g => g.id)\n );\n let id = baseId;\n let suffix = 2;\n while (existingIds.has(id)) id = `${baseId}-${suffix++}`;\n\n const selected = Object.values(groupHandler.groups)\n .filter(g => g.level === 1 && g.selected)\n .sort((a, b) => a.order - b.order)\n .map(g => ({ id: g.id, listName: g.listName, name: g.name, type: g.type }));\n const newGroup = { id, listName: name, name, type: \"custom\" };\n const insertAt = Math.max(0, Math.min(position, selected.length));\n selected.splice(insertAt, 0, newGroup);\n\n await groupHandler.updateGroups(selected, { level: 0 });\n\n const newGroupData = groupHandler.getGroup({ nestId: id });\n if (newGroupData) {\n newGroupData.settings = {\n characterCount: formData?.characterCount,\n customWidth: formData?.customWidth,\n grid: formData?.grid,\n image: formData?.image,\n showTitle: formData?.showTitle\n };\n }\n\n await groupHandler.saveGroups({ saveActor: true, saveUser: true });\n Hooks.callAll(\"forceUpdateTokenActionHud\");\n }\n };\n\n new GroupFormApp(dialogData).render(true);\n }\n\n /* -------------------------------------------- */\n\n /**\n * Show subgroup dialog.\n * @public\n * @param {GroupHandler} groupHandler\n * @param {ActionHandler} actionHandler\n * @param {object} groupData\n */\n static async openEditSubgroupApp(groupHandler, actionHandler, groupData) {\n const { nestId, name } = groupData;\n const currentSettings = await groupHandler.getGroupSettings(groupData) ?? {};\n\n const dialogData = {\n title: `${game.i18n.localize(\"tokenActionHud.form.hud.groupTitle\")}: ${name} `,\n content: {\n settings: { ...currentSettings, name }\n },\n submit: async formData => {\n const group = groupHandler.getGroup({ nestId });\n if (!group) return;\n const newName = (formData?.name ?? \"\").trim();\n if (newName) {\n group.name = newName;\n group.listName = newName;\n }\n group.settings = {\n ...group.settings,\n characterCount: formData?.characterCount,\n collapse: formData?.collapse,\n customWidth: formData?.customWidth,\n grid: formData?.grid,\n image: formData?.image,\n showTitle: formData?.showTitle,\n sort: formData?.sort,\n style: formData?._style\n };\n await groupHandler.saveGroups({ saveActor: true, saveUser: true });\n Hooks.callAll(\"forceUpdateTokenActionHud\");\n }\n };\n\n new SubgroupFormApp(dialogData).render(true);\n }\n\n /* -------------------------------------------- */\n\n /**\n * Delete a group or subgroup from the HUD.\n * @public\n * @param {GroupHandler} groupHandler\n * @param {object} groupData\n * @param {string} groupData.nestId\n * @param {number} groupData.level\n */\n static async deleteGroup(groupHandler, { nestId, level }) {\n if (level === 1) {\n const siblings = Object.values(groupHandler.groups)\n .filter(g => g.level === 1 && g.selected && g.nestId !== nestId)\n .sort((a, b) => a.order - b.order)\n .map(g => ({ id: g.id, listName: g.listName, name: g.name, type: g.type }));\n await groupHandler.updateGroups(siblings, { level: 0 });\n } else {\n const parentNestId = nestId.split(\"_\").slice(0, -1).join(\"_\");\n const parentGroupData = groupHandler.getGroup({ nestId: parentNestId });\n if (!parentGroupData) return;\n const allChildren = Object.values(groupHandler.groups)\n .filter(g => g.nestId.startsWith(`${parentNestId}_`) && g.level === level && g.selected && g.nestId !== nestId)\n .sort((a, b) => a.order - b.order);\n const lists = allChildren\n .filter(g => g.settings?.style !== \"tab\")\n .map(g => ({ id: g.id, listName: g.listName, name: g.name, type: g.type }));\n const tabs = allChildren\n .filter(g => g.settings?.style === \"tab\")\n .map(g => ({ id: g.id, listName: g.listName, name: g.name, type: g.type }));\n await groupHandler.updateGroups([...lists, ...tabs], parentGroupData);\n }\n\n const descendantPrefix = `${nestId}_`;\n for (const key of Object.keys(groupHandler.groups)) {\n if (key === nestId || key.startsWith(descendantPrefix)) {\n delete groupHandler.groups[key];\n }\n }\n\n await groupHandler.saveGroups({ saveActor: true, saveUser: true });\n Hooks.callAll(\"forceUpdateTokenActionHud\");\n }\n\n /* -------------------------------------------- */\n\n /**\n * Delete an action from a subgroup.\n * @public\n * @param {GroupHandler} groupHandler\n * @param {ActionHandler} actionHandler\n * @param {object} data\n * @param {string} data.nestId\n * @param {string} data.actionId\n */\n static async deleteAction(groupHandler, actionHandler, { nestId, actionId }) {\n const group = groupHandler.getGroup({ nestId });\n if (!group) return;\n const remaining = group.actions\n .filter(a => a.selected && a.id !== actionId)\n .map(a => ({ id: a.id, listName: a.listName, name: a.name, type: a.type }));\n actionHandler.updateActions(remaining, { nestId });\n await groupHandler.saveGroups({ saveActor: true, saveUser: true });\n Hooks.callAll(\"forceUpdateTokenActionHud\");\n }\n}\n","import { MODULE, TEMPLATE } from \"../core/constants.mjs\";\n\nconst { ApplicationV2, HandlebarsApplicationMixin } = foundry.applications.api;\n\n/**\n * Popover to add a single subgroup.\n */\nexport class AddSubgroupApp extends HandlebarsApplicationMixin(ApplicationV2) {\n static DEFAULT_OPTIONS = {\n classes: [`${MODULE.ID}-app`, \"tah-add-popover-app\"],\n id: \"token-action-hud-popover\",\n window: { frame: false }\n };\n\n static PARTS = {\n form: { template: TEMPLATE.addPopover }\n };\n\n constructor({ available, onSelect, anchorRect }) {\n super();\n this.available = available;\n this.onSelect = onSelect;\n this.anchorRect = anchorRect;\n }\n\n /* -------------------------------------------- */\n\n async _prepareContext() {\n return { available: this.available };\n }\n\n /* -------------------------------------------- */\n\n _onRender(context, options) {\n super._onRender(context, options);\n const root = this.element;\n\n const width = 260;\n const maxHeight = 300;\n const viewportW = document.documentElement.clientWidth;\n const viewportH = document.documentElement.clientHeight;\n const gap = 4;\n let left = Math.round(this.anchorRect?.left ?? 0);\n let top = Math.round((this.anchorRect?.bottom ?? 0) + gap);\n left = Math.max(4, Math.min(left, viewportW - width - 4));\n top = Math.max(4, Math.min(top, viewportH - maxHeight - 4));\n Object.assign(root.style, {\n left: `${left}px`,\n top: `${top}px`,\n width: `${width}px`,\n maxHeight: `${maxHeight}px`\n });\n\n const input = root.querySelector(\".tah-add-popover-search\");\n const items = root.querySelectorAll(\".tah-add-popover-item:not(.tah-add-popover-custom):not(.tah-add-popover-empty)\");\n const customRow = root.querySelector(\".tah-add-popover-custom\");\n const customName = root.querySelector(\".tah-add-popover-custom-name\");\n const emptyRow = root.querySelector(\".tah-add-popover-empty\");\n\n if (customRow) customRow.style.display = \"none\";\n if (emptyRow) emptyRow.style.display = \"none\";\n\n let focusIndex = 0;\n let hasNavigated = false;\n\n const isHidden = li => li.style.display === \"none\";\n\n const visibleItems = () =>\n Array.from(root.querySelectorAll(\".tah-add-popover-item\"))\n .filter(li => !isHidden(li) && !li.classList.contains(\"tah-add-popover-empty\"));\n\n const clearHighlight = () => {\n root.querySelectorAll(\".tah-add-popover-item.focused\").forEach(el => el.classList.remove(\"focused\"));\n };\n\n const highlight = () => {\n clearHighlight();\n if (!hasNavigated) return;\n const vis = visibleItems();\n if (vis[focusIndex]) {\n vis[focusIndex].classList.add(\"focused\");\n vis[focusIndex].scrollIntoView({ block: \"nearest\" });\n }\n };\n\n const applyFilter = () => {\n const query = input.value.trim().toLowerCase();\n let visibleCount = 0;\n let exactMatch = false;\n\n items.forEach(li => {\n const name = (li.dataset.listName || li.dataset.name || \"\").toLowerCase();\n const match = !query || name.includes(query);\n li.style.display = match ? \"\" : \"none\";\n if (match) visibleCount++;\n if (name === query) exactMatch = true;\n });\n\n if (query && !exactMatch) {\n customName.textContent = `\"${input.value.trim()}\"`;\n customRow.style.display = \"\";\n visibleCount++;\n } else {\n customRow.style.display = \"none\";\n }\n\n emptyRow.style.display = visibleCount > 0 ? \"none\" : \"\";\n focusIndex = 0;\n highlight();\n };\n\n const pick = li => {\n if (!li || li.classList.contains(\"tah-add-popover-empty\")) return;\n if (li.dataset.custom === \"true\") {\n const name = input.value.trim();\n if (!name) return;\n this.onSelect({ id: null, name, listName: name, type: \"custom\" });\n } else {\n this.onSelect({\n id: li.dataset.id,\n name: li.dataset.name,\n listName: li.dataset.listName,\n type: li.dataset.type\n });\n }\n this.close();\n };\n\n input.addEventListener(\"input\", applyFilter);\n input.addEventListener(\"keydown\", ev => {\n if (ev.key === \"ArrowDown\") {\n ev.preventDefault();\n focusIndex = hasNavigated ? Math.min(focusIndex + 1, visibleItems().length - 1) : 0;\n hasNavigated = true;\n highlight();\n } else if (ev.key === \"ArrowUp\") {\n ev.preventDefault();\n focusIndex = hasNavigated ? Math.max(focusIndex - 1, 0) : 0;\n hasNavigated = true;\n highlight();\n } else if (ev.key === \"Enter\") {\n ev.preventDefault();\n const target = hasNavigated ? visibleItems()[focusIndex] : visibleItems()[0];\n pick(target);\n } else if (ev.key === \"Escape\") {\n ev.preventDefault();\n this.close();\n }\n });\n\n root.querySelectorAll(\".tah-add-popover-item\").forEach(li => {\n li.addEventListener(\"click\", () => pick(li));\n });\n\n this._outsideHandler = ev => {\n if (!root.contains(ev.target)) this.close();\n };\n document.addEventListener(\"pointerdown\", this._outsideHandler, true);\n\n applyFilter();\n setTimeout(() => input.focus(), 0);\n }\n\n /* -------------------------------------------- */\n\n async close(options = {}) {\n if (this._outsideHandler) {\n document.removeEventListener(\"pointerdown\", this._outsideHandler, true);\n this._outsideHandler = null;\n }\n this.element?.remove();\n foundry.applications.instances.delete(this.id);\n return this;\n }\n\n /* -------------------------------------------- */\n\n /**\n * Open the popover.\n * @param {object} options\n * @param {GroupHandler} options.groupHandler\n * @param {string} options.parentNestId\n * @param {number} options.parentLevel\n * @param {number} options.position\n * @param {HTMLElement} options.anchorElement\n */\n static async open({ groupHandler, parentNestId, parentLevel, position, anchorElement }) {\n const available = await groupHandler.getAvailableGroups({ nestId: parentNestId, level: parentLevel });\n\n const onSelect = async chosen => {\n const allChildren = Object.values(groupHandler.groups)\n .filter(g => g.nestId.startsWith(`${parentNestId}_`) && g.level === parentLevel + 1 && g.selected)\n .sort((a, b) => a.order - b.order);\n\n const lists = allChildren\n .filter(g => g.settings?.style !== \"tab\")\n .map(g => ({ id: g.id, listName: g.listName, name: g.name, type: g.type }));\n const tabs = allChildren\n .filter(g => g.settings?.style === \"tab\")\n .map(g => ({ id: g.id, listName: g.listName, name: g.name, type: g.type }));\n\n const newTag = {\n id: chosen.id ?? chosen.name.slugify({ replacement: \"-\", strict: true }) ?? \"subgroup\",\n listName: chosen.listName ?? chosen.name,\n name: chosen.name,\n type: chosen.type ?? \"custom\"\n };\n\n const used = new Set([...lists, ...tabs].map(g => g.id));\n if (used.has(newTag.id)) {\n const base = newTag.id;\n let suffix = 2;\n while (used.has(`${base}-${suffix}`)) suffix++;\n newTag.id = `${base}-${suffix}`;\n }\n\n const insertAt = Math.max(0, Math.min(position, lists.length));\n lists.splice(insertAt, 0, newTag);\n\n const parentGroupData = groupHandler.getGroup({ nestId: parentNestId });\n if (!parentGroupData) return;\n\n await groupHandler.updateGroups([...lists, ...tabs], parentGroupData);\n await groupHandler.saveGroups({ saveActor: true, saveUser: true });\n Hooks.callAll(\"forceUpdateTokenActionHud\");\n };\n\n const rect = anchorElement.getBoundingClientRect();\n const app = new AddSubgroupApp({ available, onSelect, anchorRect: rect });\n await app.render({ force: true });\n }\n}\n","import { MODULE, TEMPLATE } from \"../core/constants.mjs\";\n\nconst { ApplicationV2, HandlebarsApplicationMixin } = foundry.applications.api;\n\n/**\n * Popover to add a single action.\n */\nexport class AddActionApp extends HandlebarsApplicationMixin(ApplicationV2) {\n static DEFAULT_OPTIONS = {\n classes: [`${MODULE.ID}-app`, \"tah-add-popover-app\"],\n id: \"token-action-hud-popover\",\n window: { frame: false }\n };\n\n /* -------------------------------------------- */\n\n static PARTS = {\n form: { template: TEMPLATE.addPopover }\n };\n\n /* -------------------------------------------- */\n\n constructor({ available, onSelect, anchorRect }) {\n super();\n this.available = available;\n this.onSelect = onSelect;\n this.anchorRect = anchorRect;\n }\n\n /* -------------------------------------------- */\n\n async _prepareContext() {\n return { available: this.available };\n }\n\n /* -------------------------------------------- */\n\n _onRender(context, options) {\n super._onRender(context, options);\n const root = this.element;\n\n const width = 260;\n const maxHeight = 300;\n const viewportW = document.documentElement.clientWidth;\n const viewportH = document.documentElement.clientHeight;\n const gap = 4;\n let left = Math.round(this.anchorRect?.left ?? 0);\n let top = Math.round((this.anchorRect?.bottom ?? 0) + gap);\n left = Math.max(4, Math.min(left, viewportW - width - 4));\n top = Math.max(4, Math.min(top, viewportH - maxHeight - 4));\n Object.assign(root.style, {\n left: `${left}px`,\n top: `${top}px`,\n width: `${width}px`,\n maxHeight: `${maxHeight}px`\n });\n\n const input = root.querySelector(\".tah-add-popover-search\");\n const items = root.querySelectorAll(\".tah-add-popover-item:not(.tah-add-popover-custom):not(.tah-add-popover-empty)\");\n const customRow = root.querySelector(\".tah-add-popover-custom\");\n const emptyRow = root.querySelector(\".tah-add-popover-empty\");\n\n if (customRow) customRow.remove();\n if (emptyRow) emptyRow.style.display = \"none\";\n\n let focusIndex = 0;\n let hasNavigated = false;\n\n const isHidden = li => li.style.display === \"none\";\n\n const visibleItems = () =>\n Array.from(root.querySelectorAll(\".tah-add-popover-item\"))\n .filter(li => !isHidden(li) && !li.classList.contains(\"tah-add-popover-empty\"));\n\n const clearHighlight = () => {\n root.querySelectorAll(\".tah-add-popover-item.focused\").forEach(el => el.classList.remove(\"focused\"));\n };\n\n const highlight = () => {\n clearHighlight();\n if (!hasNavigated) return;\n const vis = visibleItems();\n if (vis[focusIndex]) {\n vis[focusIndex].classList.add(\"focused\");\n vis[focusIndex].scrollIntoView({ block: \"nearest\" });\n }\n };\n\n const applyFilter = () => {\n const query = input.value.trim().toLowerCase();\n let visibleCount = 0;\n\n items.forEach(li => {\n const name = (li.dataset.listName || li.dataset.name || \"\").toLowerCase();\n const match = !query || name.includes(query);\n li.style.display = match ? \"\" : \"none\";\n if (match) visibleCount++;\n });\n\n emptyRow.style.display = visibleCount > 0 ? \"none\" : \"\";\n focusIndex = 0;\n highlight();\n };\n\n const pick = li => {\n if (!li || li.classList.contains(\"tah-add-popover-empty\")) return;\n this.onSelect({\n id: li.dataset.id,\n name: li.dataset.name,\n listName: li.dataset.listName,\n type: li.dataset.type\n });\n this.close();\n };\n\n input.addEventListener(\"input\", applyFilter);\n input.addEventListener(\"keydown\", ev => {\n if (ev.key === \"ArrowDown\") {\n ev.preventDefault();\n focusIndex = hasNavigated ? Math.min(focusIndex + 1, visibleItems().length - 1) : 0;\n hasNavigated = true;\n highlight();\n } else if (ev.key === \"ArrowUp\") {\n ev.preventDefault();\n focusIndex = hasNavigated ? Math.max(focusIndex - 1, 0) : 0;\n hasNavigated = true;\n highlight();\n } else if (ev.key === \"Enter\") {\n ev.preventDefault();\n const target = hasNavigated ? visibleItems()[focusIndex] : visibleItems()[0];\n pick(target);\n } else if (ev.key === \"Escape\") {\n ev.preventDefault();\n this.close();\n }\n });\n\n root.querySelectorAll(\".tah-add-popover-item\").forEach(li => {\n li.addEventListener(\"click\", () => pick(li));\n });\n\n this._outsideHandler = ev => {\n if (!root.contains(ev.target)) this.close();\n };\n document.addEventListener(\"pointerdown\", this._outsideHandler, true);\n\n applyFilter();\n setTimeout(() => input.focus(), 0);\n }\n\n /* -------------------------------------------- */\n\n async close(options = {}) {\n if (this._outsideHandler) {\n document.removeEventListener(\"pointerdown\", this._outsideHandler, true);\n this._outsideHandler = null;\n }\n this.element?.remove();\n foundry.applications.instances.delete(this.id);\n return this;\n }\n\n /* -------------------------------------------- */\n\n /**\n * Open the popover.\n * @param {object} options\n * @param {object} options.groupHandler\n * @param {object} options.actionHandler\n * @param {string} options.parentNestId\n * @param {number} options.parentLevel\n * @param {HTMLElement} options.anchorElement\n */\n static async open({ groupHandler, actionHandler, parentNestId, parentLevel, anchorElement }) {\n const groupData = { nestId: parentNestId, level: parentLevel };\n const allActions = actionHandler.getAvailableActions();\n const selected = actionHandler.getSelectedActions(groupData) ?? [];\n const selectedIds = new Set(selected.map(a => a.id));\n // Show only actions not already in the group.\n const available = allActions.filter(a => !selectedIds.has(a.id));\n\n const onSelect = async chosen => {\n const newEntry = {\n id: chosen.id,\n listName: chosen.listName ?? chosen.name,\n name: chosen.name,\n type: chosen.type ?? \"system\"\n };\n const combined = [...selected, newEntry];\n await actionHandler.updateActions(combined, groupData);\n await groupHandler.saveGroups({ saveActor: true, saveUser: true });\n Hooks.callAll(\"forceUpdateTokenActionHud\");\n };\n\n const rect = anchorElement.getBoundingClientRect();\n const app = new AddActionApp({ available, onSelect, anchorRect: rect });\n await app.render({ force: true });\n }\n}\n","import { Utils } from \"../core/utils.mjs\";\n\nexport class GroupResizer {\n constructor(tokenActionHud, hudManager) {\n this.tokenActionHud = tokenActionHud;\n this.hudManager = hudManager;\n this.groupHandler = hudManager.groupHandler;\n this.minCols = 3;\n this.isCustomWidth = false;\n this.settings = null;\n this.spacing = 10;\n }\n\n /* -------------------------------------------- */\n\n /**\n * Resize the groups element.\n * @param {object} groupElement\n */\n async resizeGroup(groupElement) {\n if (!groupElement) return;\n\n await this.#setVariables(groupElement);\n\n if (!this.subgroupsElement) return;\n\n if (!this.tokenActionHud.isDocked) {\n await this.#setWidth();\n }\n\n await this.#setHeight();\n\n this.#resetVariables();\n }\n\n /* -------------------------------------------- */\n\n /**\n * Set variables.\n * @private\n * @param {object} groupElement\n */\n async #setVariables(groupElement) {\n this.#resetVariables();\n\n this.groupElement = groupElement;\n\n // Get groups element\n await this.#setSubgroupsElement();\n if (!this.subgroupsElement) return;\n\n // Reset groups elements\n this.#resetGroupsElements();\n\n // Get groups\n this.#setSubgroupElementArr();\n }\n\n /* -------------------------------------------- */\n\n /**\n * Reset variables.\n * @private\n */\n #resetVariables() {\n this.actionsElements = null;\n this.availableHeight = null;\n this.availableWidth = null;\n this.gridWidth = null;\n this.groupElement = null;\n this.subgroupElementArr = null;\n this.subgroupsElement = null;\n this.subgroupsElementPadding = null;\n this.subgroupsElementRect = null;\n this.isCustomWidth = false;\n this.minCols = 3;\n this.settings = null;\n this.spacing = 10;\n }\n\n /* -------------------------------------------- */\n\n /**\n * Reset groups elements.\n */\n #resetGroupsElements() {\n const level1GroupElement = this.groupElement.closest('[data-part=\"group\"]');\n const groupsElements = level1GroupElement.querySelectorAll(\".tah-subgroups\");\n const style = { maxHeight: \"\", overflowY: \"\" };\n this.#resetCSS(groupsElements, style);\n }\n\n /* -------------------------------------------- */\n\n /**\n * Get the grid width.\n * @private\n */\n async #getGridWidth() {\n // Reset action elements\n const emptyStyle = { display: \"\", gridTemplateColumns: \"\", width: \"\" };\n await this.#resetCSS(this.actionsElements, emptyStyle);\n this.actionsElements.forEach(el => el.classList.remove(\"tah-actions-grid\"));\n\n const actionWidths = [];\n const actionWidthsForMedian = [];\n for (const actionsElement of this.actionsElements) {\n const actionElements = actionsElement.querySelectorAll(\".tah-action:not(.shrink)\");\n for (const actionElement of actionElements) {\n const actionRect = actionElement.getBoundingClientRect();\n const actionWidth = Math.round(parseFloat(actionRect.width) + 1 || 0);\n const actionButtonText = actionElement.querySelector(\".tah-action-button-text\");\n const actionButtonTextRect = actionButtonText?.getBoundingClientRect();\n const actionButtonTextWidth = Math.round(parseFloat(actionButtonTextRect?.width) || 0);\n actionWidthsForMedian.push(actionWidth);\n actionWidths.push({ actionWidth, actionButtonTextWidth });\n }\n }\n\n let upperQuartileAverage = Math.ceil(Utils.getUpperQuartileAverage(actionWidthsForMedian));\n const minActionButtonTextWidth = 30;\n\n for (const actionWidth of actionWidths) {\n const availableactionButtonTextWidth = upperQuartileAverage\n - (actionWidth.actionWidth - actionWidth.actionButtonTextWidth);\n if (availableactionButtonTextWidth < minActionButtonTextWidth) {\n upperQuartileAverage = (upperQuartileAverage - availableactionButtonTextWidth) + minActionButtonTextWidth;\n }\n }\n\n this.gridWidth = upperQuartileAverage;\n }\n\n /* -------------------------------------------- */\n\n /**\n * Resize the actions element into the grid format.\n * @private\n * @param {object} actionsElement\n * @param {number} groupCustomWidth The group custom width\n */\n async #resizeGrid(actionsElement, groupCustomWidth) {\n if (!actionsElement) return;\n const emptyStyle = { display: \"\", gridTemplateColumns: \"\", width: \"\" };\n await this.#assignCSS(actionsElement, emptyStyle);\n\n const actions = actionsElement.querySelectorAll(\".tah-action\");\n const squaredCols = Math.ceil(Math.sqrt(actions.length));\n const availableGroupWidth = groupCustomWidth ?? this.availableWidth;\n const availableCols = Math.floor(availableGroupWidth / this.gridWidth);\n const cols = (squaredCols > availableCols || groupCustomWidth)\n ? availableCols\n : (actions.length <= this.minCols) ? actions.length : squaredCols;\n // Apply maxHeight and width styles to content\n const style = { display: \"grid\", gridTemplateColumns: `repeat(${cols}, ${this.gridWidth}px)` };\n actionsElement.classList.add(\"tah-actions-grid\");\n await this.#assignCSS(actionsElement, style);\n }\n\n /* -------------------------------------------- */\n\n /**\n * Resize the actions element.\n * @private\n * @param {object} actionsElement\n * @param {number} groupCustomWidth\n */\n async #resize(actionsElement, groupCustomWidth) {\n if (!actionsElement) return;\n actionsElement.classList.remove(\"tah-actions-grid\");\n\n let width = 500;\n\n if (this.isCustomWidth) {\n width = this.availableWidth;\n } else if (groupCustomWidth) {\n width = groupCustomWidth;\n } else {\n const actions = actionsElement.querySelectorAll(\".tah-action\");\n if (!actions.length) return;\n const sqrtActions = Math.ceil(Math.sqrt(actions.length)); // 4\n\n // Initialize variables\n let currentRow = 1;\n let maxRowWidth = 0;\n let rowWidth = 0;\n // Iterate through action groups, calculating dimensions and counts\n if (actions.length > 0) {\n actions.forEach((action, index) => {\n if ((index + 1) / sqrtActions > currentRow) {\n rowWidth = rowWidth - 5;\n maxRowWidth = (rowWidth > maxRowWidth) ? rowWidth : maxRowWidth;\n rowWidth = 0;\n currentRow++;\n }\n const actionRect = action.getBoundingClientRect();\n const actionWidth = Math.ceil(parseFloat(actionRect.width) + 1 || 0);\n rowWidth += actionWidth;\n if (index + 1 === actions.length) {\n rowWidth = rowWidth - 5;\n maxRowWidth = (rowWidth > maxRowWidth) ? rowWidth : maxRowWidth;\n }\n });\n }\n\n // Add padding to maxAvgGroupWidth and maxGroupWidth\n maxRowWidth += this.subgroupsElementPadding;\n\n // Determine width of content\n width = (maxRowWidth < this.availableWidth && actions.length > 3) ? maxRowWidth : this.availableWidth;\n if (width < 200) width = 200;\n }\n\n const style = { maxWidth: `${width}px` };\n await this.#assignCSS(actionsElement, style);\n }\n\n /* -------------------------------------------- */\n\n /**\n * Get available content width.\n * @private\n * @returns {number} Available content width\n */\n #getAvailableWidth() {\n const customWidth = this.settings?.customWidth;\n\n if (customWidth) {\n this.isCustomWidth = true;\n return customWidth;\n }\n\n const windowWidth = canvas.screenDimensions[0] || window.innerWidth;\n const contentLeft = this.subgroupsElementRect.left;\n const uiRight = document.querySelector(\"#ui-right\");\n const uiRightClientWidth = uiRight.clientWidth;\n return Math.floor((\n uiRightClientWidth > 0\n ? windowWidth - uiRightClientWidth\n : windowWidth\n ) - this.spacing - contentLeft);\n }\n\n /* -------------------------------------------- */\n\n /**\n * Get subgroups element.\n * @private\n */\n async #setSubgroupsElement() {\n this.subgroupsElement = this.groupElement.querySelector('[data-part=\"subgroups\"]');\n if (!this.subgroupsElement) return;\n this.subgroupsElementRect = this.subgroupsElement.getBoundingClientRect();\n this.subgroupsElementComputed = getComputedStyle(this.subgroupsElement);\n this.subgroupsElementPadding =\n Math.ceil(parseFloat(this.subgroupsElementComputed.paddingLeft) || 0)\n + Math.ceil(parseFloat(this.subgroupsElementComputed.paddingRight) || 0);\n }\n\n /* -------------------------------------------- */\n\n /**\n * Get subgroup elements.\n * @private\n */\n #setSubgroupElementArr() {\n this.subgroupElementArr = this.groupElement.querySelectorAll('[data-part=\"subgroup\"]');\n if (this.subgroupElementArr.length === 0) this.subgroupElementArr = [this.groupElement];\n }\n\n /* -------------------------------------------- */\n\n /**\n * Set the width.\n */\n async #setWidth() {\n this.actionsElements = this.groupElement.querySelectorAll('[data-part=\"actions\"]');\n\n // Exit early if no action elements exist\n if (this.actionsElements.length === 0) return;\n\n // Get group settings\n const nestId = this.groupElement.dataset.nestId;\n this.settings = await this.groupHandler.getGroupSettings({ nestId, level: 1 });\n\n // Get available width\n this.availableWidth = this.#getAvailableWidth();\n\n // Loop groups\n let hasGrid = false;\n for (const subgroupElement of this.subgroupElementArr) {\n const actionsElement = subgroupElement.querySelector('[data-part=\"actions\"]');\n if (!actionsElement) continue;\n const nestId = subgroupElement.dataset.nestId;\n const groupSettings = await this.groupHandler.getGroupSettings({ nestId });\n const groupCustomWidth = groupSettings.customWidth;\n const grid = Utils.getSetting(\"grid\") || this.settings?.grid || groupSettings?.grid || actionsElement.style.display;\n if (grid) {\n if (!hasGrid) {\n await this.#getGridWidth();\n hasGrid = true;\n }\n await this.#resizeGrid(actionsElement, groupCustomWidth);\n } else {\n await this.#resize(actionsElement, groupCustomWidth);\n }\n }\n }\n\n /* -------------------------------------------- */\n\n /**\n * Set the height.\n * @private\n */\n async #setHeight() {\n await new Promise(resolve => {\n requestAnimationFrame(() => {\n this.availableHeight = this.#getAvailableHeight();\n const style = { maxHeight: `${this.availableHeight}px`, overflowY: \"auto\" };\n Object.assign(this.subgroupsElement.style, style);\n resolve();\n });\n });\n }\n\n /* -------------------------------------------- */\n\n /**\n * Get available height.\n * @private\n * @returns {number} Available height\n */\n #getAvailableHeight() {\n const windowHeight = canvas.screenDimensions[1] || window.innerHeight;\n const contentBottom = this.subgroupsElementRect.bottom;\n const contentTop = this.subgroupsElementRect.top;\n\n let uiTopBottom = null;\n if (this.tokenActionHud.isDocked) {\n let siblingsHeight = 0;\n let sibling = this.groupElement.nextElementSibling;\n\n if (sibling) {\n const siblings = [sibling];\n while (sibling) {\n sibling = sibling.nextElementSibling;\n if (sibling) siblings.push(sibling);\n }\n for (const sibling of siblings) {\n const siblingHeight = sibling.getBoundingClientRect().height;\n siblingsHeight += siblingHeight ?? 0;\n }\n }\n\n const hotbar = foundry.utils.isNewerVersion(game.version, \"12.999\")\n ? document.querySelector(\"#hotbar\")\n : document.querySelector(\"#ui-bottom\");\n const hotbarTop = hotbar?.getBoundingClientRect().top ?? windowHeight;\n const bottomBlocker = Math.max(0, windowHeight - hotbarTop);\n\n return Math.max(windowHeight - contentTop - siblingsHeight - bottomBlocker - this.spacing, 100);\n } else if (this.tokenActionHud.direction === \"down\") {\n if (foundry.utils.isNewerVersion(game.version, \"12.999\")) {\n uiTopBottom = document.querySelector(\"#hotbar\");\n } else {\n uiTopBottom = document.querySelector(\"#ui-bottom\");\n }\n } else if (foundry.utils.isNewerVersion(game.version, \"12.999\")) {\n uiTopBottom = document.querySelector(\"#scene-navigation-active\");\n } else {\n uiTopBottom = document.querySelector(\"#ui-top\");\n }\n const uiTopBottomOffsetHeight = uiTopBottom?.offsetHeight ?? 0;\n const availableHeight = (this.tokenActionHud.direction === \"down\")\n ? windowHeight - contentTop - uiTopBottomOffsetHeight - this.spacing\n : contentBottom - uiTopBottomOffsetHeight - this.spacing;\n return Math.max(availableHeight, 100);\n }\n\n /* -------------------------------------------- */\n\n /**\n * Assign CSS.\n * @private\n * @param {object} element\n * @param {object} style\n */\n async #assignCSS(element, style) {\n if (!element) return;\n requestAnimationFrame(() => {\n Object.assign(element.style, style);\n });\n }\n\n /* -------------------------------------------- */\n\n /**\n * Reset CSS.\n * @private\n * @param {Array} elements List of DOM elements\n * @param {object} style\n */\n async #resetCSS(elements, style) {\n for (const element of elements) {\n Object.assign(element.style, style);\n }\n }\n}\n","import { HudManager } from \"../managers/hud-manager.mjs\";\nimport { FormAppHelper } from \"./form-app-helper.mjs\";\nimport { AddSubgroupApp } from \"./add-subgroup-app.mjs\";\nimport { AddActionApp } from \"./add-action-app.mjs\";\nimport { GroupResizer } from \"../handlers/group-resizer.mjs\";\nimport { HUD, MODULE, SETTING, TEMPLATE } from \"../core/constants.mjs\";\nimport { Logger, Timer, Utils } from \"../core/utils.mjs\";\n\nconst { ApplicationV2, HandlebarsApplicationMixin } = foundry.applications.api;\n\n/**\n * Token Action HUD application.\n */\nexport class TokenActionHud extends HandlebarsApplicationMixin(ApplicationV2) {\n constructor(systemManager, dataHandler, socket) {\n super();\n this.systemManager = systemManager;\n this.dataHandler = dataHandler;\n this.hudManager = new HudManager(this, systemManager, dataHandler, socket);\n this.socket = socket;\n this.openGroups = new Set();\n this.updatePendingTimer = new Timer(10);\n this.updateTimer = new Timer(10);\n this.closeTimer = null;\n this.renderTimer = null;\n this.setting = {};\n }\n\n /* -------------------------------------------- */\n\n /**\n * Merge Token Action Hud's default options with ApplicationV2.\n * @override\n */\n static DEFAULT_OPTIONS = {\n actions: {\n clickGroup: {\n buttons: [0, 2],\n handler: TokenActionHud.clickGroup\n },\n clickSubgroup: {\n buttons: [0, 2],\n handler: TokenActionHud.clickSubgroup\n },\n clickAction: {\n buttons: [0, 2],\n handler: TokenActionHud.clickAction\n },\n collapseHud: TokenActionHud.collapseHud,\n expandHud: TokenActionHud.expandHud,\n lockHud: TokenActionHud.lockHud,\n unlockHud: TokenActionHud.unlockHud,\n editHud: TokenActionHud.editHud,\n addGroup: TokenActionHud.addGroup,\n addSubgroup: TokenActionHud.addSubgroup,\n addAction: TokenActionHud.addAction\n },\n background: \"none\",\n classes: [\"faded-ui\"],\n id: \"token-action-hud-app\",\n position: {\n width: HUD.DEFAULT_WIDTH,\n height: HUD.DEFAULT_HEIGHT,\n left: HUD.DEFAULT_LEFT_POS,\n top: HUD.DEFAULT_TOP_POS,\n scale: HUD.DEFAULT_SCALE,\n zIndex: HUD.DEFAULT_ZINDEX\n },\n window: {\n frame: false,\n title: \"token-action-hud\"\n }\n };\n\n /* -------------------------------------------- */\n\n /**\n * Define template parts.\n */\n static PARTS = {\n form: {\n template: TEMPLATE.hud\n }\n };\n\n /* -------------------------------------------- */\n\n /**\n * Prepare context.\n * @override\n */\n async _prepareContext() {\n let styleKey = this.setting.style ?? Utils.getSetting(\"style\") ?? \"foundryVTT\";\n let styleData = this.systemManager.styles[styleKey];\n if (!styleData) {\n styleKey = \"foundryVTT\";\n styleData = this.systemManager.styles.foundryVTT;\n }\n const styleClass = foundry.utils.isNewerVersion(game.version, \"12.999\") && [\"dockedLeft\", \"dockedCenterRight\", \"dockedRight\"].includes(styleKey)\n ? `${styleData.class}-v13`\n : styleData.class;\n const context = {\n hud: this.hudManager.hud,\n id: \"token-action-hud\",\n style: styleClass ?? \"\",\n scale: this.scale,\n background: \"#00000000\",\n collapseIcon: styleData.collapseIcon ?? \"fa-caret-left\",\n expandIcon: styleData.expandIcon ?? \"fa-caret-right\",\n collapsibleSubgroups: Utils.getSetting(\"collapsibleSubgroups\")\n };\n\n Logger.debug(\"Application context\", { context });\n return context;\n }\n\n /* -------------------------------------------- */\n /* SETTINGS */\n /* -------------------------------------------- */\n\n /**\n * Initialise the HUD.\n * @public\n */\n async init() {\n this.#cacheSettings();\n }\n\n /* -------------------------------------------- */\n\n /**\n * Cache settings for slightly faster retrieval.\n */\n #cacheSettings() {\n Object.entries(SETTING).forEach(([key, value]) => {\n if (value.cache) {\n this.setting[key] = Utils.getSetting(key);\n }\n });\n }\n\n /* -------------------------------------------- */\n\n /**\n * Update cached settings following changes.\n * @param {string} key Setting key\n * @param {*|null} value Setting value\n * @public\n */\n async updateCachedSettings(key, value = null) {\n if (!this.updateSettingsPending) {\n this.updateSettingsPending = true;\n Logger.debug(\"Updating settings...\");\n }\n\n if (!SETTING[key]) return;\n if (!SETTING[key].cache) return;\n\n this.setting[key] = value;\n\n switch (key) {\n case \"customLayout\":\n case \"userCustomLayout\":\n this.hudManager.layoutHandler.customLayout = null;\n break;\n case \"rollHandler\":\n this.hudManager.rollHandler = this.systemManager.getRollHandlerCore(this.hudManager.actionHandler);\n break;\n case \"style\":\n this.setPosition();\n break;\n case \"drag\":\n this.#updateDragButtonVisibility();\n break;\n }\n }\n\n /* -------------------------------------------- */\n /* RENDER */\n /* -------------------------------------------- */\n\n /**\n * On render.\n * @param {options} context\n * @param {options} options\n */\n _onRender(context, options) {\n super._onRender(context, options);\n this.element.classList.remove(\"tah-closed\");\n Utils.switchCSS(this.setting.style);\n clearTimeout(this.closeTimer);\n clearTimeout(this.renderTimer);\n this.#cacheElements();\n this.#setInitialHudState();\n this.#addHoverEvents(this.elements);\n\n if (!this._rootListenersAttached) {\n this.#attachRootListeners();\n this._rootListenersAttached = true;\n }\n this.#setupContextMenus();\n this.#updateDragButtonVisibility();\n this.#updateDraggableState();\n }\n\n /* -------------------------------------------- */\n\n /**\n * Show or hide the drag icon based on the Drag setting and lock state.\n * @private\n * @param {boolean} [isUnlockedOverride]\n */\n #updateDragButtonVisibility(isUnlockedOverride) {\n const button = this.elements?.dragButton;\n if (!button) return;\n const isUnlocked = isUnlockedOverride ?? this.isUnlocked;\n const drag = Utils.getSetting(\"drag\");\n const isDraggable = (drag === \"always\") || (drag === \"whenUnlocked\" && isUnlocked);\n const show = !this.isDocked && isDraggable;\n button.classList.toggle(\"tah-hidden\", !show);\n }\n\n /* -------------------------------------------- */\n\n /**\n * Cache HUD elements\n */\n #cacheElements() {\n this.elements = {\n characterName: this.element.querySelector(\"[data-part=\\\"characterName\\\"]\"),\n actionArr: this.element.querySelectorAll(\"[data-part=\\\"action\\\"]\"),\n buttons: this.element.querySelector(\"[data-part=\\\"buttons\\\"]\"),\n tabSubgroupArr: this.element.querySelectorAll(\"[data-group-type=\\\"tab\\\"]\"),\n groups: this.element.querySelector(\"[data-part=\\\"groups\\\"]\"),\n editHudButton: this.element.querySelector(\"[data-part=\\\"editHudButton\\\"]\"),\n listSubgroupsArr: this.element.querySelectorAll(\"[data-part=\\\"listSubgroups\\\"]\"),\n subgroupsContainerArr: this.element.querySelectorAll(\"[data-part=\\\"subgroupsContainer\\\"]\"),\n groupArr: this.element.querySelectorAll(\"[data-part=\\\"group\\\"]\"),\n subgroupArr: this.element.querySelectorAll(\"[data-part=\\\"subgroup\\\"]\"),\n listSubgroupTitleArr: this.element.querySelectorAll(\"[data-part=\\\"listSubgroupTitle\\\"]\"),\n groupButtonArr: this.element.querySelectorAll(\"[data-part=\\\"groupButton\\\"]\"),\n addGroupButtonArr: this.element.querySelectorAll(\"[data-part=\\\"addGroupButton\\\"]\"),\n addSubgroupButtonArr: this.element.querySelectorAll(\"[data-part=\\\"addSubgroupButton\\\"]\"),\n addActionButtonArr: this.element.querySelectorAll(\"[data-part=\\\"addActionButton\\\"]\"),\n dragButton: this.element.querySelector(\"[data-part=\\\"dragHudButton\\\"]\"),\n collapseExpandContainer: this.element.querySelector(\"[data-part=\\\"collapseExpandContainer\\\"]\"),\n collapseHudButton: this.element.querySelector(\"[data-part=\\\"collapseHudButton\\\"]\"),\n expandHudButton: this.element.querySelector(\"[data-part=\\\"expandHudButton\\\"]\"),\n unlockButton: this.element.querySelector(\"[data-part=\\\"unlockHudButton\\\"]\"),\n lockButton: this.element.querySelector(\"[data-part=\\\"lockHudButton\\\"]\")\n };\n }\n\n /* -------------------------------------------- */\n\n /**\n * Set the initial state of the HUD (collapsed or expanded, locked or unlocked).\n * @private\n */\n #setInitialHudState() {\n if (this.isCollapsed) { TokenActionHud.collapseHud.call(this); }\n\n if (Utils.getSetting(\"enableCustomization\")) {\n if (this.isUnlocked) {\n TokenActionHud.unlockHud.call(this);\n } else {\n TokenActionHud.lockHud.call(this);\n }\n } else {\n TokenActionHud.lockHud.call(this);\n this.elements.unlockButton.classList.add(\"tah-hidden\");\n }\n }\n\n /* -------------------------------------------- */\n\n /**\n * Add hover events.\n * @param {object} elements HUD elements\n */\n #addHoverEvents(elements) {\n if (!Utils.getSetting(\"clickOpenCategory\")) {\n // When a category button is hovered over...\n const hoverToggle = ev => {\n if (this.isUnlocked && ev.type !== \"pointerenter\") return;\n this.toggleGroup(ev);\n };\n elements.tabSubgroupArr.forEach(element => {\n element.addEventListener(\"touchstart\", hoverToggle, { passive: true });\n element.addEventListener(\"pointerenter\", hoverToggle);\n element.addEventListener(\"pointerleave\", hoverToggle);\n });\n }\n\n // When the drag icon is clicked and held...\n if (!this.isDocked && elements.dragButton) {\n elements.dragButton.addEventListener(\"mousedown\", this.#dragEvent.bind(this));\n elements.dragButton.addEventListener(\"touchstart\", this.#dragEvent.bind(this), { passive: true });\n }\n\n // When an action is hovered...\n elements.actionArr.forEach(element => {\n element.addEventListener(\"pointerenter\", this.handleActionHover.bind(this));\n element.addEventListener(\"pointerleave\", this.handleActionHover.bind(this));\n });\n }\n\n /* -------------------------------------------- */\n\n /**\n * Attach root listeners.\n * @private\n */\n #attachRootListeners() {\n this.element.addEventListener(\"contextmenu\", ev => {\n const actionButton = ev.target.closest(\"[data-part=\\\"actionButton\\\"]\");\n if (actionButton) {\n const isEditing = this.isUnlocked && Utils.getSetting(\"enableCustomization\");\n const actionOptsIn = actionButton.dataset.hasContextMenu === \"true\";\n if (isEditing || actionOptsIn) {\n this._actionContextMenu?._onActivate(ev);\n }\n return;\n }\n\n if (!this.isUnlocked) return;\n if (!Utils.getSetting(\"enableCustomization\")) return;\n\n if (ev.target.closest(\"[data-part=\\\"groupButton\\\"], [data-part=\\\"listSubgroupTitle\\\"], [data-part=\\\"subgroup\\\"]\")) {\n this._groupContextMenu?._onActivate(ev);\n }\n });\n\n this.element.addEventListener(\"dragstart\", this.#onDragStart.bind(this));\n this.element.addEventListener(\"dragenter\", this.#onDragEnter.bind(this));\n this.element.addEventListener(\"dragover\", this.#onDragOver.bind(this));\n this.element.addEventListener(\"dragleave\", this.#onDragLeave.bind(this));\n this.element.addEventListener(\"drop\", this.#onDrop.bind(this));\n this.element.addEventListener(\"dragend\", this.#onDragEnd.bind(this));\n }\n\n /* -------------------------------------------- */\n /* POST-RENDER */\n /* -------------------------------------------- */\n\n /**\n * Functions to execute after the application is rendered.\n */\n postRender() {\n this.rendering = false;\n this.#applyDirection();\n this.#reopenGroups();\n if (!this.isCollapsed) {\n this.renderTimer = setTimeout(() => {\n requestAnimationFrame(() => {\n this.element?.classList?.add(\"tah-expanded\");\n });\n }, 25);\n }\n }\n\n /* -------------------------------------------- */\n\n /**\n * Apply classes for HUD direction.\n * @private\n */\n #applyDirection() {\n if (this.isDocked) return;\n\n const { characterName, subgroupsContainerArr } = this.elements;\n\n if (this.direction === \"up\") {\n characterName?.classList?.add(\"tah-hidden\");\n\n subgroupsContainerArr.forEach(element => {\n element.classList.remove(\"expand-down\");\n element.classList.add(\"expand-up\");\n });\n } else {\n if (!this.isCollapsed) {\n characterName?.classList?.remove(\"tah-hidden\");\n }\n\n subgroupsContainerArr.forEach(element => {\n element.classList.add(\"expand-down\");\n element.classList.remove(\"expand-up\");\n });\n }\n }\n\n /* -------------------------------------------- */\n\n /**\n * Reopen groups following a re-render of the HUD.\n * @private\n */\n #reopenGroups() {\n if (!this.openGroups.size) return;\n\n this.openGroups.forEach(groupId => {\n const group = this.element.querySelector(`#${groupId}`);\n if (group) {\n this.toggleGroup(null, group);\n }\n });\n }\n\n /* -------------------------------------------- */\n /* HUD ACTIONS */\n /* -------------------------------------------- */\n\n /**\n * When the 'Edit HUD' button is clicked, open the Edit HUD app.\n */\n static editHud() {\n FormAppHelper.openEditHudApp(this.hudManager.groupHandler);\n }\n\n /* -------------------------------------------- */\n\n /**\n * When a \"+\" button between groups is clicked, open the Add Group app.\n * @param {Event} event\n * @param {HTMLElement} target\n */\n static addGroup(event, target) {\n const button = target ?? event.target.closest(\"[data-action=\\\"addGroup\\\"]\");\n const position = parseInt(button?.dataset.position, 10);\n FormAppHelper.openAddGroupApp(this.hudManager.groupHandler, Number.isNaN(position) ? 0 : position);\n }\n\n /* -------------------------------------------- */\n\n /**\n * When a \"+\" button between subgroups is clicked, open the popover.\n * @param {Event} event\n * @param {HTMLElement} target\n */\n static addSubgroup(event, target) {\n const button = target ?? event.target.closest(\"[data-action=\\\"addSubgroup\\\"]\");\n if (!button) return;\n const parentNestId = button.dataset.parentNestId;\n const parentLevel = parseInt(button.dataset.parentLevel, 10) || 1;\n const position = parseInt(button.dataset.position, 10);\n AddSubgroupApp.open({\n groupHandler: this.hudManager.groupHandler,\n parentNestId,\n parentLevel,\n position: Number.isNaN(position) ? 0 : position,\n anchorElement: button\n });\n }\n\n /* -------------------------------------------- */\n\n /**\n * When a \"+\" button at the end of a subgroup's action list is clicked,\n * open the popover.\n * @param {Event} event\n * @param {HTMLElement} target The clicked \"+\" button\n */\n static addAction(event, target) {\n const button = target ?? event.target.closest(\"[data-action=\\\"addAction\\\"]\");\n if (!button) return;\n const parentNestId = button.dataset.parentNestId;\n const parentLevel = parseInt(button.dataset.parentLevel, 10) || 1;\n AddActionApp.open({\n groupHandler: this.hudManager.groupHandler,\n actionHandler: this.hudManager.actionHandler,\n parentNestId,\n parentLevel,\n anchorElement: button\n });\n }\n\n /* -------------------------------------------- */\n /* ENABLE/DISABLE HUD */\n /* -------------------------------------------- */\n\n /**\n * Toggle the HUD enabled state.\n */\n async toggleHudEnable() {\n const binding = Utils.humanizeBinding(\"enableDisableHud\");\n const state = (this.isEnabled) ? \"disabled\" : \"enabled\";\n if (this.isEnabled) {\n this.#close();\n } else {\n Hooks.callAll(\"forceUpdateTokenActionHud\");\n }\n await Utils.setSetting(\"enable\", !this.isEnabled);\n Logger.info(game.i18n.format(`tokenActionHud.keybinding.toggleHud.${state}`, { binding }), true);\n }\n\n /* -------------------------------------------- */\n /* COLLAPSE/EXPAND HUD */\n /* -------------------------------------------- */\n\n /**\n * When the 'Collapse HUD' button is clicked, collapse the HUD.\n */\n static collapseHud() {\n this.toggleHudCollapse(\"collapse\");\n }\n\n /* -------------------------------------------- */\n\n /**\n * When the 'Expand HUD' button is clicked, expand the HUD.\n */\n static expandHud() {\n this.toggleHudCollapse(\"expand\");\n }\n\n /* -------------------------------------------- */\n\n /**\n * Toggle the HUD between collapse and expand states.\n * @param {string} state \"collapse\" or \"expand\"\n */\n toggleHudCollapse(state) {\n state = state ?? ((this.isCollapsed) ? \"expand\" : \"collapse\");\n const isCollapsing = state === \"collapse\";\n const { characterName, collapseHudButton, expandHudButton, groups, buttons } = this.elements;\n\n collapseHudButton.classList.toggle(\"tah-hidden\", isCollapsing);\n expandHudButton.classList.toggle(\"tah-hidden\", !isCollapsing);\n\n if (this.isDocked) {\n this.element.classList.toggle(\"tah-expanded\", !isCollapsing);\n } else {\n if (this.direction === \"down\") { characterName.classList.toggle(\"tah-hidden\", isCollapsing); }\n groups.classList.toggle(\"tah-hidden\", isCollapsing);\n buttons.classList.toggle(\"tah-hidden\", isCollapsing);\n }\n\n this.isCollapsed = isCollapsing;\n }\n\n /* -------------------------------------------- */\n /* LOCK/UNLOCK HUD */\n /* -------------------------------------------- */\n\n /**\n * When the 'Unlock HUD' button is clicked, unlock the HUD.\n * @param {Event|null} event\n */\n static async unlockHud(event = null) {\n this.toggleHudLock(\"unlock\", event);\n }\n\n /* -------------------------------------------- */\n\n /**\n * When the 'Lock HUD' button is clicked, lock the HUD.\n * @param {Event|null} event\n */\n static async lockHud(event = null) {\n this.toggleHudLock(\"lock\", event);\n }\n\n /* -------------------------------------------- */\n\n /**\n * Toggle HUD lock state.\n * @param {string} state \"lock\" or \"unlock\"\n * @param {Event|null} event\n */\n toggleHudLock(state, event = null) {\n if (event) event.preventDefault();\n\n const isUnlocking = state === \"unlock\";\n const { unlockButton, lockButton, editHudButton, subgroupArr, groupButtonArr,\n addGroupButtonArr, addSubgroupButtonArr, addActionButtonArr, groups, listSubgroupsArr,\n tabSubgroupArr, listSubgroupTitleArr } = this.elements;\n\n // Toggle button visibiltiy\n unlockButton.classList.toggle(\"tah-hidden\", isUnlocking);\n lockButton.classList.toggle(\"tah-hidden\", !isUnlocking);\n editHudButton.classList.toggle(\"tah-hidden\", !isUnlocking);\n\n // Toggle class for styling when unlocked/locked\n groups.classList.toggle(\"tah-unlocked\", isUnlocking);\n\n // Helper function to toggle classes\n const toggleElements = (elements, className, toggle) => {\n elements.forEach(element => element.classList.toggle(className, toggle));\n };\n\n // Show \"+\" buttons only when unlocked and customization is enabled\n const showAddGroup = isUnlocking && Utils.getSetting(\"enableCustomization\");\n toggleElements(addGroupButtonArr, \"tah-hidden\", !showAddGroup);\n toggleElements(addSubgroupButtonArr, \"tah-hidden\", !showAddGroup);\n toggleElements(addActionButtonArr, \"tah-hidden\", !showAddGroup);\n\n toggleElements(groupButtonArr, \"disable-edit\", !isUnlocking);\n toggleElements(listSubgroupTitleArr, \"disable-edit\", !isUnlocking);\n\n if (isUnlocking) {\n // When the HUD is unlocked, unhide elements\n toggleElements(subgroupArr, \"tah-hidden\", !isUnlocking);\n toggleElements(listSubgroupsArr, \"tah-hidden\", !isUnlocking);\n toggleElements(tabSubgroupArr, \"tah-hidden\", !isUnlocking);\n toggleElements(listSubgroupTitleArr, \"tah-hidden\", !isUnlocking);\n } else {\n // When the HUD is locked, hide elements that have no underlying actions\n const hideIfEmpty = elements => {\n elements.forEach(element => {\n const hasActions = element.querySelectorAll(\".tah-action\").length > 0;\n if (!hasActions) element.classList.add(\"tah-hidden\");\n });\n };\n\n hideIfEmpty(tabSubgroupArr);\n hideIfEmpty(subgroupArr);\n hideIfEmpty(listSubgroupsArr);\n\n listSubgroupTitleArr.forEach(element => {\n const groupElement = element.closest(\".tah-subgroup\");\n if (groupElement.dataset?.showTitle === \"false\") {\n element.classList.add(\"tah-hidden\");\n }\n });\n }\n\n this.isUnlocked = isUnlocking;\n this.#updateDragButtonVisibility(isUnlocking);\n this.#updateDraggableState(isUnlocking);\n this.#updateTooltipsState(isUnlocking);\n\n Hooks.callAll(\"tokenActionHudCoreLockChanged\", isUnlocking, this.hudManager);\n }\n\n /* -------------------------------------------- */\n\n /**\n * Disable tooltips while the HUD is unlocked.\n * @private\n * @param {boolean} [isUnlockedOverride]\n */\n #updateTooltipsState(isUnlockedOverride) {\n const isUnlocked = isUnlockedOverride ?? this.isUnlocked;\n const keepSelector = \"[data-part=\\\"addGroupButton\\\"], [data-part=\\\"addSubgroupButton\\\"], [data-part=\\\"addActionButton\\\"]\";\n if (isUnlocked) {\n this.element.querySelectorAll(\"[data-tooltip]\").forEach(el => {\n if (el.matches(keepSelector)) return;\n el.setAttribute(\"data-tooltip-disabled\", el.getAttribute(\"data-tooltip\"));\n el.removeAttribute(\"data-tooltip\");\n });\n } else {\n this.element.querySelectorAll(\"[data-tooltip-disabled]\").forEach(el => {\n el.setAttribute(\"data-tooltip\", el.getAttribute(\"data-tooltip-disabled\"));\n el.removeAttribute(\"data-tooltip-disabled\");\n });\n }\n }\n\n /* -------------------------------------------- */\n /* GROUP EVENTS */\n /* -------------------------------------------- */\n\n /**\n * When a group is clicked.\n * @param {Event} event\n */\n static clickGroup(event) {\n this.bringToFront();\n\n // Remove focus to allow core ESC interactions\n event.currentTarget.blur();\n\n if (event.button === 2) {\n if (!this.isUnlocked) this.handleGroupClick(event);\n return;\n }\n\n if (Utils.getSetting(\"clickOpenCategory\")) {\n this.toggleGroup(event);\n }\n }\n\n /* -------------------------------------------- */\n\n /**\n * When a subgroup is clicked.\n * @param {Event} event\n */\n static clickSubgroup(event) {\n if (event.button === 2) {\n if (!this.isUnlocked) this.handleGroupClick(event);\n return;\n }\n\n if (this.isUnlocked) return;\n\n const group = Utils.getClosestGroupElement(event);\n if (group.dataset?.groupType === \"tab\") {\n this.toggleGroup(event, group);\n } else {\n this.collapseExpandSubgroup(event);\n }\n }\n\n /* -------------------------------------------- */\n\n /**\n * Toggle the visibility of the group.\n * @param {Event} event\n * @param {object} group\n */\n toggleGroup(event = null, group = null) {\n group = group || Utils.getClosestGroupElement(event);\n const isOpen = group.classList.contains(\"hover\");\n const shouldOpen = !isOpen;\n if ((isOpen && event?.type === \"pointerenter\") || (!isOpen && event?.type === \"pointerleave\")) return;\n group.classList.toggle(\"hover\", shouldOpen);\n if (shouldOpen) {\n this.#toggleOtherGroups(group);\n const groupResizer = new GroupResizer(this, this.hudManager);\n groupResizer.resizeGroup(group);\n\n this.openGroups.add(group.id);\n } else {\n this.openGroups.delete(group.id);\n }\n // Remove focus to allow core ESC interactions\n if (event) event.currentTarget.blur();\n }\n\n /* -------------------------------------------- */\n\n /**\n * Toggle visibility of other groups.\n * @private\n * @param {string} groupToIgnore\n */\n #toggleOtherGroups(groupToIgnore) {\n if (!this.openGroups.size) return;\n\n this.openGroups.forEach(groupId => {\n if (groupId === groupToIgnore.id) return;\n const group = this.element.querySelector(`#${groupId}`);\n // If group no longer exists on the HUD, delete it\n if (!group) {\n this.openGroups.delete(groupId);\n return;\n }\n const isParentToIgnore = group.querySelector(`#${groupToIgnore.id}`);\n if (!isParentToIgnore) this.toggleGroup(null, group);\n });\n }\n\n /* -------------------------------------------- */\n\n /**\n * Collapse/expand a subgroup.\n * @param {Event} event\n */\n collapseExpandSubgroup(event) {\n if (!Utils.getSetting(\"collapsibleSubgroups\")) return;\n\n const target = event.target.closest('[data-part=\"listSubgroupTitle\"]');\n\n const groupElement = Utils.getClosestGroupElement(event);\n const nestId = groupElement?.dataset?.nestId;\n const resizeTarget = target.closest(\".tah-tab-subgroup.hover\") || target.closest(\"[data-part=\\\"group\\\"]\");\n const groupsElement = groupElement?.querySelector(\"[data-part=\\\"subgroups\\\"]\");\n const collapseIcon = target.querySelector(\".tah-collapse-icon\");\n const expandIcon = target.querySelector(\".tah-expand-icon\");\n const imageElement = groupElement.querySelector(\".tah-list-image\");\n\n const toggleGroupVisibility = () => {\n groupsElement?.classList.toggle(\"tah-hidden\");\n collapseIcon?.classList.toggle(\"tah-hidden\");\n expandIcon?.classList.toggle(\"tah-hidden\");\n imageElement?.classList.toggle(\"tah-hidden\");\n };\n\n const saveGroupSettings = collapse => {\n if (Utils.getSetting(\"enableCustomization\")) {\n this.hudManager.groupHandler.saveGroupSettings({ nestId, settings: { collapse } });\n }\n };\n\n if (groupsElement?.classList.contains(\"tah-hidden\")) {\n toggleGroupVisibility();\n saveGroupSettings(false);\n const groupResizer = new GroupResizer(this, this.hudManager);\n groupResizer.resizeGroup(resizeTarget);\n } else {\n toggleGroupVisibility();\n saveGroupSettings(true);\n }\n }\n\n /* -------------------------------------------- */\n\n /**\n * Handle when a group is clicked.\n * @param {Event} event\n */\n handleGroupClick(event) {\n this.hudManager.handleHudEvent(\"groupClick\", event);\n }\n\n /* -------------------------------------------- */\n\n /**\n * Open the 'Edit Group' or 'Edit Subgroup' app.\n * @param {HTMLElement} triggerElement\n */\n openEditGroupApp(triggerElement) {\n const group = triggerElement?.closest(\"[data-part=\\\"subgroup\\\"]\")\n || triggerElement?.closest(\"[data-part=\\\"group\\\"]\");\n if (!group) return;\n const { nestId, level, type } = group.dataset;\n if (!nestId) return;\n const name = this.hudManager.groupHandler.groups[nestId]?.name;\n const parsedLevel = parseInt(level, 10) || null;\n\n if (parsedLevel === 1) {\n FormAppHelper.openEditGroupApp(\n this.hudManager.groupHandler,\n { nestId, name, level: parsedLevel, type }\n );\n } else {\n FormAppHelper.openEditSubgroupApp(\n this.hudManager.groupHandler,\n this.hudManager.actionHandler,\n { nestId, name, level: parsedLevel, type }\n );\n }\n }\n\n /* -------------------------------------------- */\n /* CONTEXT MENU */\n /* -------------------------------------------- */\n\n /**\n * Build the context menu items for groups and subgroups.\n * @private\n * @returns {Array} List of context menu items\n */\n #buildGroupContextMenuItems() {\n return [\n {\n label: \"tokenActionHud.contextMenu.collapse\",\n icon: \"\",\n visible: target => this.#isContextSubgroupExpanded(target) === true,\n onClick: (event, target) => this.#toggleContextSubgroup(target)\n },\n {\n label: \"tokenActionHud.contextMenu.expand\",\n icon: \"\",\n visible: target => this.#isContextSubgroupExpanded(target) === false,\n onClick: (event, target) => this.#toggleContextSubgroup(target)\n },\n {\n label: \"tokenActionHud.contextMenu.edit\",\n icon: \"\",\n onClick: (event, target) => this.openEditGroupApp(target)\n },\n {\n label: \"tokenActionHud.contextMenu.delete\",\n icon: \"\",\n classes: \"tah-context-delete\",\n onClick: (event, target) => this.#confirmDeleteGroup(target)\n }\n ];\n }\n\n /* -------------------------------------------- */\n\n /**\n * Find the subgroup wrapper element nearest to a context-menu target.\n * @private\n * @param {HTMLElement} target\n * @returns {HTMLElement|null} Closest subgroup\n */\n #getContextSubgroupElement(target) {\n return target?.closest?.(\"[data-part=\\\"subgroup\\\"]\") ?? null;\n }\n\n /* -------------------------------------------- */\n\n /**\n * Whether the subgroup is currently expanded.\n * @private\n * @param {HTMLElement} target\n * @returns {boolean|null}\n */\n #isContextSubgroupExpanded(target) {\n const sg = this.#getContextSubgroupElement(target);\n if (!sg) return null;\n if (sg.dataset.groupType === \"tab\") {\n return sg.classList.contains(\"hover\");\n }\n\n const inner = sg.querySelector(\":scope > .tah-list-subgroup > [data-part=\\\"subgroups\\\"]\");\n if (!inner) return null;\n return !inner.classList.contains(\"tah-hidden\");\n }\n\n /* -------------------------------------------- */\n\n /**\n * Toggle the expand/collapse state of the subgroup.\n * @private\n * @param {HTMLElement} target\n */\n #toggleContextSubgroup(target) {\n const sg = this.#getContextSubgroupElement(target);\n if (!sg) return;\n if (sg.dataset.groupType === \"tab\") {\n this.toggleGroup(null, sg);\n return;\n }\n const title = sg.querySelector(\":scope > .tah-list-subgroup > [data-part=\\\"listSubgroupTitle\\\"]\");\n if (title) this.collapseExpandSubgroup({ target: title });\n }\n\n /* -------------------------------------------- */\n\n #buildActionContextMenuItems() {\n return [\n {\n label: \"tokenActionHud.contextMenu.delete\",\n icon: \"\",\n classes: \"tah-context-delete\",\n visible: () => this.isUnlocked,\n onClick: (event, target) => this.#confirmDeleteAction(target)\n }\n ];\n }\n\n /* -------------------------------------------- */\n\n /**\n * Setup context menus.\n * @private\n */\n #setupContextMenus() {\n const ContextMenu = foundry.applications.ux.ContextMenu.implementation;\n const sharedOptions = { fixed: true, eventName: \"tah-never\", jQuery: false };\n\n const groupItems = this.#buildGroupContextMenuItems();\n Hooks.callAll(\"tokenActionHudCoreGroupContextMenu\", groupItems, this.hudManager);\n\n const actionItems = this.#buildActionContextMenuItems();\n Hooks.callAll(\"tokenActionHudCoreActionContextMenu\", actionItems, this.hudManager);\n\n this._groupContextMenu = new ContextMenu(\n this.element,\n \"[data-part=\\\"groupButton\\\"], [data-part=\\\"listSubgroupTitle\\\"], [data-part=\\\"subgroup\\\"]\",\n this.#prepareContextMenuItems(groupItems),\n sharedOptions\n );\n\n this._actionContextMenu = new ContextMenu(\n this.element,\n \"[data-part=\\\"actionButton\\\"]\",\n this.#prepareContextMenuItems(actionItems),\n sharedOptions\n );\n }\n\n /* -------------------------------------------- */\n\n /**\n * Prepare context menu items.\n * @private\n * @param {Array} items\n * @returns {Array} Context menu items\n */\n #prepareContextMenuItems(items) {\n if (foundry.utils.isNewerVersion(game.version, \"13.999\")) return items;\n\n // V13 ContextMenu uses `name`, `callback`, `condition`\n return items.map(item => {\n const out = { ...item };\n if (item.label && !item.name) out.name = item.label;\n if (item.onClick && !item.callback) {\n out.callback = (target, event) => item.onClick(event, target);\n }\n if (item.visible !== undefined && item.condition === undefined) {\n out.condition = typeof item.visible === \"function\"\n ? target => item.visible(target)\n : item.visible;\n }\n return out;\n });\n }\n\n /* -------------------------------------------- */\n\n /**\n * Confirm and delete a group or subgroup.\n * @private\n * @param {HTMLElement} triggerElement\n */\n async #confirmDeleteGroup(triggerElement) {\n const groupEl = triggerElement?.closest(\"[data-part=\\\"subgroup\\\"]\")\n || triggerElement?.closest(\"[data-part=\\\"group\\\"]\");\n if (!groupEl) return;\n const nestId = groupEl.dataset.nestId;\n const parsedLevel = parseInt(groupEl.dataset.level, 10) || 1;\n const name = this.hudManager.groupHandler.groups[nestId]?.name ?? \"\";\n const confirmed = await foundry.applications.api.DialogV2.confirm({\n window: { title: game.i18n.localize(\"tokenActionHud.delete.confirm.title\") },\n content: `${game.i18n.format(\"tokenActionHud.delete.confirm.content\", { name })}
`,\n modal: true\n });\n if (!confirmed) return;\n await FormAppHelper.deleteGroup(this.hudManager.groupHandler, { nestId, level: parsedLevel });\n }\n\n /* -------------------------------------------- */\n\n /**\n * Confirm and delete an action.\n * @private\n * @param {HTMLElement} triggerElement\n */\n async #confirmDeleteAction(triggerElement) {\n const button = triggerElement?.closest(\"[data-part=\\\"actionButton\\\"]\");\n const subgroupEl = triggerElement?.closest(\"[data-part=\\\"subgroup\\\"]\");\n if (!button || !subgroupEl) return;\n const actionId = button.dataset.actionId;\n const nestId = subgroupEl.dataset.nestId;\n const name = button.querySelector(\".tah-button-text\")?.textContent?.trim() ?? \"\";\n const confirmed = await foundry.applications.api.DialogV2.confirm({\n window: { title: game.i18n.localize(\"tokenActionHud.delete.confirm.title\") },\n content: `${game.i18n.format(\"tokenActionHud.delete.confirm.content\", { name })}
`,\n modal: true\n });\n if (!confirmed) return;\n await FormAppHelper.deleteAction(\n this.hudManager.groupHandler,\n this.hudManager.actionHandler,\n { nestId, actionId }\n );\n }\n\n /* -------------------------------------------- */\n /* DRAG-AND-DROP REORDER */\n /* -------------------------------------------- */\n\n /**\n * Set the draggable attribute on group/subgroup wrappers based on\n * whether the HUD is unlocked and customization is enabled.\n * @private\n * @param {boolean} [isUnlockedOverride] Use this value instead of the async-backed getter.\n */\n #updateDraggableState(isUnlockedOverride) {\n const isUnlocked = isUnlockedOverride ?? this.isUnlocked;\n const canDrag = isUnlocked && Utils.getSetting(\"enableCustomization\");\n const apply = el => {\n if (canDrag) el.setAttribute(\"draggable\", \"true\");\n else el.removeAttribute(\"draggable\");\n };\n this.elements?.groupArr?.forEach(apply);\n this.elements?.subgroupArr?.forEach(apply);\n this.elements?.actionArr?.forEach(apply);\n }\n\n /* -------------------------------------------- */\n\n /**\n * Resolve the nearest draggable group/subgroup element from an event.\n * @private\n * @param {Event} ev\n * @returns {HTMLElement|null}\n */\n #resolveDraggable(ev) {\n const node = ev.target.closest?.(\"[data-part=\\\"action\\\"], [data-part=\\\"subgroup\\\"], [data-part=\\\"group\\\"]\");\n if (!node) return null;\n if (!node.hasAttribute(\"draggable\")) return null;\n return node;\n }\n\n /* -------------------------------------------- */\n\n /**\n * Get an action's siblings.\n * @private\n * @param {HTMLElement} source\n * @returns {HTMLElement[]}\n */\n #getActionSiblings(source) {\n const parent = source?.parentElement;\n if (!parent) return [];\n return Array.from(parent.children)\n .filter(el => el.dataset?.part === \"action\" && el !== source);\n }\n\n /* -------------------------------------------- */\n\n /**\n * Find the sibling action nearest to the cursor.\n * @private\n * @param {HTMLElement} source\n * @param {number} clientX\n * @param {number} clientY\n * @returns {HTMLElement|null}\n */\n #findNearestActionSibling(source, clientX, clientY) {\n const siblings = this.#getActionSiblings(source);\n let nearest = null;\n let minDist = Infinity;\n for (const sibling of siblings) {\n const rect = sibling.getBoundingClientRect();\n const cx = rect.left + (rect.width / 2);\n const cy = rect.top + (rect.height / 2);\n const d = Math.hypot(clientX - cx, clientY - cy);\n if (d < minDist) { minDist = d; nearest = sibling; }\n }\n return nearest;\n }\n\n /* -------------------------------------------- */\n\n /**\n * Get \"+\" drop targets for source.\n * @private\n * @param {HTMLElement} source\n * @returns {HTMLElement[]} List of drop targets\n */\n #getDropTargetsForSource(source) {\n if (!source) return [];\n if (source.dataset.part === \"group\") {\n return Array.from(this.element.querySelectorAll(\"[data-part=\\\"addGroupButton\\\"]\"));\n }\n\n const sourceLevel = parseInt(source.dataset.level, 10);\n const parentLevel = sourceLevel - 1;\n const parentNestId = (source.dataset.nestId || \"\").split(\"_\").slice(0, -1).join(\"_\");\n const all = this.element.querySelectorAll(\"[data-part=\\\"addSubgroupButton\\\"]\");\n return Array.from(all).filter(btn =>\n btn.dataset.parentNestId === parentNestId\n && btn.dataset.parentLevel === String(parentLevel)\n );\n }\n\n /* -------------------------------------------- */\n\n /**\n * Find the \"+\" drop target nearest to the cursor.\n * @private\n * @param {HTMLElement} source\n * @param {number} clientX\n * @param {number} clientY\n * @returns {HTMLElement|null} Nearest drop target\n */\n #findNearestDropTarget(source, clientX, clientY) {\n const targets = this.#getDropTargetsForSource(source);\n let nearest = null;\n let minDist = Infinity;\n for (const btn of targets) {\n const rect = btn.getBoundingClientRect();\n const cx = rect.left + (rect.width / 2);\n const cy = rect.top + (rect.height / 2);\n const d = Math.hypot(clientX - cx, clientY - cy);\n if (d < minDist) { minDist = d; nearest = btn; }\n }\n return nearest;\n }\n\n /* -------------------------------------------- */\n\n #onDragStart(ev) {\n const source = this.#resolveDraggable(ev);\n if (!source) return;\n ev.stopPropagation();\n if (source.dataset.part === \"action\") {\n const parentSubgroup = source.closest(\"[data-part=\\\"subgroup\\\"]\");\n const actionButton = source.querySelector(\"[data-part=\\\"actionButton\\\"]\");\n this._dragState = {\n part: \"action\",\n actionId: actionButton?.dataset.actionId,\n parentNestId: parentSubgroup?.dataset.nestId\n };\n } else {\n this._dragState = {\n part: source.dataset.part, // \"group\" | \"subgroup\"\n nestId: source.dataset.nestId,\n level: parseInt(source.dataset.level, 10) || 1\n };\n }\n source.classList.add(\"tah-dragging\");\n this.elements.groups?.classList.add(\"tah-drag-active\");\n if (ev.dataTransfer) {\n ev.dataTransfer.effectAllowed = \"move\";\n try { ev.dataTransfer.setData(\"text/plain\", source.dataset.nestId); } catch{ }\n const transparentImage = document.createElement(\"img\");\n transparentImage.src = \"data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\";\n ev.dataTransfer.setDragImage(transparentImage, 0, 0);\n }\n }\n\n /* -------------------------------------------- */\n\n #onDragEnter(ev) {\n if (!this._dragState) return;\n ev.preventDefault();\n if (ev.dataTransfer) ev.dataTransfer.dropEffect = \"move\";\n }\n\n /* -------------------------------------------- */\n\n #onDragOver(ev) {\n if (!this._dragState) return;\n\n ev.preventDefault();\n ev.dataTransfer.dropEffect = \"move\";\n if (this._dragState.part === \"action\") {\n this.#onDragOverAction(ev);\n return;\n }\n const source = this.element.querySelector(`[data-nest-id=\"${CSS.escape(this._dragState.nestId)}\"]`);\n if (!source) return;\n const plus = this.#findNearestDropTarget(source, ev.clientX, ev.clientY);\n if (!plus) return;\n this.#clearDropIndicators();\n plus.classList.add(\"tah-drop-indicator\");\n }\n\n /* -------------------------------------------- */\n\n #onDragOverAction(ev) {\n const source = this.#findActionSourceElement();\n if (!source) return;\n const target = this.#findNearestActionSibling(source, ev.clientX, ev.clientY);\n if (!target) return;\n const rect = target.getBoundingClientRect();\n const before = this.isDocked\n ? ev.clientY < rect.top + (rect.height / 2)\n : ev.clientX < rect.left + (rect.width / 2);\n this.#clearDropIndicators();\n target.classList.add(before ? \"tah-drop-action-before\" : \"tah-drop-action-after\");\n }\n\n /* -------------------------------------------- */\n\n /**\n * Find action source element.\n * @private\n * @returns {HTMLElement|null}\n */\n #findActionSourceElement() {\n const { actionId, parentNestId } = this._dragState ?? {};\n if (!actionId || !parentNestId) return null;\n const parent = this.element.querySelector(\n `[data-part=\"subgroup\"][data-nest-id=\"${CSS.escape(parentNestId)}\"]`\n );\n if (!parent) return null;\n const button = parent.querySelector(`[data-action-id=\"${CSS.escape(actionId)}\"]`);\n return button?.closest(\"[data-part=\\\"action\\\"]\") ?? null;\n }\n\n /* -------------------------------------------- */\n\n #onDragLeave(ev) {\n if (!ev.relatedTarget || !this.element.contains(ev.relatedTarget)) {\n this.#clearDropIndicators();\n }\n }\n\n /* -------------------------------------------- */\n\n async #onDrop(ev) {\n if (!this._dragState) return;\n if (this._dragState.part === \"action\") {\n await this.#onDropAction(ev);\n return;\n }\n const source = this.element.querySelector(`[data-nest-id=\"${CSS.escape(this._dragState.nestId)}\"]`);\n if (!source) return;\n const plus = this.#findNearestDropTarget(source, ev.clientX, ev.clientY);\n if (!plus) return;\n ev.preventDefault();\n ev.stopPropagation();\n\n const position = parseInt(plus.dataset.position, 10) || 0;\n this.#clearDropIndicators();\n\n await this.#reorderGroupToPosition({\n level: this._dragState.level,\n sourceNestId: this._dragState.nestId,\n position\n });\n }\n\n /* -------------------------------------------- */\n\n async #onDropAction(ev) {\n const source = this.#findActionSourceElement();\n if (!source) return;\n const target = this.#findNearestActionSibling(source, ev.clientX, ev.clientY);\n if (!target) return;\n ev.preventDefault();\n ev.stopPropagation();\n const dropBefore = target.classList.contains(\"tah-drop-action-before\");\n this.#clearDropIndicators();\n const targetButton = target.querySelector(\"[data-part=\\\"actionButton\\\"]\");\n const targetActionId = targetButton?.dataset.actionId;\n if (!targetActionId) return;\n await this.#reorderActionToPosition({\n parentNestId: this._dragState.parentNestId,\n sourceActionId: this._dragState.actionId,\n targetActionId,\n dropBefore\n });\n }\n\n /* -------------------------------------------- */\n\n /**\n * Reorder action to its new position.\n * @private\n * @param {object} options\n * @param {string} options.parentNestId\n * @param {string} options.sourceActionId\n * @param {string} options.targetActionId\n * @param {boolean} options.dropBefore\n */\n async #reorderActionToPosition({ parentNestId, sourceActionId, targetActionId, dropBefore }) {\n const groupHandler = this.hudManager.groupHandler;\n const actionHandler = this.hudManager.actionHandler;\n const group = groupHandler.getGroup({ nestId: parentNestId });\n if (!group) return;\n const actions = group.actions.filter(a => a.selected).slice();\n const sIdx = actions.findIndex(a => a.id === sourceActionId);\n if (sIdx < 0) return;\n const [moved] = actions.splice(sIdx, 1);\n let tIdx = actions.findIndex(a => a.id === targetActionId);\n if (tIdx < 0) return;\n if (!dropBefore) tIdx += 1;\n actions.splice(tIdx, 0, moved);\n const payload = actions.map(a => ({ id: a.id, listName: a.listName, name: a.name, type: a.type }));\n actionHandler.updateActions(payload, { nestId: parentNestId });\n await groupHandler.saveGroups({ saveActor: true, saveUser: true });\n Hooks.callAll(\"forceUpdateTokenActionHud\");\n }\n\n /* -------------------------------------------- */\n\n #onDragEnd() {\n this.#clearDropIndicators();\n this.elements.groups?.classList.remove(\"tah-drag-active\");\n this.element.querySelectorAll(\".tah-dragging\").forEach(el => el.classList.remove(\"tah-dragging\"));\n this._dragState = null;\n }\n\n /* -------------------------------------------- */\n\n #clearDropIndicators() {\n this.element.querySelectorAll(\".tah-drop-indicator, .tah-drop-action-before, .tah-drop-action-after\")\n .forEach(el => el.classList.remove(\"tah-drop-indicator\", \"tah-drop-action-before\", \"tah-drop-action-after\"));\n }\n\n /* -------------------------------------------- */\n\n /**\n * Reorder group to its new position.\n * @private\n * @param {object} options\n * @param {number} options.level\n * @param {string} options.sourceNestId\n * @param {number} options.position\n */\n async #reorderGroupToPosition({ level, sourceNestId, position }) {\n const groupHandler = this.hudManager.groupHandler;\n\n if (level === 1) {\n const siblings = Object.values(groupHandler.groups)\n .filter(g => g.level === 1 && g.selected)\n .sort((a, b) => a.order - b.order);\n const sIdx = siblings.findIndex(g => g.nestId === sourceNestId);\n if (sIdx < 0) return;\n const [moved] = siblings.splice(sIdx, 1);\n\n const target = sIdx < position ? position - 1 : position;\n const clamped = Math.max(0, Math.min(target, siblings.length));\n if (clamped === sIdx) return;\n siblings.splice(clamped, 0, moved);\n const payload = siblings.map(g => ({ id: g.id, listName: g.listName, name: g.name, type: g.type }));\n await groupHandler.updateGroups(payload, { level: 0 });\n } else {\n const parentNestId = sourceNestId.split(\"_\").slice(0, -1).join(\"_\");\n const parentGroupData = groupHandler.getGroup({ nestId: parentNestId });\n if (!parentGroupData) return;\n const allChildren = Object.values(groupHandler.groups)\n .filter(g => g.nestId.startsWith(`${parentNestId}_`) && g.level === level && g.selected)\n .sort((a, b) => a.order - b.order);\n\n // \"+\" buttons for subgroups only live inside listSubgroups containers, so\n // drag-to-reorder is list-track only. Tab-subgroups carry through untouched.\n const lists = allChildren.filter(g => g.settings?.style !== \"tab\");\n const tabs = allChildren.filter(g => g.settings?.style === \"tab\");\n const sIdx = lists.findIndex(g => g.nestId === sourceNestId);\n if (sIdx < 0) return;\n const [moved] = lists.splice(sIdx, 1);\n const target = sIdx < position ? position - 1 : position;\n const clamped = Math.max(0, Math.min(target, lists.length));\n if (clamped === sIdx) return;\n lists.splice(clamped, 0, moved);\n\n const listPayload = lists.map(g => ({ id: g.id, listName: g.listName, name: g.name, type: g.type }));\n const tabPayload = tabs.map(g => ({ id: g.id, listName: g.listName, name: g.name, type: g.type }));\n await groupHandler.updateGroups([...listPayload, ...tabPayload], parentGroupData);\n }\n\n await groupHandler.saveGroups({ saveActor: true, saveUser: true });\n Hooks.callAll(\"forceUpdateTokenActionHud\");\n }\n\n /* -------------------------------------------- */\n /* ACTION EVENTS */\n /* -------------------------------------------- */\n\n /**\n * When an action is clicked.\n * @param {Event} event\n */\n static clickAction(event) {\n event.preventDefault();\n\n if (this.isUnlocked) {\n event.currentTarget?.blur?.();\n return;\n }\n\n if (event.button === 2) {\n const button = event.target?.closest?.(\"[data-part=\\\"actionButton\\\"]\");\n if (button?.dataset?.hasContextMenu === \"true\") {\n button.blur?.();\n return;\n }\n }\n\n this.hudManager.handleHudEvent(\"clickAction\", event);\n event.currentTarget?.blur?.();\n }\n\n /* -------------------------------------------- */\n\n /**\n * Handle when an action is hovered.\n * @param {Event} event\n */\n handleActionHover(event) {\n this.hudManager.handleHudEvent(\"hoverAction\", event);\n }\n\n /* -------------------------------------------- */\n /* HUD DRAG */\n /* -------------------------------------------- */\n\n /**\n * Drag event handler.\n * @private\n * @param {Event} event\n */\n #dragEvent(event) {\n if (!this.isDraggable) return;\n\n // Get the main element\n const element = this.element;\n\n const clientX = event.clientX ?? event.changedTouches[0].clientX;\n const clientY = event.clientY ?? event.changedTouches[0].clientY;\n\n // Initialise positions and starting positions\n let pos1 = 0;\n let pos2 = 0;\n let pos3 = clientX;\n let pos4 = clientY;\n const originalElementTop = element.offsetTop;\n const originalElementLeft = element.offsetLeft;\n let newElementTop = originalElementTop;\n let newElementLeft = originalElementLeft;\n\n /**\n * Mouse movement event handler.\n * @param {Event} event\n */\n const mouseMoveEvent = event => {\n const clientX = event.clientX ?? event.changedTouches[0].clientX;\n const clientY = event.clientY ?? event.changedTouches[0].clientY;\n pos1 = pos3 - clientX;\n pos2 = pos4 - clientY;\n pos3 = clientX;\n pos4 = clientY;\n\n // If the mouse has not moved, do not update\n if (pos1 === pos3 && pos2 === pos4) return;\n\n newElementTop = newElementTop - pos2;\n newElementLeft = newElementLeft - pos1;\n\n this.topPos = newElementTop;\n\n // Apply styles\n requestAnimationFrame(() => {\n Object.assign(element.style, { left: `${newElementLeft}px`, top: `${newElementTop}px` });\n });\n };\n\n /* -------------------------------------------- */\n\n /**\n * Mouse up event handler\n */\n const mouseUpEvent = () => {\n // Remove the mouse move and touch move events\n document.onmousemove = null;\n element.ontouchmove = null;\n\n // Remove the mouse up and touch end events\n document.onmouseup = null;\n element.ontouchend = null;\n\n // If position has not changed, do not update\n if (newElementTop === originalElementTop && newElementLeft === originalElementLeft) return;\n\n this.topPos = newElementTop;\n\n this.#applyDirection();\n\n // Save the new position to the user's flags\n this.hudPosition = { top: newElementTop, left: newElementLeft };\n };\n\n // Bind mouse move and touch move events\n document.onmousemove = mouseMoveEvent;\n element.ontouchmove = mouseMoveEvent;\n\n // Bind mouse up and touch end events\n document.onmouseup = mouseUpEvent;\n element.ontouchend = mouseUpEvent;\n }\n\n /* -------------------------------------------- */\n /* POSITION */\n /* -------------------------------------------- */\n\n /**\n * Set position of the HUD\n * @public\n */\n setPosition() {\n if (!this.hudManager.hud) return;\n if (this.isDocked) {\n this.#setDockedPosition();\n } else {\n this.#setUndockedPosition();\n }\n }\n\n /* -------------------------------------------- */\n\n /**\n * Set docked position\n */\n #setDockedPosition() {\n this.element.style.top = 0;\n this.element.style.left = 0;\n\n const interfaceElement = document.querySelector(\"#interface\");\n const dockPosition = this.systemManager.styles[this.setting.style]?.dockPosition;\n const isV13 = foundry.utils.isNewerVersion(game.version, \"12.999\");\n\n switch (dockPosition) {\n case \"right\":\n if (isV13) {\n const sidebarElement = document.querySelector(\"#sidebar\");\n sidebarElement.prepend(this.element);\n } else {\n interfaceElement.appendChild(this.element);\n }\n break;\n case \"center-right\":\n const rightUiElement = interfaceElement.querySelector(\"#ui-right\");\n if (isV13) {\n rightUiElement.prepend(this.element);\n } else {\n interfaceElement.insertBefore(this.element, rightUiElement);\n }\n break;\n case \"left\":\n const leftUiElement = interfaceElement.querySelector(\"#ui-left\");\n if (isV13) {\n leftUiElement.prepend(this.element);\n } else {\n interfaceElement.insertBefore(this.element, leftUiElement);\n }\n break;\n }\n }\n\n /* -------------------------------------------- */\n\n /**\n * Set undocked position\n */\n #setUndockedPosition() {\n document.body.appendChild(this.element);\n this.#setPositionFromFlag();\n this.#applyDirection();\n }\n\n /* -------------------------------------------- */\n\n /**\n * Set the position of the HUD based on user flag\n * @private\n */\n #setPositionFromFlag() {\n if (!this.hudPosition) {\n this.element.style.top = `${HUD.DEFAULT_TOP_POS}px`;\n this.element.style.left = `${HUD.DEFAULT_LEFT_POS}px`;\n return;\n }\n\n return new Promise(resolve => {\n const check = () => {\n if (this.element) {\n this.element.style.bottom = null;\n this.topPos = this.hudPosition.top < 5 || this.hudPosition.top > window.innerHeight + 5\n ? HUD.DEFAULT_TOP_POS\n : this.hudPosition.top ?? HUD.DEFAULT_TOP_POS;\n this.leftPos = this.hudPosition.left < 5 || this.hudPosition.left > window.innerWidth + 5\n ? HUD.DEFAULT_LEFT_POS\n : this.hudPosition.left ?? HUD.DEFAULT_LEFT_POS;\n this.element.style.top = `${this.topPos}px`;\n this.element.style.left = `${this.leftPos}px`;\n resolve();\n } else {\n setTimeout(check, 10);\n }\n };\n\n check();\n });\n }\n\n /* -------------------------------------------- */\n /* RESET */\n /* -------------------------------------------- */\n\n /**\n * Reset the position of the HUD\n * @public\n */\n async resetPosition() {\n Logger.debug(\"Resetting position...\");\n this.hudPosition = { top: HUD.DEFAULT_TOP_POS, left: HUD.DEFAULT_LEFT_POS };\n }\n\n /* -------------------------------------------- */\n\n /**\n * Copy user's data to others users\n * @public\n * @param {string} fromUserId The user id to copy from\n * @param {string | Array} toUserIds The user ids to copy to\n */\n async copy(fromUserId, toUserIds) {\n await this.#copyUserData(fromUserId, toUserIds);\n }\n\n /* -------------------------------------------- */\n\n /**\n * Copy user's data to others users\n * @private\n * @param {string} fromUserId The user id to copy from\n * @param {string | Array} toUserIds The user ids to copy to\n */\n async #copyUserData(fromUserId, toUserIds) {\n if (!game.user.isGM) {\n Logger.info(\"Copy failed: User is not a GM\", true);\n return;\n }\n // Exit if parameters are missing\n if (!fromUserId || !toUserIds.length) {\n Logger.info(\"Copy failed: Parameters missing\", true);\n return;\n }\n\n Logger.debug(\"Copying user data to users...\");\n\n const fromGroup = await this.dataHandler.getDataAsGm({ type: \"user\", id: fromUserId });\n\n if (typeof toUserIds === \"string\") {\n await this.dataHandler.saveDataAsGm(\"user\", toUserIds, fromGroup);\n } else if (Array.isArray(toUserIds)) {\n for (const userId of toUserIds) {\n await this.dataHandler.saveDataAsGm(\"user\", userId, fromGroup);\n }\n }\n\n Logger.debug(\"User data copied to users\");\n }\n\n /* -------------------------------------------- */\n\n /**\n * Reset the HUD layout with the socket\n */\n static async resetLayoutWithSocket() {\n game?.tokenActionHud?.resetLayout();\n }\n\n /* -------------------------------------------- */\n\n /**\n * Reset the HUD layout\n */\n async resetLayout() {\n Logger.debug(\"Resetting layout...\");\n await this.resetUserAndActorData();\n this.resetPosition();\n Logger.debug(\"Layout reset\");\n }\n\n /* -------------------------------------------- */\n\n /**\n * Reset current actor's HUD data\n */\n async resetActorData() {\n Logger.debug(\"Resetting actor data...\");\n\n await this.dataHandler.saveDataAsGm(\"actor\", this.hudManager.actor.id, {});\n\n Logger.debug(\"Actor data reset\");\n\n this.hudManager.hardResetHud();\n const trigger = { trigger: { type: \"method\", name: \"TokenActionHud#resetActorData\" } };\n this.update(trigger);\n }\n\n /* -------------------------------------------- */\n\n /**\n * Reset every actor's HUD data\n * @public\n */\n async resetAllActorData() {\n Logger.debug(\"Resetting all actor data...\");\n\n for (const actor of game.actors) {\n Logger.debug(`Resetting flags for actor [${actor.id}]`, { actor });\n await this.dataHandler.saveDataAsGm(\"actor\", actor.id, {});\n }\n\n Logger.debug(\"All actor data reset\");\n this.hudManager.hardResetHud();\n const trigger = { trigger: { type: \"method\", name: \"TokenActionHud#resetAllActorData\" } };\n this.update(trigger);\n }\n\n /* -------------------------------------------- */\n\n /**\n * Reset user's HUD data\n * @public\n */\n async resetUserData() {\n Logger.debug(\"Resetting user data...\");\n await this.dataHandler.saveDataAsGm(\"user\", game.userId, {});\n Logger.debug(\"User data reset\");\n this.hudManager.hardResetHud();\n const trigger = { trigger: { type: \"method\", name: \"TokenActionHud#resetUserData\" } };\n this.update(trigger);\n }\n\n /* -------------------------------------------- */\n\n /**\n * Reset every user's HUD data\n * @public\n */\n async resetAllUserData() {\n Logger.debug(\"Resetting all user data...\");\n for (const user of game.users) {\n await this.dataHandler.saveDataAsGm(\"user\", user.id, {});\n }\n Logger.debug(\"All user data reset\");\n this.hudManager.hardResetHud();\n const trigger = { trigger: { type: \"method\", name: \"TokenActionHud#resetAllUserData\" } };\n this.update(trigger);\n }\n\n /* -------------------------------------------- */\n\n /**\n * Reset user and actor's HUD data\n */\n async resetUserAndActorData() {\n Logger.debug(\"Resetting user data...\");\n await this.dataHandler.saveDataAsGm(\"user\", game.userId, {});\n Logger.debug(\"User data reset\");\n\n Logger.debug(\"Resetting actor data...\");\n await this.dataHandler.saveDataAsGm(\"actor\", this.hudManager.actor.id, {});\n Logger.debug(\"Actor data reset\");\n\n this.hudManager.hardResetHud();\n const trigger = { trigger: { type: \"method\", name: \"TokenActionHud#resetUserAndActorData\" } };\n this.update(trigger);\n }\n\n /* -------------------------------------------- */\n /* UPDATE / CLOSE */\n /* -------------------------------------------- */\n\n /**\n * Update the HUD.\n * @public\n * @param {object} trigger\n */\n async update(trigger = null) {\n // Stops settings updates from triggering the HUD update multiple times\n // Instead an update is triggered when settings are updated and the settings config window is closed\n if (trigger?.name === \"closeSettingsConfig\") {\n if (!this.updateSettingsPending) return;\n this.updateSettingsPending = false;\n Logger.debug(\"Settings updated\");\n }\n\n await this.#handleUpdate();\n await this.#performUpdate(trigger);\n }\n\n /* -------------------------------------------- */\n\n /**\n * Handles HUD updates to avoid overlapping updates.\n */\n async #handleUpdate() {\n // Start a timer and reset it each time an update call is received before the timer has elapsed\n if (this.isUpdatePending) this.updatePendingTimer.abort();\n\n this.isUpdatePending = true;\n await this.updatePendingTimer.start();\n this.isUpdatePending = false;\n\n // Wait for the current update to complete before progressing a pending update\n // Stop waiting if the current update takes longer than 5 seconds\n const waitForUpdateCompletion = async () => {\n const maxWaitTime = 5000;\n const interval = 10;\n const iterations = maxWaitTime / interval;\n\n let i = 0;\n while (i < iterations && this.isUpdating) {\n await this.updateTimer.start();\n i++;\n }\n\n return !this.isUpdating;\n };\n\n if (this.isUpdating) {\n const hasCompleted = await waitForUpdateCompletion();\n if (!hasCompleted) {\n Logger.debug(\"Update took too long. Aborting...\");\n }\n }\n }\n\n /* -------------------------------------------- */\n\n /**\n * Perform the HUD update following handling.\n * @param {object} trigger\n */\n async #performUpdate(trigger) {\n this.isUpdating = true;\n Logger.debug(\"Updating HUD...\", trigger);\n\n // Await does have an effect\n const initialised = await this.hudManager.init(trigger);\n if (!initialised) {\n this.#abortUpdate();\n return;\n }\n\n Hooks.callAll(\"tokenActionHudCorePreRender\", this.hudManager.hud, this.hudManager);\n\n this.rendering = true;\n this.render({ force: true, position: {} });\n\n this.isUpdating = false;\n\n Hooks.callAll(\"tokenActionHudCoreHudUpdated\", MODULE);\n Logger.debug(\"HUD updated\");\n }\n\n /* -------------------------------------------- */\n\n /**\n * Abort the HUD update with a debug message.\n * @private\n */\n #abortUpdate() {\n this.#close();\n Logger.debug(\"HUD update aborted as no character(s) found or HUD is disabled\");\n this.isUpdating = false;\n }\n\n /* -------------------------------------------- */\n\n /**\n * Close the HUD\n * @public\n */\n closeHud() {\n this.#close();\n }\n\n /* -------------------------------------------- */\n\n /**\n * Close the HUD\n * @private\n */\n #close() {\n requestAnimationFrame(() => {\n this.element?.classList?.remove(\"tah-expanded\");\n this.element?.classList?.add(\"tah-closed\");\n });\n\n this.openGroups = new Set();\n this.closeTimer = setTimeout(() => {\n this.close({ animate: false });\n }, 500);\n }\n\n /* -------------------------------------------- */\n /* TOKEN / ACTOR VALIDATION */\n /* -------------------------------------------- */\n\n /**\n * Whether the token change is valid for a HUD update.\n * @public\n * @param {object} token\n * @param {object} data\n * @returns {boolean} Whether the token change is valid for a HUD update\n */\n isValidTokenChange(token, data = null) {\n if (data.flags) return false;\n return this.#isRelevantToken(token) || (Utils.getSetting(\"alwaysShowHud\") && token.actorId === game.user.character?.id);\n }\n\n /* -------------------------------------------- */\n\n /**\n * Whether the token is controlled or on the canvas.\n * @private\n * @param {object} token\n * @returns {boolean} Whether the token is controlled or on the canvas\n */\n #isRelevantToken(token) {\n const controlledTokens = Utils.getControlledTokens();\n return (\n controlledTokens?.some(controlledToken => controlledToken.id === token.id)\n || (!controlledTokens?.length\n && canvas?.tokens?.placeables?.some(token => token.id === this.hudManager.token?.id))\n );\n }\n\n /* -------------------------------------------- */\n\n /**\n * Whether the given actor is the selected actor.\n * @param {object} actor\n * @returns {boolean} Whether the given actor is the selected actor\n */\n isControlledActor(actor) {\n return actor?.id === this.hudManager.actor?.id;\n }\n\n /* -------------------------------------------- */\n\n /**\n * Whether the actor or item update is valid for a HUD update.\n * @param {object} actor\n * @param {object} data\n * @returns {boolean} Whether the actor or item update is valid for a HUD update\n */\n isValidActorOrItemUpdate(actor, data) {\n if (!actor) {\n Logger.debug(\"No actor; updating HUD\", { data });\n return true;\n }\n\n if (this.isControlledActor(actor)) {\n Logger.debug(\"Same actor; updating HUD\", { actor, data });\n return true;\n } else {\n Logger.debug(\"Different actor; skipping HUD update\", { actor, data });\n return false;\n }\n }\n /* -------------------------------------------- */\n /* STATE */\n /* -------------------------------------------- */\n\n /**\n * The direction the HUD will expand.\n * @private\n * @returns {string} \"up\" or \"down\"\n */\n get direction() {\n const direction = Utils.getSetting(\"direction\");\n if (direction === \"up\" || (direction === \"auto\" && this.topPos > window.innerHeight / 2)) return \"up\";\n return \"down\";\n }\n\n /* -------------------------------------------- */\n\n /**\n * Get HUD position.\n * @returns {object} {top, left}\n */\n get hudPosition() {\n return Utils.getUserFlag(\"position\");\n }\n\n /* -------------------------------------------- */\n\n /**\n * Set HUD position.\n * @param {object} obj {top, left}\n */\n set hudPosition(obj) {\n Utils.setUserFlag(\"position\", obj);\n Logger.debug(`Position set to x: ${obj.top}px, y: ${obj.left}px`);\n }\n\n /* -------------------------------------------- */\n\n /**\n * Whether the HUD is enabled.\n * @returns {boolean} Whether the HUD is enabled\n */\n get isEnabled() {\n return Utils.getSetting(\"enable\");\n }\n\n set isEnabled(bool) {\n Utils.setSetting(\"enable\", bool);\n }\n\n /* -------------------------------------------- */\n\n /**\n * Whether the HUD is collapsed.\n * @returns {boolean} Whether the HUD is collapsed\n */\n get isCollapsed() {\n return Utils.getUserFlag(\"isCollapsed\");\n }\n\n set isCollapsed(bool) {\n Utils.setUserFlag(\"isCollapsed\", bool);\n }\n\n /* -------------------------------------------- */\n\n /**\n * Whether the HUD is docked.\n * @returns {boolean} Whether the HUD is docked\n */\n get isDocked() {\n const style = this.systemManager.styles[this.setting.style] ?? this.systemManager.styles.foundryVTT;\n return style?.isDocked || style?.dockPosition;\n }\n\n /* -------------------------------------------- */\n\n /**\n * Whether the HUD is unlocked.\n * @returns {boolean} Whether the HUD is unlocked\n */\n get isUnlocked() {\n return Utils.getUserFlag(\"isUnlocked\");\n }\n\n set isUnlocked(bool) {\n Utils.setUserFlag(\"isUnlocked\", bool);\n }\n\n /* -------------------------------------------- */\n\n /**\n * Whether the HUD is draggable.\n * @returns {boolean} Whether the HUD is draggable\n */\n get isDraggable() {\n const drag = Utils.getSetting(\"drag\");\n return ((drag === \"always\") || (drag === \"whenUnlocked\" && this.isUnlocked));\n }\n\n /* -------------------------------------------- */\n\n /**\n * The HUD scale.\n * @private\n * @returns {number} HUD scale\n */\n get scale() {\n if (this.isDocked) return 1;\n const scale = parseFloat(Utils.getSetting(\"scale\")) || 1;\n return Math.min(Math.max(scale, 0.5), 2);\n }\n}\n","import { MODULE } from \"./constants.mjs\";\nimport { DataHandler } from \"../handlers/data-handler.mjs\";\nimport { TokenActionHud } from \"../applications/token-action-hud.mjs\";\n\nlet socket;\n\n/**\n * Register socket with socketlib module.\n */\nexport function registerSocket() {\n socket = socketlib.registerModule(MODULE.ID);\n socket.register(\"getFilePaths\", DataHandler.getFilePathsWithSocket);\n socket.register(\"getData\", DataHandler.getDataWithSocket);\n socket.register(\"saveData\", DataHandler.saveDataWithSocket);\n socket.register(\"reset\", TokenActionHud.resetLayoutWithSocket);\n}\n\n/* -------------------------------------------- */\n\n/**\n * Whether the socketlib module is active.\n * @returns {boolean} Whether the socketlib module is active\n */\nexport function isSocketlibActive() {\n if (game.modules.get(\"socketlib\")?.active) return true;\n\n Logger.error(\"This module requires the 'socketlib' module to be installed and enabled.\", true);\n return false;\n}\n\n/* -------------------------------------------- */\n\n/**\n * Get the socket.\n * @returns {object} Socket\n */\nexport function getSocket() {\n return socket;\n}\n","import { GROUP_TYPE } from \"../../core/constants.mjs\";\nimport { Utils } from \"../../core/utils.mjs\";\n\n/**\n * Handler for building the HUD's generic actions.\n */\nexport class GenericActionHandler {\n constructor(actionHandler) {\n this.actionHandler = actionHandler;\n this.actor = actionHandler.actor;\n this.token = actionHandler.token;\n }\n\n /* -------------------------------------------- */\n /* BUILD */\n /* -------------------------------------------- */\n\n /**\n * Build generic actions.\n * @public\n */\n buildActions() {\n this.#buildUtilities();\n }\n\n /* -------------------------------------------- */\n\n /**\n * Build utilities.\n * @private\n */\n #buildUtilities() {\n if (this.actor) {\n this.#buildSingleTokenUtilities();\n } else {\n this.#buildMultipleTokenUtilities();\n }\n }\n\n /* -------------------------------------------- */\n\n /**\n * Build utilities for a single token.\n * @private\n */\n #buildSingleTokenUtilities() {\n if (!this.token) return;\n const actionsData = [];\n\n // Build Toggle Combat action\n const toggleCombatId = \"toggleCombat\";\n const toggleCombatName = this.token?.inCombat\n ? game.i18n.localize(\"tokenActionHud.removeFromCombat\")\n : game.i18n.localize(\"tokenActionHud.addToCombat\");\n const toggleCombatAction = {\n id: toggleCombatId,\n name: toggleCombatName,\n onClick: async () => {\n const token = Utils.getFirstControlledToken();\n token.document.toggleCombatant();\n\n }\n };\n actionsData.push(toggleCombatAction);\n\n // Build Toggle Visibility action\n if (game.user.isGM) {\n const toggleVisibilityId = \"toggleVisibility\";\n const toggleVisibilityName = this.token?.document?.hidden\n ? game.i18n.localize(\"tokenActionHud.makeVisible\")\n : game.i18n.localize(\"tokenActionHud.makeInvisible\");\n const toggleVisibilityAction = {\n id: toggleVisibilityId,\n name: toggleVisibilityName,\n onClick: async () => {\n const token = Utils.getFirstControlledToken();\n const isHidden = token.document.hidden;\n await token.document.update({ hidden: !isHidden });\n }\n };\n actionsData.push(toggleVisibilityAction);\n }\n\n const groupData = { id: \"token\", type: GROUP_TYPE.SYSTEM };\n\n // Add actions to HUD\n this.actionHandler.addActions(actionsData, groupData);\n }\n\n /* -------------------------------------------- */\n\n /**\n * Build utilities for multiple tokens.\n * @private\n */\n #buildMultipleTokenUtilities() {\n const tokens = Utils.getControlledTokens();\n const actionsData = [];\n\n // Toggle Combat\n const toggleCombatId = \"toggleCombat\";\n const toggleCombatName = tokens.every(token => token.inCombat)\n ? game.i18n.localize(\"tokenActionHud.removeFromCombat\")\n : game.i18n.localize(\"tokenActionHud.addToCombat\");\n const toggleCombatAction = {\n id: toggleCombatId,\n name: toggleCombatName,\n onClick: async () => {\n const controlledTokens = Utils.getControlledTokens();\n for (const token of controlledTokens) {\n await token.document.toggleCombatant();\n }\n }\n };\n actionsData.push(toggleCombatAction);\n\n // Toggle Visibility\n if (game.user.isGM) {\n const toggleVisibilityId = \"toggleVisibility\";\n const toggleVisibilityname = tokens.every(token => token.document?.hidden)\n ? game.i18n.localize(\"tokenActionHud.makeVisible\")\n : game.i18n.localize(\"tokenActionHud.makeInvisible\");\n const toggleVisibilityAction = {\n id: toggleVisibilityId,\n name: toggleVisibilityname,\n onClick: async () => {\n const controlledTokens = Utils.getControlledTokens();\n for (const token of controlledTokens) {\n const isHidden = token.document.hidden;\n await token.document.update({ hidden: !isHidden });\n }\n }\n };\n actionsData.push(toggleVisibilityAction);\n }\n\n const groupData = { id: \"token\", type: GROUP_TYPE.SYSTEM };\n\n // Add actions to HUD\n this.actionHandler.addActions(actionsData, groupData);\n }\n}\n","import { ACTION_TYPE, COMPENDIUM_PACK_TYPES } from \"../../core/constants.mjs\";\nimport { Utils } from \"../../core/utils.mjs\";\n\n/**\n * Handler for building the HUD's compendium actions.\n */\nexport class CompendiumActionHandler {\n actionHandler;\n\n compendiumActions;\n\n packIds;\n\n constructor(actionHandler) {\n this.actionHandler = actionHandler;\n this.compendiumActions = new Map();\n this.packIds = [];\n }\n\n /* -------------------------------------------- */\n /* BUILD */\n /* -------------------------------------------- */\n\n /**\n * Build compendium actions.\n */\n async buildActions() {\n if (!Utils.getSetting(\"enableCompendiumActions\")) return;\n\n if (this.compendiumActions.size === 0) {\n this.packIds = game.packs\n .filter(\n pack =>\n COMPENDIUM_PACK_TYPES.includes(pack.documentName)\n && (foundry.utils.isNewerVersion(game.version, \"10\") ? pack.visible : !pack.private || game.user.isGM)\n )\n .map(pack => pack.metadata.id);\n\n if (this.packIds.length === 0) return;\n\n await Promise.all(this.packIds.map(packId => this.#setActions(packId)));\n }\n\n for (const pack of this.compendiumActions.values()) {\n this.actionHandler.addActions(pack.actions, pack.groupData);\n }\n }\n\n /* -------------------------------------------- */\n\n /**\n * Set compendium actions into the compendiumActions map.\n * @param {string} packId\n */\n async #setActions(packId) {\n const pack = game.packs.get(packId);\n const entries = pack ? pack.index.size > 0 ? pack.index : await pack.getIndex() : null;\n if (!entries) return;\n const actionType = this.#getCompendiumActionType(pack?.documentName);\n if (!actionType) return;\n const actions = entries.map(entry => (\n this.actionHandler.createAction(\n {\n id: entry._id,\n name: entry.name,\n listName: `${game.i18n.localize(ACTION_TYPE[actionType])}: ${entry.name}`,\n img: Utils.getImage(entry),\n onClick: this.#getOnClick(actionType, pack, entry._id)\n })\n ));\n const groupData = { id: this.#getGroupId(packId), type: \"core\" };\n this.compendiumActions.set(packId, { actions, groupData });\n }\n\n /* -------------------------------------------- */\n /* HELPERS */\n /* -------------------------------------------- */\n\n /**\n * Get compendium action type based on document name.\n * @param {string} documentName\n * @returns {string} Compendium action type\n */\n #getCompendiumActionType(documentName) {\n switch (documentName) {\n case \"Macro\":\n return \"compendiumMacro\";\n default:\n return \"compendiumEntry\";\n }\n }\n\n /* -------------------------------------------- */\n\n /**\n * Get on click function.\n * @param {string} actionType\n * @param {object} pack\n * @param {string} documentId\n * @returns {Function}\n */\n #getOnClick(actionType, pack, documentId) {\n switch (actionType) {\n case \"compendiumMacro\":\n return this.#getOnClickFunction(pack, documentId);\n default:\n return this.#getOnClickEntry(pack, documentId);\n }\n }\n\n /* -------------------------------------------- */\n\n /**\n * Get on click function for compendium journal entry.\n * @param {object} pack\n * @param {string} documentId\n * @returns {Function}\n */\n #getOnClickEntry(pack, documentId) {\n return async () => {\n const journalEntry = await pack.getDocument(documentId);\n journalEntry.sheet.render(true); };\n }\n\n /* -------------------------------------------- */\n\n /**\n * Get on click function for compendium macro.\n * @param {object} pack\n * @param {string} documentId\n * @returns {Function}\n */\n #getOnClickFunction(pack, documentId) {\n return async () => {\n await pack.getDocument(documentId).then(macro => macro.execute());\n };\n }\n\n /* -------------------------------------------- */\n\n /**\n * Get the group ID from the pack ID.\n * @param {string} packId\n * @returns {string} Group ID\n */\n #getGroupId(packId) {\n return packId.replace(\".\", \"-\");\n }\n\n /* -------------------------------------------- */\n /* LOOKUPS */\n /* -------------------------------------------- */\n\n /**\n * Whether the compendium is linked.\n * @public\n * @param {string} packId\n * @returns {boolean} Whether the compendium is linked\n */\n isLinkedCompendium(packId) {\n return (this.packIds.length)\n ? this.packIds?.includes(packId)\n : false;\n }\n}\n","import { ACTION_TYPE } from \"../../core/constants.mjs\";\nimport { Utils } from \"../../core/utils.mjs\";\n\n/**\n * Handler for building the HUD's macro actions.\n */\nexport class MacroActionHandler {\n constructor(actionHandler) {\n this.actionHandler = actionHandler;\n }\n\n /* -------------------------------------------- */\n /* RESET */\n /* -------------------------------------------- */\n\n /**\n * Clear cached macro actions.\n */\n clearCache() {\n this.macroActions = null;\n }\n\n /* -------------------------------------------- */\n /* BUILD */\n /* -------------------------------------------- */\n\n /**\n * Build macro actions.\n * @override\n */\n async buildActions() {\n if (!Utils.getSetting(\"enableMacroActions\")) return;\n\n if (!this.macroActions) {\n this.macroActions = {\n actions: await this.#getActions(),\n groupData: { id: \"macros\", type: \"core\" }\n };\n }\n\n this.actionHandler.addActions(this.macroActions.actions, this.macroActions.groupData);\n }\n\n /* -------------------------------------------- */\n\n /**\n * Get actions.\n * @private\n * @returns {object} Actions\n */\n async #getActions() {\n const actionType = \"macro\";\n const macros = game.macros.filter(macro => this.#hasPermission(macro));\n\n return macros.map(macro =>\n this.actionHandler.createAction({\n id: macro.id,\n name: macro.name,\n listName: this.#getListName(actionType, macro.name),\n img: Utils.getImage(macro),\n onClick: () => {\n game.macros.get(macro.id).execute();\n }\n })\n );\n }\n\n /* -------------------------------------------- */\n /* HELPERS */\n /* -------------------------------------------- */\n\n /**\n * Check if the user has permission for the macro.\n * @private\n * @param {object} macro\n * @returns {boolean} Whether the user has permission\n */\n #hasPermission(macro) {\n const { ownership } = macro;\n return ownership[game.userId] ? ownership[game.userId] > 0 : ownership.default > 0;\n }\n\n /* -------------------------------------------- */\n\n /**\n * Get list name.\n * @param {string} actionType\n * @param {string} name Action name\n * @returns {string} List name\n */\n #getListName(actionType, name) {\n const actionTypeName = `${game.i18n.localize(ACTION_TYPE[actionType])}: ` ?? \"\";\n return `${actionTypeName}${name}`;\n }\n}\n","import { DELIMITER } from \"../../core/constants.mjs\";\nimport { GenericActionHandler } from \"./generic-action-handler.mjs\";\nimport { CompendiumActionHandler } from \"./compendium-action-handler.mjs\";\nimport { MacroActionHandler } from \"./macro-action-handler.mjs\";\nimport { getTooltip } from \"../tooltip-handler.mjs\";\nimport { Logger, Utils } from \"../../core/utils.mjs\";\n\n/**\n * Handler for the HUD actions.\n */\nexport class ActionHandler {\n constructor() {\n this.hudManager = {};\n this.groupHandler = {};\n this.genericActionHandler = new GenericActionHandler(this);\n this.compendiumActionHandler = new CompendiumActionHandler(this);\n this.macroActionHandler = new MacroActionHandler(this);\n this.actions = [];\n this.availableActions = new Map();\n this.delimiter = DELIMITER;\n this.actionHandlerExtenders = [];\n }\n\n /* -------------------------------------------- */\n /* RESET */\n /* -------------------------------------------- */\n\n /**\n * Soft reset variables.\n */\n softReset() {\n this.genericActionHandler = new GenericActionHandler(this);\n this.actions = [];\n this.availableActions = new Map();\n }\n\n /* -------------------------------------------- */\n /* PREPARE */\n /* -------------------------------------------- */\n\n /**\n * Prepare actions.\n * @param {object} groups HUD groups\n */\n prepareActions(groups) {\n for (const group of Object.values(groups)) {\n if (group.actions?.length) {\n this.actions.push(...group.actions);\n for (const action of group.actions) {\n action.selected = false;\n }\n }\n }\n }\n\n /* -------------------------------------------- */\n /* BUILD */\n /* -------------------------------------------- */\n\n /**\n * Build actions.\n */\n async buildActionsCore() {\n await Promise.all([\n this.#buildSystemActionsCore(),\n this.#buildGenericActionsCore(),\n this.#buildCompendiumActionsCore(),\n this.#buildMacroActionsCore()\n ]);\n await this.#buildExtendedActionsCore();\n this.#updateNonPresetActions();\n this.#setCharacterLimit();\n }\n\n /* -------------------------------------------- */\n\n /**\n * Build system-specific actions.\n * @private\n */\n async #buildSystemActionsCore() {\n Logger.debug(\"Building system actions...\", { actor: this.actor, token: this.token });\n const groupIds = this.groupHandler.getGroupIds();\n await this.buildSystemActions(groupIds);\n Logger.debug(\"System actions built\", { hud: this.hud, actor: this.actor, token: this.token });\n }\n\n /* -------------------------------------------- */\n\n /**\n * Placeholder function for the system module.\n * @override\n * @param {Array} groupIds List of group IDs\n */\n async buildSystemActions(groupIds) {}\n\n /* -------------------------------------------- */\n\n /**\n * Build compendium-specific actions.\n * @private\n */\n async #buildCompendiumActionsCore() {\n Logger.debug(\"Building compendium actions...\");\n await this.compendiumActionHandler.buildActions();\n Logger.debug(\"Compendium actions built\", { hud: this.hud });\n }\n\n /* -------------------------------------------- */\n\n /**\n * Build generic actions.\n * @private\n */\n #buildGenericActionsCore() {\n Logger.debug(\"Building generic actions...\", { actor: this.actor, token: this.token });\n this.genericActionHandler.buildActions();\n Logger.debug(\"Generic actions built\", { hud: this.hud, actor: this.actor, token: this.token });\n }\n\n /* -------------------------------------------- */\n\n /**\n * Build macro-specific actions.\n * @private\n */\n async #buildMacroActionsCore() {\n Logger.debug(\"Building macro actions...\");\n await this.macroActionHandler.buildActions();\n Logger.debug(\"Macro actions built\", { hud: this.hud });\n }\n\n /* -------------------------------------------- */\n\n /**\n * Build extended actions.\n * @private\n */\n async #buildExtendedActionsCore() {\n await Promise.all(this.actionHandlerExtenders.map(\n async extender => await extender.extendActionHandler()\n ));\n }\n\n /* -------------------------------------------- */\n\n /**\n * Update non-preset actions.\n * @private\n */\n #updateNonPresetActions() {\n const nonPresetActions = this.actions.filter(action => !action?.isPreset);\n\n for (const nonPresetAction of nonPresetActions) {\n const availableAction = this.availableActions.get(nonPresetAction.id);\n\n if (availableAction) {\n const systemSelected = availableAction.systemSelected ?? nonPresetAction.systemSelected;\n const userSelected = nonPresetAction.userSelected ?? availableAction.userSelected;\n Object.assign(nonPresetAction, this.createAction({ ...availableAction, systemSelected, userSelected }));\n }\n }\n }\n\n /* -------------------------------------------- */\n\n /**\n * Set character limit for action names based on the 'Character per Word' setting.\n * @private\n */\n #setCharacterLimit() {\n const groups = this.groupHandler.getGroups({ level: 1 });\n\n for (const group of groups) {\n const groupCharacterCount = group?.settings?.characterCount;\n\n const subgroups = this.groupHandler.getGroups({ nestId: group.nestId });\n\n for (const subgroup of subgroups) {\n const actions = subgroup.actions;\n if (!actions?.length) continue;\n\n const subgroupCharacterCount = subgroup?.settings?.characterCount;\n const characterCount = (subgroupCharacterCount >= 0)\n ? subgroupCharacterCount\n : groupCharacterCount;\n\n // Exit if character limit is not defined\n if ((!characterCount && characterCount !== 0) || characterCount < 0) continue;\n\n for (const action of actions) {\n if (action.name.length <= characterCount) continue;\n if (characterCount === 0) {\n action.name = \"\";\n continue;\n }\n // Set each word to the character limit\n action.name = action.name\n .split(\" \")\n .map(word => word.slice(0, characterCount))\n .join(\" \");\n }\n }\n }\n }\n\n /* -------------------------------------------- */\n\n /**\n * Whether actions should be sorted.\n * @private\n * @param {object} group\n * @returns {boolean}\n */\n #shouldSortActions(group) {\n if (group?.settings?.sort !== undefined) return !!group.settings.sort;\n const topLevelNestId = group?.nestId?.split(\"_\")[0];\n if (topLevelNestId && topLevelNestId !== group.nestId) {\n const topLevelGroup = this.groupHandler.getGroup({ nestId: topLevelNestId });\n if (topLevelGroup?.settings?.sort !== undefined) return !!topLevelGroup.settings.sort;\n }\n return !!Utils.getSetting(\"sortActions\");\n }\n\n /* -------------------------------------------- */\n /* LOOKUPS */\n /* -------------------------------------------- */\n\n /**\n * Get actions by ID.\n * @public\n * @param {object} actionData\n * @returns {Array} List of actions\n */\n getActions(actionData) {\n return this.actions.filter(action => action.id === actionData.id);\n }\n\n /* -------------------------------------------- */\n /* CREATE / UPDATE */\n /* -------------------------------------------- */\n\n /**\n * Create action object.\n * @public\n * @param {object} actionData\n * @returns {object} Action\n */\n createAction(actionData) {\n const fullName = actionData.fullName ?? actionData.name;\n const tooltip = getTooltip(actionData.tooltip, fullName);\n\n const infoProps = info => {\n if (!info) return {};\n return {\n ...(info.class && { class: info.class }),\n ...(info.icon && { icon: info.icon }),\n ...(info.text && { text: info.text }),\n ...(info.title && { title: info.title })\n };\n };\n\n return {\n id: actionData.id,\n name: actionData.name ?? actionData.id ?? \"\",\n fullName,\n listName: actionData.listName || actionData.name || actionData.id || \"\",\n ...(actionData.onClick && { onClick: actionData.onClick }),\n ...(actionData.onHover && { onClick: actionData.onHover }),\n ...(actionData.encodedValue && { encodedValue: actionData.encodedValue }),\n ...(actionData.cssClass && { cssClass: actionData.cssClass }),\n icons: actionData.icons || {},\n ...(actionData.icon1 && { icon1: actionData.icon1 }),\n ...(actionData.icon2 && { icon2: actionData.icon2 }),\n ...(actionData.icon3 && { icon3: actionData.icon3 }),\n ...(actionData.img && { img: actionData.img }),\n ...(actionData.hasContextMenu && { hasContextMenu: actionData.hasContextMenu }),\n info1: infoProps(actionData.info1),\n info2: infoProps(actionData.info2),\n info3: infoProps(actionData.info3),\n system: actionData.system || {},\n isAction: true,\n ...(actionData.isItem && { isItem: actionData.isItem }),\n ...(actionData.isPreset && { isPreset: actionData.isPreset }),\n userSelected: actionData.userSelected ?? true,\n systemSelected: actionData.systemSelected ?? true,\n selected: actionData.systemSelected\n ? actionData.userSelected ?? actionData.systemSelected ?? true\n : false,\n tooltip,\n ...(actionData.useRawHtmlName && { useRawHtmlName: actionData.useRawHtmlName })\n };\n }\n\n /* -------------------------------------------- */\n\n /**\n * Add actions to the HUD.\n * @public\n * @param {object} actionsData\n * @param {object} groupData\n */\n addActions(actionsData, groupData) {\n if (!actionsData.length) return;\n\n // Create actions\n const actions = new Map(actionsData.map(actionData => [\n actionData.id,\n (actionData.isAction) ? actionData : this.createAction(actionData)]\n ));\n this.#addToAvailableActions(actions);\n\n if (!groupData?.id) return;\n\n if (!groupData?.type) { groupData.type = \"system\"; }\n\n const groups = this.groupHandler.getGroups(groupData);\n\n if (!groups.length) return;\n\n for (const group of groups) {\n // Get existing actions\n const existingActions = new Map(group.actions.map(action => [action.id, action]));\n\n const reorderedActions = [];\n\n // Loop the previously saved actions in the group\n existingActions.forEach((existingAction, existingActionId) => {\n const action = actions.get(existingActionId);\n if (action) {\n const systemSelected = action.systemSelected ?? existingAction.systemSelected;\n const userSelected = existingAction.userSelected ?? action.userSelected;\n const selected = (!systemSelected)\n ? false\n : userSelected ?? systemSelected ?? true;\n Object.assign(existingAction, { ...action, isPreset: true, selected, systemSelected, userSelected });\n } else if (!existingAction.selected && existingAction.isPreset) {\n const systemSelected = false;\n Object.assign(existingAction, this.createAction({ ...existingAction, systemSelected }));\n }\n });\n\n // Loop the generated actions and add any not previously saved\n actions.forEach((action, actionId) => {\n const existingAction = existingActions.get(actionId);\n if (!existingAction) reorderedActions.push(this.createAction({ ...action, isPreset: true }));\n });\n\n // Add actions to group\n group.actions.push(...reorderedActions);\n\n // Sort actions\n if (this.#shouldSortActions(group)) {\n group.actions.sort((a, b) => (a.name ?? \"\").localeCompare(b.name ?? \"\"));\n }\n }\n }\n\n /* -------------------------------------------- */\n\n /**\n * Update actions.\n * @public\n * @param {Array} actionsData\n * @param {object} groupData\n */\n updateActions(actionsData, groupData) {\n const group = this.groupHandler.getGroup(groupData);\n const actions = group.actions;\n\n const reorderedActions = [];\n\n // Set 'selected' to true for selected actions\n // Reorder actions based on order in dialog\n for (const actionData of actionsData) {\n if (actionData.id.includes(\"itemMacro\")) continue;\n const existingAction = group.actions.find(action => action.id === actionData.id);\n if (existingAction) {\n const actionClone = { ...existingAction, userSelected: true };\n reorderedActions.push(actionClone);\n } else {\n const availableAction = this.availableActions.get(actionData.id);\n if (availableAction) {\n const actionClone = { ...availableAction, userSelected: true };\n reorderedActions.push(actionClone);\n }\n }\n }\n // Set 'selected' to false for unselected actions\n for (const action of actions) {\n if (!action.id || action?.id.includes(\"itemMacro\")) continue;\n\n const actionData = actionsData.find(actionData => actionData.id === action.id);\n if (!actionData && action.isPreset) {\n const actionClone = { ...action, userSelected: false };\n reorderedActions.push(actionClone);\n }\n }\n\n // Sort actions\n if (this.#shouldSortActions(group)) {\n reorderedActions.sort((a, b) => (a.name ?? \"\").localeCompare(b.name ?? \"\"));\n }\n\n // Replace group actions\n group.actions = reorderedActions;\n }\n\n /* -------------------------------------------- */\n\n /**\n * Add to available actions.\n * @private\n * @param {Array} actions List of actions\n */\n #addToAvailableActions(actions) {\n for (const [actionId, action] of actions) {\n if (!this.availableActions.has(actionId)) {\n this.availableActions.set(actionId, action);\n }\n }\n }\n\n /* -------------------------------------------- */\n /* AVAILABLE CHOICES */\n /* -------------------------------------------- */\n\n /**\n * Get available actions.\n * @public\n * @returns {Array} List of available actions\n */\n getAvailableActions() {\n return [...this.availableActions.values()]\n .map(action => this.#toChoice(action))\n .sort((a, b) => a.listName.localeCompare(b.listName));\n }\n\n /* -------------------------------------------- */\n\n /**\n * Get selected actions.\n * @public\n * @param {object} groupData\n * @returns {Array} List of selected actions\n */\n getSelectedActions(groupData) {\n const group = this.groupHandler.getGroup(groupData);\n if (!group) return [];\n return group.actions\n .filter(action => action.selected === true)\n .map(action => this.#toChoice(action));\n }\n\n /* -------------------------------------------- */\n\n /**\n * Convert an action into a popover choice.\n * @private\n * @param {object} actionData\n * @returns {{id: string, name: string, listName: string, type: string}}\n */\n #toChoice(actionData) {\n const { id, name, listName } = actionData;\n return { id, name, listName: listName ?? name, type: \"action\" };\n }\n\n /* -------------------------------------------- */\n /* EXTENDERS */\n /* -------------------------------------------- */\n\n /**\n * Add action handler extender\n * @public\n * @param {object} actionHandlerExtender\n */\n addActionHandlerExtender(actionHandlerExtender) {\n Logger.debug(\"Adding action handler extender...\", { actionHandlerExtender });\n actionHandlerExtender.hudManager = this.hudManager;\n actionHandlerExtender.groupHandler = this.groupHandler;\n actionHandlerExtender.actionHandler = this;\n this.actionHandlerExtenders.push(actionHandlerExtender);\n }\n\n /* -------------------------------------------- */\n /* SHORTCUTS */\n /* -------------------------------------------- */\n\n /**\n * Get character name\n * @returns {string} The character name\n */\n get characterName() {\n return this.hudManager?.characterName;\n }\n\n /* -------------------------------------------- */\n\n /**\n * Get actor\n * @returns {object} The actor\n */\n get actor() {\n return this.hudManager?.actor;\n }\n\n /* -------------------------------------------- */\n\n /**\n * Set actor\n */\n set actor(actor) {\n this.hudManager.actor = actor;\n }\n\n /* -------------------------------------------- */\n\n /**\n * Get actors\n * @returns {Array} The actors\n */\n get actors() {\n return this.hudManager?.actors;\n }\n\n /* -------------------------------------------- */\n\n /**\n * Set actors\n * @param {Array} actors The actors\n */\n set actors(actors) {\n this.hudManager.actors = actors;\n }\n\n /* -------------------------------------------- */\n\n /**\n * Get token\n * @returns {object} The token\n */\n get token() {\n return this.hudManager?.token;\n }\n\n /* -------------------------------------------- */\n\n /**\n * Set token\n */\n set token(token) {\n this.hudManager.token = token;\n }\n\n /* -------------------------------------------- */\n\n /**\n * Get tokens\n * @returns {Array} The tokens\n */\n get tokens() {\n return this.hudManager?.tokens;\n }\n\n /* -------------------------------------------- */\n\n /**\n * Set tokens\n * @param {Array} tokens The tokens\n */\n set tokens(tokens) {\n this.hudManager.tokens = tokens;\n }\n\n /* -------------------------------------------- */\n\n /**\n * Whether the right mouse button was clicked\n * @returns {boolean} Whether the right mouse button was clicked\n */\n get isRightClick() {\n return this.hudManager?.isRightClick;\n }\n\n /* -------------------------------------------- */\n\n /**\n * Whether the ALT key was pressed\n * @returns {boolean} Whether the ALT key was pressed\n */\n get isAlt() {\n return this.hudManager?.isAlt;\n }\n\n /* -------------------------------------------- */\n\n /**\n * Whether the CTRL key was pressed\n * @returns {boolean} Whether the CTRL key was pressed\n */\n get isCtrl() {\n return this.hudManager?.isCtrl;\n }\n\n /* -------------------------------------------- */\n\n /**\n * Whether the SHIFT key was pressed\n * @returns {boolean} Whether the SHIFT key was pressed\n */\n get isShift() {\n return this.hudManager?.isShift;\n }\n\n /* -------------------------------------------- */\n\n /**\n * Whether the element was hovered\n * @returns {boolean} Whether the element was hovered\n */\n get isHover() {\n return this.hudManager?.isHover;\n }\n}\n","import { ActionHandler } from \"./action-handler.mjs\";\n\n/**\n * An extension of the base ActionHandler which extends the HUD via core or system modules.\n */\nexport class ActionHandlerExtender extends ActionHandler {\n constructor() {\n super();\n }\n\n /**\n * Extend action handler\n * @override\n */\n extendActionHandler() {}\n}\n","import { DELIMITER } from \"../../core/constants.mjs\";\nimport { Logger, Utils } from \"../../core/utils.mjs\";\n\n/**\n * Resolves core actions triggered from the HUD\n */\nexport class RollHandler {\n constructor() {\n this.hudManager = null;\n this.delimiter = DELIMITER;\n this.preRollHandlers = [];\n this.rollHandlerExtenders = [];\n }\n\n /**\n * Throw error\n * @public\n * @param {*} err The error\n */\n throwInvalidValueErr(err) {\n throw new Error(\n `Error handling button click: ${err}`\n );\n }\n\n /**\n * Add roll handler extender\n * @public\n * @param {object} rollHandlerExtender The RollHandlerExtender instance\n */\n addRollHandlerExtender(rollHandlerExtender) {\n Logger.debug(\"Adding roll handler extender...\", { rollHandlerExtender });\n this.rollHandlerExtenders.push(rollHandlerExtender);\n }\n\n /**\n * Handle action events\n * @public\n * @param {Event} event The event\n * @param {object} action The action\n * @param {class} actionHandler The ActionHandler instance\n */\n async handleActionClickCore(event, action, actionHandler) {\n try {\n Logger.debug(\"Handling action click event\", { event });\n\n // Update variables with current action context\n this.action = action;\n\n // If the action has an onClick function, call it and trigger a HUD update\n if (typeof action?.onClick === \"function\") {\n action.onClick();\n Hooks.callAll(\"forceUpdateTokenActionHud\");\n return;\n }\n\n // Get the value of the associated button\n const buttonValue = this.#getButtonValue(event);\n\n // Check pre-handlers in extenders\n for (let handler of this.rollHandlerExtenders) {\n handler.action = this.action;\n if (handler.prehandleActionEvent(event, buttonValue, actionHandler)) {\n return;\n }\n }\n\n // Check pre-handlers\n for (let handler of this.preRollHandlers) {\n handler.action = this.action;\n if (handler.prehandleActionEvent(event, buttonValue, actionHandler)) {\n return;\n }\n }\n\n // Check handlers in extenders\n for (let handler of this.rollHandlerExtenders) {\n handler.action = this.action;\n if (handler.handleActionClick(event, buttonValue, actionHandler)) {\n return;\n }\n }\n\n // If the action was not yet handled, call the default method\n this.handleActionClick(event, buttonValue);\n } catch(error) {\n Logger.error(\"Error handling action click event\", { error, event, action });\n }\n }\n\n /* -------------------------------------------- */\n\n /**\n * Overide for the TAH system module\n * @override\n * @param {Event} event The event\n * @param {string} buttonValue The button value\n */\n handleActionClick(event, buttonValue) {}\n\n /* -------------------------------------------- */\n\n /**\n * Handle action hover events\n * @param {Event} event The event\n * @param {object} action The action\n */\n async handleActionHoverCore(event, action) {\n Logger.debug(\"Handling action hover event\", { event });\n\n // Update variables with current action context\n this.action = action;\n\n // If the action has an onHover function, call it\n if (typeof action?.onHover === \"function\") {\n action.onHover();\n return;\n }\n\n // Get the value of the associated button\n const buttonValue = this.#getButtonValue(event);\n\n this.handleActionHover(event, buttonValue);\n }\n\n /* -------------------------------------------- */\n\n /**\n * Overide for the TAH system module\n * @override\n * @param {Event} event The event\n * @param {string} buttonValue The button value\n */\n handleActionHover(event, buttonValue) {}\n\n /* -------------------------------------------- */\n\n /**\n * Handle group click events\n * @param {Event} event The event\n * @param {group} group The nest ID\n */\n async handleGroupClickCore(event, group) {\n Logger.debug(`Handling click event for group [${group.name}]`, { event });\n\n this.handleGroupClick(event, group);\n }\n\n /* -------------------------------------------- */\n\n /**\n * Overide for the TAH system module\n * @override\n * @param {Event} event The event\n * @param {object} group The group\n */\n handleGroupClick(event, group) {}\n\n /* -------------------------------------------- */\n\n /**\n * Add a pre-roll handler\n * @public\n * @param {object} handler The roll handler\n */\n addPreRollHandler(handler) {\n Logger.debug(`Adding pre-roll handler ${handler.constructor.name}`);\n this.preRollHandlers.push(handler);\n }\n\n /* -------------------------------------------- */\n\n /**\n * Get button value\n * @private\n * @param {Event} event The event\n * @returns {string} The button value\n */\n #getButtonValue(event) {\n if (!event) return null;\n const buttonElement = event.target.querySelector(\".tah-action-button\") ?? event.target.closest(\".tah-action-button\");\n return buttonElement?.value || null;\n }\n\n /* -------------------------------------------- */\n\n /**\n * Renders the item sheet\n * @public\n * @param {object} actor The actor\n * @param {string} itemId The item id\n * @returns {boolean} Whether the item was rendered\n */\n renderItem(actor, itemId) {\n // If actor is not specified, use the RollHandler's actor\n if (!actor) {\n actor = this.actor;\n }\n\n // Get the item\n const item = Utils.getItem(actor, itemId);\n\n // If the item is not found, return false\n if (!item) return false;\n\n // Render the item and return true\n item.sheet.render(true);\n return true;\n }\n\n /* -------------------------------------------- */\n\n /**\n * Whether the item sheet should be rendered\n * @public\n * @returns {boolean}\n */\n isRenderItem() {\n return (this.isRightClick && !(this.isAlt || this.isCtrl || this.isShift));\n }\n\n /* -------------------------------------------- */\n /* Shortcuts to the HudManager properties */\n /* -------------------------------------------- */\n\n /**\n * Get actor\n * @returns {object} The actor\n */\n get actor() {\n return this.hudManager?.actor;\n }\n\n /* -------------------------------------------- */\n\n /**\n * Get actors\n * @returns {Array} The actors\n */\n get actors() {\n return this.hudManager?.actors;\n }\n\n /* -------------------------------------------- */\n\n /**\n * Get token\n * @returns {object} The token\n */\n get token() {\n return this.hudManager?.token;\n }\n\n /* -------------------------------------------- */\n\n /**\n * Get tokens\n * @returns {Array} The tokens\n */\n get tokens() {\n return this.hudManager?.tokens;\n }\n\n /* -------------------------------------------- */\n\n /**\n * Whether the right mouse button was clicked\n * @returns {boolean} Whether the right mouse button was clicked\n */\n get isRightClick() {\n return this.hudManager.isRightClick;\n }\n\n /* -------------------------------------------- */\n\n /**\n * Whether the ALT key was pressed\n * @returns {boolean} Whether the ALT key was pressed\n */\n get isAlt() {\n return this.hudManager.isAlt;\n }\n\n /* -------------------------------------------- */\n\n /**\n * Whether the CTRL key was pressed\n * @returns {boolean} Whether the CTRL key was pressed\n */\n get isCtrl() {\n return this.hudManager.isCtrl;\n }\n\n /* -------------------------------------------- */\n\n /**\n * Whether the SHIFT key was pressed\n * @returns {boolean} Whether the SHIFT key was pressed\n */\n get isShift() {\n return this.hudManager.isShift;\n }\n\n /* -------------------------------------------- */\n\n /**\n * Whether the element was hovered over\n * @returns {boolean} Whether the element was hovered over\n */\n get isHover() {\n return this.hudManager?.isHover;\n }\n}\n","import { RollHandler } from \"./roll-handler.mjs\";\n\n/*\n * Used for adding support for actions not part of the core functions.\n * Returns true from prehandleActionEvent() if it can perform an action and stops\n * further actions being performed.\n */\nexport class PreRollHandler extends RollHandler {\n /**\n * Pre-handle action event\n * @param {Event} event The event\n * @param {string} buttonValue The button value\n * @param {class} actionHandler The ActionHandler instance\n * @returns {boolean}\n */\n prehandleActionEvent(event, buttonValue, actionHandler) {\n return false;\n }\n}\n","import { RollHandler } from \"./roll-handler.mjs\";\n\n/**\n * An extension of the base RollHandler which extends the actions that can be handled\n */\nexport class RollHandlerExtender extends RollHandler {\n constructor() {\n super();\n }\n\n /**\n * Pre-handle action event.\n * @param {Event} event\n * @param {string} buttonValue The button value\n * @param {class} actionHandler The ActionHandler instance\n * @returns {boolean}\n */\n prehandleActionEvent(event, buttonValue, actionHandler) {\n return false;\n }\n\n /* -------------------------------------------- */\n\n /**\n * Handle action click\n * @override\n * @param {Event} event The click event\n * @param {string} buttonValue The button value\n * @param {class} actionHandler The ActionHandler instance\n * @returns {boolean}\n */\n handleActionClick(event, buttonValue, actionHandler) {\n return false;\n }\n}\n","import { CUSTOM_STYLE, MODULE, TEMPLATE } from \"../core/constants.mjs\";\nimport { Utils } from \"../core/utils.mjs\";\n\nconst { ApplicationV2, HandlebarsApplicationMixin } = foundry.applications.api;\n\nexport class CustomStyleForm extends HandlebarsApplicationMixin(ApplicationV2) {\n constructor(...args) {\n super(args);\n }\n\n /* -------------------------------------------- */\n\n static DEFAULT_OPTIONS = {\n actions: {\n reset: CustomStyleForm.reset\n },\n classes: [`${MODULE.ID}-app`, \"sheet\"],\n id: \"token-action-hud-core-settings\",\n form: {\n closeOnSubmit: true,\n handler: CustomStyleForm.submit\n },\n position: {\n width: 540,\n height: 680\n },\n tag: \"form\",\n window: {\n minimizable: true,\n resizable: true,\n title: \"tokenActionHud.settings.customStyle.form.title\",\n icon: \"fa-solid fa-palette\"\n }\n };\n\n /* -------------------------------------------- */\n\n static PARTS = {\n form: {\n template: TEMPLATE.customStyleForm\n }\n };\n\n /* -------------------------------------------- */\n\n async _prepareContext() {\n this.context = {\n backgroundColor: Utils.getSetting(\"backgroundColor\", CUSTOM_STYLE.backgroundColor.default),\n buttonHeight: Utils.getSetting(\"buttonHeight\", CUSTOM_STYLE.buttonHeight.default),\n buttonBackgroundColor: Utils.getSetting(\"buttonBackgroundColor\", CUSTOM_STYLE.buttonBackgroundColor.default),\n buttonHoverBackgroundColor: Utils.getSetting(\"buttonHoverBackgroundColor\", CUSTOM_STYLE.buttonHoverBackgroundColor.default),\n buttonToggleActiveBackgroundColor: Utils.getSetting(\"buttonToggleActiveBackgroundColor\", CUSTOM_STYLE.buttonToggleActiveBackgroundColor.default),\n buttonToggleHoverBackgroundColor: Utils.getSetting(\"buttonToggleHoverBackgroundColor\", CUSTOM_STYLE.buttonToggleHoverBackgroundColor.default),\n buttonTextColor: Utils.getSetting(\"buttonTextColor\", CUSTOM_STYLE.buttonTextColor.default),\n buttonHoverTextColor: Utils.getSetting(\"buttonHoverTextColor\", CUSTOM_STYLE.buttonHoverTextColor.default),\n buttonToggleActiveTextColor: Utils.getSetting(\"buttonToggleActiveTextColor\", CUSTOM_STYLE.buttonToggleActiveTextColor.default),\n buttonToggleHoverTextColor: Utils.getSetting(\"buttonToggleHoverTextColor\", CUSTOM_STYLE.buttonToggleHoverTextColor.default),\n buttonBorderPrimaryColor: Utils.getSetting(\"buttonBorderPrimaryColor\", CUSTOM_STYLE.buttonBorderPrimaryColor.default),\n buttonBorderSecondaryColor: Utils.getSetting(\"buttonBorderSecondaryColor\", CUSTOM_STYLE.buttonBorderSecondaryColor.default),\n buttonHoverBorderPrimaryColor: Utils.getSetting(\"buttonHoverBorderPrimaryColor\", CUSTOM_STYLE.buttonHoverBorderPrimaryColor.default),\n buttonHoverBorderSecondaryColor: Utils.getSetting(\"buttonHoverBorderSecondaryColor\", CUSTOM_STYLE.buttonHoverBorderSecondaryColor.default),\n buttonToggleActiveBorderPrimaryColor: Utils.getSetting(\"buttonToggleActiveBorderPrimaryColor\", CUSTOM_STYLE.buttonToggleActiveBorderPrimaryColor.default),\n buttonToggleActiveBorderSecondaryColor: Utils.getSetting(\"buttonToggleActiveBorderSecondaryColor\", CUSTOM_STYLE.buttonToggleActiveBorderSecondaryColor.default),\n buttonToggleHoverBorderPrimaryColor: Utils.getSetting(\"buttonToggleHoverBorderPrimaryColor\", CUSTOM_STYLE.buttonToggleHoverBorderPrimaryColor.default),\n buttonToggleHoverBorderSecondaryColor: Utils.getSetting(\"buttonToggleHoverBorderSecondaryColor\", CUSTOM_STYLE.buttonToggleHoverBorderSecondaryColor.default),\n textPrimaryColor: Utils.getSetting(\"textPrimaryColor\", CUSTOM_STYLE.textPrimaryColor.default),\n textSecondaryColor: Utils.getSetting(\"textSecondaryColor\", CUSTOM_STYLE.textSecondaryColor.default),\n textTertiaryColor: Utils.getSetting(\"textTertiaryColor\", CUSTOM_STYLE.textTertiaryColor.default),\n textHoverPrimaryColor: Utils.getSetting(\"textHoverPrimaryColor\", CUSTOM_STYLE.textHoverPrimaryColor.default),\n textHoverSecondaryColor: Utils.getSetting(\"textHoverSecondaryColor\", CUSTOM_STYLE.textHoverSecondaryColor.default),\n textHoverTertiaryColor: Utils.getSetting(\"textHoverTertiaryColor\", CUSTOM_STYLE.textHoverTertiaryColor.default)\n };\n return this.context;\n }\n\n /* -------------------------------------------- */\n\n _onRender(context, options) {\n super._onRender(context, options);\n if (typeof ColorPicker !== \"undefined\") { ColorPicker.install(); }\n }\n\n /* -------------------------------------------- */\n\n static async reset() {\n const tahElement = document.querySelector(\"#token-action-hud-app\");\n for (const [key, value] of Object.entries(CUSTOM_STYLE)) {\n Utils.setSetting(key, value.default);\n tahElement?.style.setProperty(value.cssProperty, value.default);\n }\n this.render(true);\n }\n\n /* -------------------------------------------- */\n\n static async submit(event, form, formData) {\n const isCustom = Utils.getSetting(\"style\") === \"custom\";\n const tahElement = document.querySelector(\"#token-action-hud-app\");\n for (const [key, value] of Object.entries(formData.object)) {\n const customStyle = CUSTOM_STYLE[key];\n if (value !== this.context[key]) {\n Utils.setSetting(key, value);\n if (isCustom && tahElement) {\n tahElement.style.setProperty(customStyle.cssProperty, value);\n }\n }\n }\n }\n}\n","import { Logger, Utils } from \"../core/utils.mjs\";\n\n/**\n * Reset all layouts confirmation dialog.\n * @public\n */\nexport async function resetAllLayoutsDialog() {\n await foundry.applications.api.DialogV2.confirm({\n window: {\n title: game.i18n.localize(\"tokenActionHud.dialog.resetAllLayouts.title\")\n },\n content: `${game.i18n.localize(\"tokenActionHud.dialog.resetAllLayouts.content\")}
`,\n modal: true,\n yes: {\n label: game.i18n.localize(\"tokenActionHud.dialog.button.yes\"),\n callback: async () => resetAllLayouts()\n },\n no: {\n label: game.i18n.localize(\"tokenActionHud.dialog.button.no\")\n }\n });\n}\n\n/* -------------------------------------------- */\n\n/**\n * Reset HUD layouts for everyone.\n * @public\n */\nasync function resetAllLayouts() {\n if (!game.tokenActionHud) return;\n\n const customLayoutElement = document.querySelector(\"#token-action-hud-core-settings input[name=customLayout]\");\n if (customLayoutElement) {\n await Utils.setSetting(\"customLayout\", customLayoutElement?.value ?? \"\");\n }\n\n const userCustomLayoutElement = document.querySelector(\"#token-action-hud-core-settings input[name=userCustomLayout]\");\n if (userCustomLayoutElement) {\n await Utils.setUserFlag(\"userCustomLayout\", userCustomLayoutElement?.value ?? \"\");\n }\n\n await game.tokenActionHud.socket.executeForEveryone(\"reset\");\n Logger.info(\"All layouts reset\", true);\n}\n","import { MODULE, LAYOUT_SETTING, TEMPLATE } from \"../core/constants.mjs\";\nimport { resetLayoutDialog } from \"../dialogs/reset-layout.mjs\";\nimport { resetAllLayoutsDialog } from \"../dialogs/reset-all-layouts.mjs\";\nimport { Utils } from \"../core/utils.mjs\";\n\nconst { ApplicationV2, HandlebarsApplicationMixin } = foundry.applications.api;\n\nexport class TahSettingsForm extends HandlebarsApplicationMixin(ApplicationV2) {\n constructor(...args) {\n super(args);\n\n this.settings = {};\n }\n\n /* -------------------------------------------- */\n\n static DEFAULT_OPTIONS = {\n actions: {\n exportLayout: TahSettingsForm.exportLayout,\n resetLayout: resetLayoutDialog,\n resetAllLayouts: resetAllLayoutsDialog,\n reset: TahSettingsForm.reset\n },\n classes: [`${MODULE.ID}-app`, \"sheet\"],\n id: \"token-action-hud-core-settings\",\n form: {\n closeOnSubmit: true,\n handler: TahSettingsForm.submit\n },\n position: {\n width: 540,\n height: \"auto\"\n },\n tag: \"form\",\n window: {\n minimizable: true,\n resizable: true\n }\n };\n\n /* -------------------------------------------- */\n\n static PARTS = {\n form: {\n template: TEMPLATE.settings\n }\n };\n\n /* -------------------------------------------- */\n\n async _prepareContext() {\n const settings = [];\n const context = { settings };\n\n for (const [key, setting] of Object.entries(this.settings)) {\n const { scope, hint, icon, label, name, type, inputType, range, choices, action } = setting;\n\n if (scope === \"world\" && !game.user.isGM) continue;\n\n const value = (setting?.scope)\n ? (scope === \"user\")\n ? await Utils.getUserFlag(key)\n : await Utils.getSetting(key)\n : \"\";\n const settingType = type instanceof Function ? type.name : \"String\";\n const isButton = inputType === \"button\";\n const isCheckbox = inputType === \"checkbox\";\n const isFilePicker = inputType === \"filePicker\";\n const filePickerType = (inputType === \"filePicker\") ? settingType ?? \"any\" : \"\";\n const isNumber = inputType === \"number\";\n const isRange = (inputType === \"range\") && range;\n const isSelect = choices !== undefined;\n settings.push({\n id: key,\n hint: game.i18n.localize(hint),\n icon,\n label: game.i18n.localize(label),\n name: game.i18n.localize(name),\n value,\n type,\n isButton,\n action,\n isCheckbox,\n isFilePicker,\n filePickerType,\n isNumber,\n isRange,\n isSelect\n });\n }\n return context;\n }\n\n /* -------------------------------------------- */\n\n static exportLayout() {\n if (!game.tokenActionHud) return;\n game.tokenActionHud.hudManager.layoutHandler.exportLayout();\n }\n\n static async submit(event, form, formData) {\n for (const [key, value] of Object.entries(formData.object)) {\n switch (this.settings[key].scope) {\n case \"client\":\n case \"world\":\n await Utils.setSetting(key, value); break;\n case \"user\":\n await Utils.setUserFlag(key, value); break;\n }\n\n await game.tokenActionHud.updateCachedSettings(key, value);\n }\n\n game.tokenActionHud.update();\n }\n}\n\n/* -------------------------------------------- */\n\nexport class TahSettingsFormLayout extends TahSettingsForm {\n constructor() {\n super();\n this.settings = LAYOUT_SETTING;\n }\n\n /* -------------------------------------------- */\n\n static DEFAULT_OPTIONS = {\n window: {\n title: \"tokenActionHud.settings.layout.form.title\",\n icon: \"fa-solid fa-table-cells-large\"\n }\n };\n}\n","import { CustomStyleForm } from \"../applications/custom-style-form.mjs\";\nimport { TahSettingsFormLayout } from \"../applications/settings-form.mjs\";\nimport { CUSTOM_STYLE, MODULE } from \"./constants.mjs\";\nimport { Logger, Utils } from \"./utils.mjs\";\n\n/**\n * When a module setting is changed, update the HUD settings.\n * @param {string} key Setting key\n * @param {*} value Setting value\n */\nfunction onChangeFunction(key, value) {\n if (game.tokenActionHud) game.tokenActionHud.updateCachedSettings(key, value);\n}\n\n/* -------------------------------------------- */\n\n// Register key bindings\nHooks.on(\"init\", async () => {\n game.keybindings.register(MODULE.ID, \"enableDisableHud\", {\n name: game.i18n.localize(\"tokenActionHud.enableDisableHud\"),\n editable: [],\n onDown: () => { if (game.tokenActionHud) game.tokenActionHud.toggleHudEnable(); }\n });\n\n game.keybindings.register(MODULE.ID, \"collapseExpandHud\", {\n name: game.i18n.localize(\"tokenActionHud.collapseExpandHud\"),\n editable: [],\n onDown: () => { if (game.tokenActionHud) game.tokenActionHud.toggleHudCollapse(); }\n });\n});\n\n/* -------------------------------------------- */\n\n/**\n * Register module settings\n * @param {SystemManager} systemManager\n * @param {Array} rollHandlers List of available roll handlers\n * @param {object} styles Styles\n */\nexport const registerSettingsCore = function(systemManager, rollHandlers, styles) {\n game.settings.registerMenu(MODULE.ID, \"customStyle\", {\n hint: game.i18n.localize(\"tokenActionHud.settings.customStyle.hint\"),\n label: game.i18n.localize(\"tokenActionHud.settings.customStyle.label\"),\n name: game.i18n.localize(\"tokenActionHud.settings.customStyle.name\"),\n icon: \"fas fa-palette\",\n type: CustomStyleForm,\n restricted: false,\n scope: \"client\"\n });\n\n /* -------------------------------------------- */\n\n game.settings.registerMenu(MODULE.ID, \"layout\", {\n hint: game.i18n.localize(\"tokenActionHud.settings.layout.hint\"),\n label: game.i18n.localize(\"tokenActionHud.settings.layout.label\"),\n name: game.i18n.localize(\"tokenActionHud.settings.layout.name\"),\n icon: \"fas fa-table-layout\",\n type: TahSettingsFormLayout,\n restricted: false,\n scope: \"client\"\n });\n\n /* -------------------------------------------- */\n\n game.settings.register(MODULE.ID, \"startup\", {\n name: \"One-Time Startup Prompt\",\n scope: \"world\",\n config: false,\n type: Boolean,\n default: false\n });\n\n /* -------------------------------------------- */\n\n game.settings.register(MODULE.ID, \"migrationVersion\", {\n name: \"Migration Version\",\n scope: \"world\",\n config: false,\n type: String,\n default: \"0.0\"\n });\n\n /* -------------------------------------------- */\n\n game.settings.register(MODULE.ID, \"enable\", {\n name: game.i18n.localize(\"tokenActionHud.settings.enable.name\"),\n hint: game.i18n.localize(\"tokenActionHud.settings.enable.hint\"),\n scope: \"client\",\n config: true,\n type: Boolean,\n default: true,\n onChange: value => {\n onChangeFunction(\"enable\", value);\n }\n });\n\n /* -------------------------------------------- */\n\n game.settings.register(MODULE.ID, \"rollHandler\", {\n name: game.i18n.localize(\"tokenActionHud.settings.rollHandler.name\"),\n hint: game.i18n.localize(\"tokenActionHud.settings.rollHandler.hint\"),\n scope: \"world\",\n config: true,\n type: String,\n choices: rollHandlers,\n default: \"core\",\n onChange: value => {\n onChangeFunction(\"rollHandler\", value);\n }\n });\n\n /* -------------------------------------------- */\n\n const styleChoices = Object.fromEntries(Object.entries(styles).map(([key, value]) => [key, value.name]));\n\n game.settings.register(MODULE.ID, \"style\", {\n name: game.i18n.localize(\"tokenActionHud.settings.style.name\"),\n hint: game.i18n.localize(\"tokenActionHud.settings.style.hint\"),\n scope: \"client\",\n config: true,\n type: String,\n default: \"foundryVTT\",\n choices: styleChoices,\n onChange: value => {\n Utils.switchCSS(value);\n onChangeFunction(\"style\", value);\n }\n });\n\n /* -------------------------------------------- */\n\n game.settings.register(MODULE.ID, \"customLayout\", {\n name: game.i18n.localize(\"tokenActionHud.settings.customLayout.name\"),\n hint: game.i18n.localize(\"tokenActionHud.settings.customLayout.hint\"),\n scope: \"world\",\n config: false,\n type: String\n });\n\n /* -------------------------------------------- */\n\n game.settings.register(MODULE.ID, \"userCustomLayout\", {\n name: game.i18n.localize(\"tokenActionHud.settings.userCustomLayout.name\"),\n hint: game.i18n.localize(\"tokenActionHud.settings.userCustomLayout.hint\"),\n scope: \"client\",\n config: false,\n type: String\n });\n\n /* -------------------------------------------- */\n\n game.settings.register(MODULE.ID, \"allow\", {\n name: game.i18n.localize(\"tokenActionHud.settings.allow.name\"),\n hint: game.i18n.localize(\"tokenActionHud.settings.allow.hint\"),\n scope: \"world\",\n config: true,\n type: String,\n choices: {\n 4: game.i18n.localize(\"tokenActionHud.settings.allow.choice.4\"),\n 3: game.i18n.localize(\"tokenActionHud.settings.allow.choice.3\"),\n 2: game.i18n.localize(\"tokenActionHud.settings.allow.choice.2\"),\n 1: game.i18n.localize(\"tokenActionHud.settings.allow.choice.1\")\n },\n default: 1,\n requiresReload: true\n });\n\n /* -------------------------------------------- */\n\n game.settings.register(MODULE.ID, \"enableCustomization\", {\n name: game.i18n.localize(\"tokenActionHud.settings.enableCustomization.name\"),\n hint: game.i18n.localize(\"tokenActionHud.settings.enableCustomization.hint\"),\n scope: \"world\",\n config: true,\n type: Boolean,\n default: true,\n onChange: value => {\n onChangeFunction(\"enableCustomization\", value);\n }\n });\n\n /* -------------------------------------------- */\n\n game.settings.register(MODULE.ID, \"enableCompendiumActions\", {\n name: game.i18n.localize(\"tokenActionHud.settings.enableCompendiumActions.name\"),\n hint: game.i18n.localize(\"tokenActionHud.settings.enableCompendiumActions.hint\"),\n scope: \"world\",\n config: true,\n type: Boolean,\n default: true,\n onChange: value => {\n onChangeFunction(\"enableCompendiumActions\", value);\n }\n });\n\n /* -------------------------------------------- */\n\n game.settings.register(MODULE.ID, \"enableMacroActions\", {\n name: game.i18n.localize(\"tokenActionHud.settings.enableMacroActions.name\"),\n hint: game.i18n.localize(\"tokenActionHud.settings.enableMacroActions.hint\"),\n scope: \"world\",\n config: true,\n type: Boolean,\n default: true,\n onChange: value => {\n onChangeFunction(\"enableMacroActions\", value);\n }\n });\n\n /* -------------------------------------------- */\n\n game.settings.register(MODULE.ID, \"direction\", {\n name: game.i18n.localize(\"tokenActionHud.settings.direction.name\"),\n hint: game.i18n.localize(\"tokenActionHud.settings.direction.hint\"),\n scope: \"client\",\n config: true,\n type: String,\n default: \"auto\",\n choices: {\n auto: game.i18n.localize(\"tokenActionHud.settings.direction.choice.auto\"),\n up: game.i18n.localize(\"tokenActionHud.settings.direction.choice.up\"),\n down: game.i18n.localize(\"tokenActionHud.settings.direction.choice.down\")\n },\n onChange: value => {\n onChangeFunction(\"direction\", value);\n }\n });\n\n /* -------------------------------------------- */\n\n game.settings.register(MODULE.ID, \"grid\", {\n name: game.i18n.localize(\"tokenActionHud.settings.grid.name\"),\n hint: game.i18n.localize(\"tokenActionHud.settings.grid.hint\"),\n scope: \"client\",\n config: true,\n type: Boolean,\n default: false,\n onChange: value => {\n onChangeFunction(\"grid\", value);\n }\n });\n\n /* -------------------------------------------- */\n\n game.settings.register(MODULE.ID, \"scale\", {\n name: game.i18n.localize(\"tokenActionHud.settings.scale.name\"),\n hint: game.i18n.localize(\"tokenActionHud.settings.scale.hint\"),\n scope: \"client\",\n config: true,\n type: Number,\n range: {\n min: 0.5,\n max: 2,\n step: 0.05\n },\n default: 1,\n onChange: value => {\n onChangeFunction(\"scale\", value);\n }\n });\n\n /* -------------------------------------------- */\n\n game.settings.register(MODULE.ID, \"drag\", {\n name: game.i18n.localize(\"tokenActionHud.settings.drag.name\"),\n hint: game.i18n.localize(\"tokenActionHud.settings.drag.hint\"),\n scope: \"client\",\n config: true,\n type: String,\n default: \"whenUnlocked\",\n choices: {\n always: game.i18n.localize(\"tokenActionHud.settings.drag.choices.always\"),\n whenUnlocked: game.i18n.localize(\"tokenActionHud.settings.drag.choices.whenUnlocked\"),\n never: game.i18n.localize(\"tokenActionHud.settings.drag.choices.never\")\n },\n onChange: value => {\n onChangeFunction(\"drag\", value);\n }\n });\n\n /* -------------------------------------------- */\n\n game.settings.register(MODULE.ID, \"alwaysShowHud\", {\n name: game.i18n.localize(\"tokenActionHud.settings.alwaysShowHud.name\"),\n hint: game.i18n.localize(\"tokenActionHud.settings.alwaysShowHud.hint\"),\n scope: \"client\",\n config: true,\n type: Boolean,\n default: true,\n onChange: value => {\n onChangeFunction(\"alwaysShowHud\", value);\n }\n });\n\n /* -------------------------------------------- */\n\n game.settings.register(MODULE.ID, \"clickOpenCategory\", {\n name: game.i18n.localize(\"tokenActionHud.settings.clickOpenCategory.name\"),\n hint: game.i18n.localize(\"tokenActionHud.settings.clickOpenCategory.hint\"),\n scope: \"client\",\n config: true,\n type: Boolean,\n default: false,\n onChange: value => {\n onChangeFunction(\"clickOpenCategory\", value);\n }\n });\n\n /* -------------------------------------------- */\n\n game.settings.register(MODULE.ID, \"collapsibleSubgroups\", {\n name: game.i18n.localize(\"tokenActionHud.settings.collapsibleSubgroups.name\"),\n hint: game.i18n.localize(\"tokenActionHud.settings.collapsibleSubgroups.hint\"),\n scope: \"client\",\n config: true,\n type: Boolean,\n default: true,\n onChange: value => {\n onChangeFunction(\"collapsibleSubgroups\", value);\n }\n });\n\n /* -------------------------------------------- */\n\n game.settings.register(MODULE.ID, \"displayCharacterName\", {\n name: game.i18n.localize(\"tokenActionHud.settings.displayCharacterName.name\"),\n hint: game.i18n.localize(\"tokenActionHud.settings.displayCharacterName.hint\"),\n scope: \"client\",\n config: true,\n type: Boolean,\n default: true,\n onChange: value => {\n onChangeFunction(\"displayCharacterName\", value);\n }\n });\n\n /* -------------------------------------------- */\n\n game.settings.register(MODULE.ID, \"sortActions\", {\n name: game.i18n.localize(\"tokenActionHud.settings.sortActions.name\"),\n hint: game.i18n.localize(\"tokenActionHud.settings.sortActions.hint\"),\n scope: \"client\",\n config: true,\n type: Boolean,\n default: false,\n onChange: value => {\n onChangeFunction(\"sortActions\", value);\n }\n });\n\n /* -------------------------------------------- */\n\n game.settings.register(MODULE.ID, \"displayIcons\", {\n name: game.i18n.localize(\"tokenActionHud.settings.displayIcons.name\"),\n hint: game.i18n.localize(\"tokenActionHud.settings.displayIcons.hint\"),\n scope: \"client\",\n config: true,\n type: Boolean,\n default: true,\n onChange: value => {\n onChangeFunction(\"displayIcons\", value);\n }\n });\n\n /* -------------------------------------------- */\n\n game.settings.register(MODULE.ID, \"tooltips\", {\n name: game.i18n.localize(\"tokenActionHud.settings.tooltips.name\"),\n hint: game.i18n.localize(\"tokenActionHud.settings.tooltips.hint\"),\n scope: \"client\",\n config: true,\n type: String,\n default: \"full\",\n choices: {\n full: game.i18n.localize(\"tokenActionHud.settings.tooltips.choices.full\"),\n nameOnly: game.i18n.localize(\"tokenActionHud.settings.tooltips.choices.nameOnly\"),\n none: game.i18n.localize(\"tokenActionHud.settings.tooltips.choices.none\")\n },\n onChange: value => {\n onChangeFunction(\"tooltips\", value);\n }\n });\n\n /* -------------------------------------------- */\n\n game.settings.register(MODULE.ID, \"tooltipDelay\", {\n name: game.i18n.localize(\"tokenActionHud.settings.tooltipDelay.name\"),\n hint: game.i18n.localize(\"tokenActionHud.settings.tooltipDelay.hint\"),\n scope: \"client\",\n config: true,\n type: Number,\n default: 1500,\n onChange: value => {\n setTooltipDelay(value);\n }\n });\n\n /* -------------------------------------------- */\n\n const tooltipDelay = Utils.getSetting(\"tooltipDelay\") || 1500;\n setTooltipDelay(tooltipDelay);\n\n /**\n * Set the tooltip delay.\n * @param {number} ms Delay amount in milliseconds\n */\n function setTooltipDelay(ms) {\n const root = document.querySelector(\":root\");\n root.style.setProperty(\"--tah-tooltip-delay\", `${ms}ms`);\n }\n\n /* -------------------------------------------- */\n\n if (Utils.isModuleActive(\"itemacro\") && !Utils.isModuleActive(\"midi-qol\")) {\n game.settings.register(MODULE.ID, \"itemMacro\", {\n name: game.i18n.localize(\"tokenActionHud.settings.itemMacro.name\"),\n hint: game.i18n.localize(\"tokenActionHud.settings.itemMacro.hint\"),\n scope: \"client\",\n config: true,\n type: String,\n choices: {\n both: game.i18n.localize(\"tokenActionHud.settings.itemMacro.choices.both\"),\n itemMacro: game.i18n.localize(\"tokenActionHud.settings.itemMacro.choices.itemMacro\"),\n original: game.i18n.localize(\"tokenActionHud.settings.itemMacro.choices.original\")\n },\n default: \"both\",\n onChange: value => {\n onChangeFunction(\"itemMacro\", value);\n }\n });\n }\n\n /* -------------------------------------------- */\n\n game.settings.register(MODULE.ID, \"activeCssAsText\", {\n name: game.i18n.localize(\"tokenActionHud.settings.activeCssAsText.name\"),\n hint: game.i18n.localize(\"tokenActionHud.settings.activeCssAsText.hint\"),\n scope: \"client\",\n config: true,\n type: Boolean,\n default: false,\n onChange: value => {\n onChangeFunction(\"activeCssAsText\", value);\n }\n });\n\n /* -------------------------------------------- */\n\n game.settings.register(MODULE.ID, \"debug\", {\n name: game.i18n.localize(\"tokenActionHud.settings.debug.name\"),\n hint: game.i18n.localize(\"tokenActionHud.settings.debug.hint\"),\n scope: \"client\",\n config: true,\n type: Boolean,\n default: false,\n onChange: value => {\n onChangeFunction(\"debug\", value);\n }\n });\n\n /* -------------------------------------------- */\n\n registerCustomStyleSettings();\n\n systemManager.registerSettings(onChangeFunction);\n\n Logger.debug(\"Available roll handlers\", { rollHandlers });\n};\n\n/* -------------------------------------------- */\n\n/**\n * Register color settings.\n */\nfunction registerCustomStyleSettings() {\n for (const [key, value] of Object.entries(CUSTOM_STYLE)) {\n game.settings.register(MODULE.ID, key, {\n scope: \"client\",\n config: false,\n type: value.type,\n default: value.default\n });\n }\n}\n","import { ActionHandlerExtender } from \"./action-handler-extender.mjs\";\nimport { DELIMITER, ITEM_MACRO_ICON } from \"../../core/constants.mjs\";\nimport { Utils } from \"../../core/utils.mjs\";\n\n/**\n * Handler for building actions related to the Item Macro module.\n */\nexport class ItemMacroActionHandlerExtender extends ActionHandlerExtender {\n constructor() {\n super();\n }\n\n /* -------------------------------------------- */\n\n /**\n * Extend the action list.\n * @override\n */\n extendActionHandler() {\n if (!this.actor) return;\n\n const items = this.actor.items.filter(item => item.flags?.itemacro?.macro?.command);\n if (!items?.length) return;\n\n const itemMacroSetting = Utils.getSetting(\"itemMacro\");\n if (itemMacroSetting === \"original\") return;\n\n const replaceExisting = itemMacroSetting === \"itemMacro\";\n\n Object.values(this.groupHandler.groups).forEach(group => {\n this.#addGroupActions(items, group, replaceExisting);\n });\n }\n\n /* -------------------------------------------- */\n\n /**\n * Add group actions.\n * @private\n * @param {Array} items\n * @param {object} group\n * @param {boolean} replace Whether to replace the action or not\n */\n #addGroupActions(items, group, replace) {\n // Exit if no actions exist\n if (!group?.actions?.length) return;\n\n const actions = [];\n for (const existingAction of group.actions) {\n const item = items.find(item => item.id === existingAction.id);\n if (!item) continue;\n\n const existingItemMacroAction = group.actions.find(action => action.id === `itemMacro+${existingAction.id}`);\n const actionToReplace = existingItemMacroAction ?? existingAction;\n\n if (existingItemMacroAction) replace = true;\n\n const macroAction = this.#createItemMacroAction(item, existingAction, actionToReplace, replace);\n\n if (!replace) {\n actions.push(macroAction);\n }\n\n if (!this.actionHandler.availableActions.has(macroAction.id)) {\n this.actionHandler.availableActions.set(macroAction.id, macroAction);\n }\n }\n\n this.#addActions(actions, group);\n }\n\n /* -------------------------------------------- */\n\n /**\n * Create item macro action.\n * @private\n * @param {object} item\n * @param {object} existingAction\n * @param {object} actionToReplace\n * @param {boolean} replace Whether to replace the action or not\n * @returns {object} Item Macro action\n */\n #createItemMacroAction(item, existingAction, actionToReplace, replace) {\n const action = (replace) ? actionToReplace : Utils.deepClone(existingAction);\n action.encodedValue = `itemMacro${existingAction.encodedValue?.substr(existingAction.encodedValue.indexOf(DELIMITER))}`;\n action.id = `itemMacro+${existingAction.id}`;\n action.fullName = existingAction.fullName;\n action.listName = `Item Macro: ${existingAction.fullName}`;\n action.name = existingAction.name;\n action.img = existingAction.img;\n action.itemMacroIcon = ``;\n action.selected = existingAction.userSelected ?? existingAction.systemSelected;\n\n action.onClick = () => {\n try {\n item.executeMacro();\n } catch(err) {\n Logger.debug(\"ItemMacro Error\", err);\n return false;\n }\n };\n\n return action;\n }\n\n /* -------------------------------------------- */\n\n /**\n * Add actions to the group.\n * @private\n * @param {object} actions\n * @param {object} group\n */\n #addActions(actions, group) {\n actions.forEach(macroAction => {\n const index = group.actions.findIndex(action => action.id === macroAction.id) + 1;\n group.actions.splice(index, 0, macroAction);\n });\n }\n}\n","import { registerSettingsCore } from \"../core/settings.mjs\";\nimport { ItemMacroActionHandlerExtender } from \"../handlers/action-handlers/item-macro-extender.mjs\";\nimport { RollHandler } from \"../handlers/roll-handlers/roll-handler.mjs\";\nimport { MODULE, CSS_STYLE } from \"../core/constants.mjs\";\nimport { Logger, Utils } from \"../core/utils.mjs\";\n\nexport class SystemManager {\n constructor() {\n this.coreModuleId = MODULE.ID;\n this.defaults = [];\n this.styles = null;\n }\n\n /* -------------------------------------------- */\n /* METHODS TO OVERRIDE */\n /* -------------------------------------------- */\n\n getActionHandler() {}\n\n getRollHandler(rollHandlerId) {\n return false;\n }\n\n getAvailableRollHandlers() {}\n\n registerSettings(onChangeFunction) {}\n\n async registerDefaults() {}\n\n registerStyles() {}\n\n /* -------------------------------------------- */\n /* INITIALISE */\n /* -------------------------------------------- */\n\n /**\n * Initialise the system manager\n */\n async init() {\n await this.#registerDefaultsCore();\n this.#registerStylesCore();\n this.#registerSettingsCore();\n }\n\n\n /* -------------------------------------------- */\n /* REGISTER */\n /* -------------------------------------------- */\n\n /**\n * Register defaults\n * @private\n * @returns {Array} Default HUD layout and subgroups\n */\n async #registerDefaultsCore() {\n const defaults = await this.registerDefaults() ?? [];\n\n Hooks.callAll(\"tokenActionHudCoreRegisterDefaults\", defaults);\n\n if (defaults) {\n this.defaults = defaults;\n }\n }\n\n /* -------------------------------------------- */\n\n /**\n * Register styles\n * @private\n */\n #registerStylesCore() {\n const systemStyles = this.registerStyles() ?? {};\n this.styles = foundry.utils.mergeObject(CSS_STYLE, systemStyles);\n\n Hooks.callAll(\"tokenActionHudCoreRegisterStyles\", this.styles);\n }\n\n /* -------------------------------------------- */\n\n /**\n * Register module settings\n * @private\n */\n #registerSettingsCore() {\n const rollHandlers = this.getAvailableRollHandlers();\n registerSettingsCore(this, rollHandlers, this.styles);\n }\n\n /* -------------------------------------------- */\n\n /**\n * Initialise the action handler\n * @public\n * @param {HudManager} hudManager\n * @returns {ActionHandler}\n */\n getActionHandlerCore(hudManager) {\n const actionHandler = this.getActionHandler();\n actionHandler.systemManager = this;\n\n const { dataHandler, groupHandler } = hudManager;\n actionHandler.hudManager = hudManager;\n actionHandler.dataHandler = dataHandler;\n actionHandler.groupHandler = groupHandler;\n actionHandler.addGroup = groupHandler.addGroup.bind(groupHandler);\n actionHandler.addGroupInfo = groupHandler.addGroupInfo.bind(groupHandler);\n this.#addActionHandlerExtenders(groupHandler, actionHandler);\n\n Hooks.callAll(\"tokenActionHudCoreAddActionHandler\", actionHandler);\n\n return actionHandler;\n }\n\n /* -------------------------------------------- */\n\n /**\n * Add action handler extensions\n * @public\n * @param {GroupHandler} groupHandler\n * @param {ActionHandler} actionHandler\n */\n #addActionHandlerExtenders(groupHandler, actionHandler) {\n if (Utils.isModuleActive(\"itemacro\") && !Utils.isModuleActive(\"midi-qol\")) {\n actionHandler.addActionHandlerExtender(new ItemMacroActionHandlerExtender(groupHandler, actionHandler));\n }\n\n Hooks.callAll(\"tokenActionHudCoreAddActionHandlerExtenders\", actionHandler);\n }\n\n /* -------------------------------------------- */\n\n /**\n * Get the roll handler\n * @public\n * @param {HudManager} hudManager\n * @returns {RolHandler}\n */\n getRollHandlerCore(hudManager) {\n let rollHandlerId = Utils.getSetting(\"rollHandler\");\n\n if (!(rollHandlerId === \"core\" || Utils.isModuleActive(rollHandlerId))) {\n Logger.error(rollHandlerId, game.i18n.localize(\"tokenActionHud.handlerNotFound\"));\n rollHandlerId = \"core\";\n Utils.setSetting(\"rollHandler\", rollHandlerId);\n }\n\n // If no system RollHandler is returned, use core RollHandler\n const rollHandler = this.getRollHandler(rollHandlerId) ?? new RollHandler();\n rollHandler.hudManager = hudManager;\n\n this.#addRollHandlerExtenders(rollHandler);\n\n Hooks.callAll(\"tokenActionHudCoreAddRollHandler\", rollHandler);\n\n return rollHandler;\n }\n\n /* -------------------------------------------- */\n\n /**\n * Add roll handler extensions\n * @public\n * @param {RollHandler} rollHandler\n */\n #addRollHandlerExtenders(rollHandler) {\n Hooks.callAll(\"tokenActionHudCoreAddRollHandlerExtenders\", rollHandler);\n }\n\n /* -------------------------------------------- */\n\n /**\n * Add handler\n * @param {Array} choices\n * @param {string} id Module ID\n */\n static addHandler(choices, id) {\n if (Utils.isModuleActive(id)) {\n const title = Utils.getModuleTitle(id);\n foundry.utils.mergeObject(choices, { [id]: title });\n }\n }\n}\n","import { MODULE } from \"./constants.mjs\";\nimport { ActionHandler } from \"../handlers/action-handlers/action-handler.mjs\";\nimport { ActionHandlerExtender } from \"../handlers/action-handlers/action-handler-extender.mjs\";\nimport { DataHandler } from \"../handlers/data-handler.mjs\";\nimport { PreRollHandler } from \"../handlers/roll-handlers/pre-roll-handler.mjs\";\nimport { RollHandler } from \"../handlers/roll-handlers/roll-handler.mjs\";\nimport { RollHandlerExtender } from \"../handlers/roll-handlers/roll-handler-extender.mjs\";\nimport { SystemManager } from \"../managers/system-manager.mjs\";\nimport { Logger, Timer, Utils } from \"./utils.mjs\";\n\n/**\n * Register the API.\n */\nexport function registerApi() {\n const module = game.modules.get(MODULE.ID);\n module.api = {\n ActionHandlerExtender,\n ActionHandler,\n DataHandler,\n Logger,\n PreRollHandler,\n RollHandler,\n RollHandlerExtender,\n SystemManager,\n Timer,\n Utils\n };\n\n Hooks.callAll(\"tokenActionHudCoreApiReady\", module);\n}\n","import { MODULE, TEMPLATE } from \"./core/constants.mjs\";\nimport { DataHandler } from \"./handlers/data-handler.mjs\";\nimport { MigrationManager } from \"./managers/migration-manager.mjs\";\nimport { TokenActionHud } from \"./applications/token-action-hud.mjs\";\nimport { Logger, Utils } from \"./core/utils.mjs\";\nimport { registerSocket, getSocket, isSocketlibActive } from \"./core/sockets.mjs\";\nimport { registerApi } from \"./core/api.mjs\";\n\nlet systemManager;\n\n/* -------------------------------------------- */\n/* HOOKS */\n/* -------------------------------------------- */\n\nHooks.once(\"socketlib.ready\", registerSocket);\nHooks.on(\"ready\", registerApi);\nHooks.on(\"tokenActionHudSystemReady\", registerCoreModule);\nHooks.on(\"tokenActionHudCoreReady\", registerHud);\nHooks.on(\"renderHotbar\", (_, html) => addContextMenuListener(html, foundry.utils.isNewerVersion(game.version, \"12.999\") ? \"li.slot\" : \"li.macro\"));\nHooks.on(\"renderSceneNavigation\", (_, html) => addContextMenuListener(html, foundry.utils.isNewerVersion(game.version, \"12.999\") ? \"li.ui-control\" : \"li.scene.nav-item\"));\n\n/* -------------------------------------------- */\n/* REGISTRATION */\n/* -------------------------------------------- */\n\n/**\n * Register the core module.\n * @param {object} systemModule The system module\n */\nasync function registerCoreModule(systemModule) {\n // Exit if core module version is not compatible with the system module\n if (!Utils.isSystemModuleCompatible(systemModule.api?.requiredCoreModuleVersion)) return;\n\n // Exit if socketlit module is not installed or enabled\n if (!isSocketlibActive()) return;\n\n // Create new SystemManager and register core and system module settings\n systemManager = new systemModule.api.SystemManager(MODULE.ID);\n await systemManager.init();\n\n // Register Handlebar helpers\n Utils.registerHandlebars();\n\n // Load templates\n if (foundry.utils.isNewerVersion(game.version, \"12.9999\")) {\n foundry.applications.handlebars.loadTemplates(Object.values(TEMPLATE));\n } else {\n loadTemplates(Object.values(TEMPLATE));\n }\n\n Hooks.callAll(\"tokenActionHudCoreReady\");\n}\n\n/* -------------------------------------------- */\n\n/**\n * Register the HUD.\n */\nasync function registerHud() {\n // Get socket\n const socket = getSocket();\n\n // Initialise DataHandler\n const dataHandler = new DataHandler(socket);\n await dataHandler.init();\n\n // Initialise MigrationManager\n const migrationManager = new MigrationManager(dataHandler, socket);\n await migrationManager.init();\n\n checkColorPicker();\n registerHudHooks();\n\n game.tokenActionHud = new TokenActionHud(systemManager, dataHandler, socket);\n await game.tokenActionHud.init();\n\n Hooks.callAll(\"tokenActionHudReady\");\n\n game.tokenActionHud.update({ type: \"hook\", name: \"tokenActionHudCoreReady\" });\n}\n\n/* -------------------------------------------- */\n\n/**\n * Notify GM if the Color Picker is not active.\n */\nfunction checkColorPicker() {\n if (game.user.isGM && !game.modules.get(\"color-picker\")?.active && Utils.getSetting(\"startup\") === false) {\n Logger.info(\"To enable color pickers, install the 'Color Picker' module.\", true);\n Utils.setSetting(\"startup\", true);\n }\n}\n\n/* -------------------------------------------- */\n/* HOOK HANDLERS */\n/* -------------------------------------------- */\n\n/**\n * Register HUD-related hooks.\n */\nfunction registerHudHooks() {\n Hooks.on(\"renderTokenActionHud\", () => game.tokenActionHud.postRender());\n const hooks = [\n \"deleteActor\", \"updateActor\", \"createActiveEffect\", \"deleteActiveEffect\",\n \"createCombat\", \"deleteCombat\", \"updateCombat\", \"updateCombatant\",\n \"deleteCompendium\", \"updateCompendium\", \"createItem\", \"deleteItem\",\n \"updateItem\", \"createMacro\", \"deleteMacro\", \"updateMacro\", \"controlToken\",\n \"deleteToken\", \"updateToken\", \"closeSettingsConfig\", \"forceUpdateTokenActionHud\"\n ];\n\n hooks.forEach(hook => Hooks.on(hook, (...args) => handleHookEvent({ ...args }, hook)));\n}\n\n/* -------------------------------------------- */\n\n/**\n * Handle hook events.\n * @param {object} hookData\n * @param {string} hookName\n */\nfunction handleHookEvent(hookData, hookName) {\n if (!validateHookData(hookData, hookName)) return;\n game.tokenActionHud.update({ type: \"hook\", name: hookName, data: hookData });\n}\n\n/* -------------------------------------------- */\n\n/**\n * Validate hook data.\n * @param {object} hookData\n * @param {string} hookName\n * @returns {boolean} Whether the hook is valid\n */\nfunction validateHookData(hookData, hookName) {\n if (!game.tokenActionHud) return false;\n switch (hookName) {\n case \"deleteActor\":\n case \"updateActor\":\n return game.tokenActionHud.isValidActorOrItemUpdate(hookData[0], hookData[1]);\n case \"createActiveEffect\":\n case \"deleteActiveEffect\":\n return game.tokenActionHud.isControlledActor(hookData[0]?.parent);\n case \"createCombatant\":\n case \"updateCombatant\":\n return game.tokenActionHud.isControlledActor(hookData[0]?.actor);\n case \"deleteCompendium\":\n case \"updateCompendium\":\n return validateCompendium(hookData.source?.metadata?.id);\n case \"createItem\":\n case \"deleteItem\":\n case \"updateItem\":\n return game.tokenActionHud.isValidActorOrItemUpdate(hookData[0]?.actor);\n case \"createMacro\":\n case \"deleteMacro\":\n case \"updateMacro\":\n game.tokenActionHud.hudManager.actionHandler.macroActionHandler.clearCache();\n return true;\n case \"updateToken\":\n return Object.hasOwn(hookData[1], \"hidden\") && game.tokenActionHud.isValidTokenChange(hookData[0], hookData[1]);\n default:\n return true;\n }\n}\n\n/* -------------------------------------------- */\n\n/**\n * Validate compendium hook.\n * @param {string} id Compendium ID\n * @returns {boolean} Whether the compendium hook is valid\n */\nfunction validateCompendium(id) {\n const compendiumHandler = game.tokenActionHud.hudManager.actionHandler.compendiumActionHandler;\n if (!compendiumHandler.isLinkedCompendium(id)) return false;\n compendiumHandler.compendiumActions = new Map();\n return true;\n}\n\n/* -------------------------------------------- */\n/* CONTEXT MENU / Z-INDEX */\n/* -------------------------------------------- */\n\n/**\n * Add context menu listeners.\n * @param {object} html\n * @param {string} selector\n */\nfunction addContextMenuListener(html, selector) {\n const htmlElement = html[0] ?? html;\n const element = htmlElement.querySelector(selector);\n if (element) element.addEventListener(\"contextmenu\", sendHudToBottom);\n}\n\n/* -------------------------------------------- */\n\n/**\n * Send HUD to bottom.\n */\nfunction sendHudToBottom() {\n if (game.tokenActionHud?.element) {\n game.tokenActionHud.element.style.zIndex = 20;\n }\n}\n"],"names":["MODULE","ID","NAME","TEMPLATE_DIR","TEMPLATE","action","addPopover","customStyleForm","group","hud","listSubgroup","settings","tabSubgroup","formHud","formGroup","formSubgroup","DELIMITER","ACTION_TYPE","compendiumEntry","compendiumMacro","compendiumPlaylist","macro","COMPENDIUM_PACK_TYPES","CSS_STYLE","foundryVTT","class","file","moduleId","name","primaryColor","secondaryColor","tertiaryColor","compact","dockedLeft","isDocked","dockPosition","dockedCenterRight","collapseIcon","expandIcon","dockedRight","foundryVttLight","pathfinder","highContrast","custom","CUSTOM_STYLE","backgroundColor","cssProperty","type","String","default","buttonHeight","Number","buttonBackgroundColor","buttonBorderPrimaryColor","buttonBorderSecondaryColor","buttonTextColor","buttonHoverBorderPrimaryColor","buttonHoverBorderSecondaryColor","buttonHoverBackgroundColor","buttonHoverTextColor","buttonToggleActiveBackgroundColor","buttonToggleActiveBorderPrimaryColor","buttonToggleActiveBorderSecondaryColor","buttonToggleActiveTextColor","buttonToggleHoverBackgroundColor","buttonToggleHoverBorderPrimaryColor","buttonToggleHoverBorderSecondaryColor","buttonToggleHoverTextColor","textPrimaryColor","textSecondaryColor","textTertiaryColor","textHoverPrimaryColor","textHoverSecondaryColor","textHoverTertiaryColor","GROUP_TYPE","COMPENDIUM","CUSTOM","SYSTEM","SYSTEM_DERIVED","HUD","DEFAULT_HEIGHT","DEFAULT_WIDTH","DEFAULT_LEFT_POS","DEFAULT_TOP_POS","DEFAULT_SCALE","DEFAULT_ZINDEX","ITEM_MACRO_ICON","ICON","TOOLTIP","LAYOUT_SETTING","customLayout","hint","inputType","filePickerType","dtype","scope","userCustomLayout","exportLayout","label","icon","resetLayout","resetAllLayouts","SETTING","activeCssAsText","classes","cache","allow","alwaysShowHud","clickOpenCategory","customStyle","debug","direction","displayCharacterName","displayIcons","drag","enable","enableCustomization","grid","itemMacro","migrationVersion","reset","renderItemOnRightClick","rollHandler","scale","sortActions","startup","style","tooltips","Logger$1","Logger","info","message","notify","ui","notifications","console","log","error","permanent","data","isDebug","game","tokenActionHud","setting","Utils","getSetting","dataClone","deepClone","Timer","constructor","milliseconds","this","timer","start","abort","Promise","resolve","setTimeout","clearTimeout","checkAllow","userRole","allowSetting","capitalize","value","replace","text","charAt","toUpperCase","substring","toLowerCase","original","options","foundry","utils","getActor","actorId","tokenId","token","canvas","tokens","placeables","find","id","actor","actors","get","getClosestGroupElement","event","target","closest","getControlledActors","controlled","map","getStatusEffect","statusId","effects","effect","statuses","every","status","getImage","entity","defaultImages","push","result","img","includes","getItem","itemId","items","getToken","getControlledTokens","getFirstControlledToken","controlledToken","character","user","key","defaultValue","setSetting","set","getActorFlag","getFlag","setActorFlag","setFlag","unsetActorFlag","unsetFlag","getUserFlag","setUserFlag","unsetUserFlag","i18n","toTranslate","localize","isGmActive","users","some","isGM","active","isModuleActive","module","modules","getModuleTitle","title","getModuleVersion","version","humanizeBinding","keyboardManager","helpers","interaction","KeyboardManager","binding","keybindings","stringParts","modifiers","reduce","parts","part","MODIFIER_CODES","unshift","getKeycodeDisplayString","join","median","numbers","mid","Math","floor","length","nums","sort","a","b","getUpperQuartileAverage","sortedNumbers","slice","startIndex","ceil","endIndex","sum","count","i","upperQuartileAverage","getModifier","num","sign","sortItems","Map","entries","localeCompare","sortItemsByName","switchCSS","tahElement","document","querySelector","styleClass","isNewerVersion","classList","contains","PRESERVE","Set","classesToRemove","filter","c","has","remove","add","applyCustomStyles","removeCustomStyles","element","Object","saved","setProperty","values","removeProperty","registerHandlebars","Handlebars","registerHelper","string","reduceOp","args","reducer","Array","from","pop","first","shift","tokenActionHudCoreTrue","arguments","block","fn","inverse","getModuleVersionParts","moduleVersion","trigger","moduleVersionParts","split","major","minor","patch","isSystemModuleCompatible","requiredCoreModuleVersion","requiredCoreModuleVersionParts","coreModuleVersionParts","requiredVersion","installedVersion","getNestedGroups","groups","order","groupId","groupType","isArray","foundGroups","level","nestId","assign","keys","getGroupByNestId","findGroup","async","groupStyle","foundGroup","deleteGroupByNestId","findAndDeleteGroup","index","splice","deleteGroupsById","filePicker","applications","apps","FilePicker","implementation","DataHandler","socket","init","createDirectories","all","private","isPrivate","fileMap","getFilePathsAsGm","isPersistentStorage","ForgeVTT","DATA_FOLDER","moduleDirectory","directoriesToCreate","world","directory","browse","catch","createDirectory","path","getFileParts","filename","folder","hasPermission","files","getFilePaths","executeAsGM","getFilePathsWithSocket","dataHandler","actorFiles","userFiles","canSaveData","saveDataAsGm","saveData","saveDataWithSocket","fileName","encodeURI","File","JSON","stringify","response","upload","canGetData","getDataAsGm","getData","getDataWithSocket","foundFile","foundFolder","endsWith","ms","Date","now","fetch","ok","parse","getDataMigrate","folderPath","foundFolderPath","foundFilePath","then","json","MigrationManager","isSuccess","unsetOldFlags","migrateFiles","objects","children","scene","scenes","err","CharacterHandler","hudManager","groupHandler","actionHandler","previousActorId","setCharacter","isCharacter","isMultipleTokens","controlledTokens","isSameActor","resetCharacter","handleMultipleTokens","handleSingleToken","characterName","isValidCharacter","t","testUserPermission","LayoutHandler","systemManager","defaultLayout","setDefaultLayout","setCustomLayout","defaults","layout","softReset","hardReset","userId","saveDataToFile","getTooltip","tooltip","content","styles","GroupHandler","layoutHandler","defaultGroups","actorGroups","userGroups","setDefaultGroups","setSavedActorGroups","setSavedUserGroups","defaultGroup","getUserGroups","savedUserData","prepareGroups","userGroup","createGroup","selected","parentNestId","parentGroup","lists","tabs","getActorGroups","actorGroup","existingGroup","actions","getGroup","getGroups","startsWith","getGroupIds","getGroupSettings","groupData","keepData","groupDataClone","nestIdParts","defaultSettings","showTitle","groupSettings","subtitleClass","groupSystem","system","commonProps","cssClass","info1","info2","info3","listName","isSelected","defaultSelected","updateGroups","groupsData","parentGroupData","childGroupData","existingGroups","existingParentGroup","saveGroupSettings","saveGroups","saveActor","saveUser","saveActorGroups","saveUserGroups","getReducedGroupData","keepActions","isPreset","userSelected","getAvailableGroups","derivedGroups","getDerivedGroups","systemGroups","getSystemGroups","compendiumGroups","getCompendiumGroups","macroGroups","getMacroGroups","toChoice","packs","pack","documentName","visible","metadata","addGroup","update","parentGroups","updateGroup","updateExistingGroups","removeGroup","addGroupInfo","groupInfo","forEach","setHasActions","hasActions","HudManager","getActionHandlerCore","getRollHandlerCore","characterHandler","isHudEnabled","buildHud","softResetHud","hardResetHud","previousActor","isGmInactiveUserNotified","prepareHud","buildActionsCore","prepareActions","handleHudEvent","eventType","getAction","setKeyPresses","setIsHover","Hooks","call","handleGroupClickCore","handleActionClickCore","handleActionHoverCore","setIsRightClick","setIsAlt","setIsCtrl","setIsShift","button","originalEvent","isRightClick","isModiferActive","keyboard","isModifierActive","MODIFIER_KEYS","ALT","altKey","emulateKeypress","force","downKeys","isAlt","CONTROL","ctrlKey","isCtrl","SHIFT","shiftKey","isShift","isHover","groupElement","dataset","actionButtonElement","actionId","availableActions","role","resetLayoutDialog","api","DialogV2","confirm","window","modal","yes","callback","no","customLayoutElement","updateCachedSettings","userCustomLayoutElement","ApplicationV2","HandlebarsApplicationMixin","FormApp","super","submit","static","resetActions","form","closeOnSubmit","handler","position","width","height","tag","minimizable","resizable","_prepareContext","resetActorData","formData","object","HudFormApp","template","GroupFormApp","SubgroupFormApp","FormAppHelper","openEditHudApp","dialogData","callAll","render","openEditGroupApp","currentSettings","newName","trim","characterCount","customWidth","image","openAddGroupApp","baseId","slugify","replacement","strict","existingIds","g","suffix","newGroup","insertAt","max","min","newGroupData","openEditSubgroupApp","collapse","_style","deleteGroup","siblings","allChildren","descendantPrefix","deleteAction","remaining","updateActions","AddSubgroupApp","frame","available","onSelect","anchorRect","_onRender","context","root","maxHeight","viewportW","documentElement","clientWidth","viewportH","clientHeight","gap","left","round","top","bottom","input","querySelectorAll","customRow","customName","emptyRow","display","focusIndex","hasNavigated","isHidden","li","visibleItems","clearHighlight","el","highlight","vis","scrollIntoView","applyFilter","query","visibleCount","exactMatch","match","textContent","pick","close","addEventListener","ev","preventDefault","_outsideHandler","focus","removeEventListener","instances","delete","open","parentLevel","anchorElement","newTag","chosen","used","base","rect","getBoundingClientRect","app","AddActionApp","allActions","getAvailableActions","getSelectedActions","selectedIds","newEntry","combined","GroupResizer","minCols","isCustomWidth","spacing","resizeGroup","setVariables","subgroupsElement","setWidth","setHeight","resetVariables","setSubgroupsElement","resetGroupsElements","setSubgroupElementArr","actionsElements","availableHeight","availableWidth","gridWidth","subgroupElementArr","subgroupsElementPadding","subgroupsElementRect","level1GroupElement","groupsElements","overflowY","resetCSS","getGridWidth","emptyStyle","gridTemplateColumns","actionWidths","actionWidthsForMedian","actionsElement","actionElements","actionElement","actionRect","actionWidth","parseFloat","actionButtonText","actionButtonTextRect","actionButtonTextWidth","minActionButtonTextWidth","availableactionButtonTextWidth","resizeGrid","groupCustomWidth","assignCSS","squaredCols","sqrt","availableGroupWidth","availableCols","cols","resize","sqrtActions","currentRow","maxRowWidth","rowWidth","maxWidth","getAvailableWidth","windowWidth","screenDimensions","innerWidth","contentLeft","uiRight","uiRightClientWidth","subgroupsElementComputed","getComputedStyle","paddingLeft","paddingRight","hasGrid","subgroupElement","requestAnimationFrame","getAvailableHeight","windowHeight","innerHeight","contentBottom","contentTop","uiTopBottom","siblingsHeight","sibling","nextElementSibling","siblingHeight","hotbar","hotbarTop","bottomBlocker","uiTopBottomOffsetHeight","offsetHeight","elements","TokenActionHud","openGroups","updatePendingTimer","updateTimer","closeTimer","renderTimer","clickGroup","buttons","clickSubgroup","clickAction","collapseHud","expandHud","lockHud","unlockHud","editHud","addSubgroup","addAction","background","zIndex","styleKey","styleData","collapsibleSubgroups","cacheSettings","updateSettingsPending","setPosition","updateDragButtonVisibility","cacheElements","setInitialHudState","addHoverEvents","_rootListenersAttached","attachRootListeners","setupContextMenus","updateDraggableState","isUnlockedOverride","dragButton","isUnlocked","isDraggable","show","toggle","actionArr","tabSubgroupArr","editHudButton","listSubgroupsArr","subgroupsContainerArr","groupArr","subgroupArr","listSubgroupTitleArr","groupButtonArr","addGroupButtonArr","addSubgroupButtonArr","addActionButtonArr","collapseExpandContainer","collapseHudButton","expandHudButton","unlockButton","lockButton","isCollapsed","hoverToggle","toggleGroup","passive","dragEvent","bind","handleActionHover","actionButton","isEditing","actionOptsIn","hasContextMenu","_actionContextMenu","_onActivate","_groupContextMenu","onDragStart","onDragEnter","onDragOver","onDragLeave","onDrop","onDragEnd","postRender","rendering","applyDirection","reopenGroups","size","parseInt","isNaN","toggleHudEnable","state","isEnabled","format","toggleHudCollapse","isCollapsing","toggleHudLock","isUnlocking","toggleElements","className","showAddGroup","hideIfEmpty","updateTooltipsState","keepSelector","matches","setAttribute","getAttribute","removeAttribute","bringToFront","currentTarget","blur","handleGroupClick","collapseExpandSubgroup","isOpen","shouldOpen","toggleOtherGroups","groupResizer","groupToIgnore","isParentToIgnore","resizeTarget","groupsElement","imageElement","toggleGroupVisibility","triggerElement","parsedLevel","buildGroupContextMenuItems","isContextSubgroupExpanded","onClick","toggleContextSubgroup","confirmDeleteGroup","getContextSubgroupElement","sg","inner","buildActionContextMenuItems","confirmDeleteAction","ContextMenu","ux","sharedOptions","fixed","eventName","jQuery","groupItems","actionItems","prepareContextMenuItems","item","out","undefined","condition","groupEl","confirmed","subgroupEl","canDrag","apply","resolveDraggable","node","hasAttribute","getActionSiblings","source","parent","parentElement","findNearestActionSibling","clientX","clientY","nearest","minDist","Infinity","cx","cy","d","hypot","getDropTargetsForSource","sourceLevel","btn","findNearestDropTarget","targets","stopPropagation","parentSubgroup","_dragState","dataTransfer","effectAllowed","setData","transparentImage","createElement","src","setDragImage","dropEffect","onDragOverAction","CSS","escape","plus","clearDropIndicators","findActionSourceElement","before","relatedTarget","onDropAction","reorderGroupToPosition","sourceNestId","dropBefore","targetButton","targetActionId","reorderActionToPosition","sourceActionId","sIdx","findIndex","moved","tIdx","payload","clamped","listPayload","tabPayload","changedTouches","pos1","pos2","pos3","pos4","originalElementTop","offsetTop","originalElementLeft","offsetLeft","newElementTop","newElementLeft","mouseMoveEvent","topPos","mouseUpEvent","onmousemove","ontouchmove","onmouseup","ontouchend","hudPosition","setDockedPosition","setUndockedPosition","interfaceElement","isV13","sidebarElement","prepend","appendChild","rightUiElement","insertBefore","leftUiElement","body","setPositionFromFlag","check","leftPos","resetPosition","copy","fromUserId","toUserIds","copyUserData","fromGroup","resetLayoutWithSocket","resetUserAndActorData","resetAllActorData","resetUserData","resetAllUserData","handleUpdate","performUpdate","isUpdatePending","waitForUpdateCompletion","maxWaitTime","interval","iterations","isUpdating","hasCompleted","initialised","abortUpdate","closeHud","animate","isValidTokenChange","flags","isRelevantToken","isControlledActor","isValidActorOrItemUpdate","obj","bool","registerSocket","socketlib","registerModule","register","isSocketlibActive","getSocket","GenericActionHandler","buildActions","buildUtilities","buildSingleTokenUtilities","buildMultipleTokenUtilities","actionsData","toggleCombatId","toggleCombatName","inCombat","toggleCombatAction","toggleCombatant","toggleVisibilityId","toggleVisibilityName","hidden","toggleVisibilityAction","addActions","toggleVisibilityname","CompendiumActionHandler","compendiumActions","packIds","packId","setActions","getIndex","actionType","getCompendiumActionType","entry","createAction","_id","getOnClick","getGroupId","documentId","getOnClickFunction","getOnClickEntry","journalEntry","getDocument","sheet","execute","isLinkedCompendium","MacroActionHandler","clearCache","macroActions","getActions","macros","getListName","ownership","actionTypeName","ActionHandler","genericActionHandler","compendiumActionHandler","macroActionHandler","delimiter","actionHandlerExtenders","buildSystemActionsCore","buildGenericActionsCore","buildCompendiumActionsCore","buildMacroActionsCore","buildExtendedActionsCore","updateNonPresetActions","setCharacterLimit","groupIds","buildSystemActions","extender","extendActionHandler","nonPresetActions","nonPresetAction","availableAction","systemSelected","groupCharacterCount","subgroups","subgroup","subgroupCharacterCount","word","shouldSortActions","topLevelNestId","topLevelGroup","actionData","fullName","infoProps","onHover","encodedValue","icons","icon1","icon2","icon3","isAction","isItem","useRawHtmlName","addToAvailableActions","existingActions","reorderedActions","existingAction","existingActionId","actionClone","addActionHandlerExtender","actionHandlerExtender","ActionHandlerExtender","RollHandler","preRollHandlers","rollHandlerExtenders","throwInvalidValueErr","Error","addRollHandlerExtender","rollHandlerExtender","buttonValue","getButtonValue","prehandleActionEvent","handleActionClick","addPreRollHandler","buttonElement","renderItem","isRenderItem","PreRollHandler","RollHandlerExtender","CustomStyleForm","ColorPicker","install","isCustom","resetAllLayoutsDialog","executeForEveryone","TahSettingsForm","range","choices","settingType","Function","isButton","isCheckbox","isFilePicker","isNumber","isRange","isSelect","TahSettingsFormLayout","onChangeFunction","on","editable","onDown","registerSettingsCore","rollHandlers","registerMenu","restricted","config","Boolean","onChange","styleChoices","fromEntries","requiresReload","auto","up","down","step","always","whenUnlocked","never","full","nameOnly","none","setTooltipDelay","tooltipDelay","both","registerCustomStyleSettings","registerSettings","ItemMacroActionHandlerExtender","itemacro","command","itemMacroSetting","replaceExisting","addGroupActions","existingItemMacroAction","actionToReplace","macroAction","createItemMacroAction","substr","indexOf","itemMacroIcon","executeMacro","SystemManager","coreModuleId","getActionHandler","getRollHandler","rollHandlerId","getAvailableRollHandlers","registerDefaults","registerStyles","registerDefaultsCore","registerStylesCore","systemStyles","mergeObject","addActionHandlerExtenders","addRollHandlerExtenders","addHandler","registerApi","registerCoreModule","systemModule","handlebars","loadTemplates","registerHud","migrationManager","checkColorPicker","registerHudHooks","hooks","hook","handleHookEvent","hookData","hookName","validateHookData","validateCompendium","hasOwn","compendiumHandler","addContextMenuListener","html","selector","htmlElement","sendHudToBottom","once","_"],"mappings":"AAGO,MAAMA,EAAS,CACpBC,GAAI,wBACJC,KAAM,oBASFC,EAAe,WAAWH,EAAOC,eAO1BG,EAAW,CACtBC,OAAQ,GAAGF,eACXG,WAAY,GAAGH,oBACfI,gBAAiB,GAAGJ,0BACpBK,MAAO,GAAGL,cACVM,IAAK,GAAGN,YACRO,aAAc,GAAGP,sBACjBQ,SAAU,GAAGR,iBACbS,YAAa,GAAGT,qBAChBU,QAAS,GAAGV,iBACZW,UAAW,GAAGX,mBACdY,aAAc,GAAGZ,uBAQNa,EAAY,IAOZC,EAAc,CACzBC,gBAAiB,iCACjBC,gBAAiB,iCACjBC,mBAAoB,oCACpBC,MAAO,wBAeIC,EAAwB,CAAC,eAAgB,QAAS,aAOlDC,EAAY,CACvBC,WAAY,CACVC,MAAO,6BACPC,KAAM,uBACNC,SAAU3B,EAAOC,GACjB2B,KAAM,mBACNC,aAAc,UACdC,eAAgB,YAChBC,cAAe,WAEjBC,QAAS,CACPP,MAAO,qCACPC,KAAM,+BACNC,SAAU3B,EAAOC,GACjB2B,KAAM,2BACNC,aAAc,UACdC,eAAgB,YAChBC,cAAe,WAEjBE,WAAY,CACVR,MAAO,wBACPC,KAAM,kBACNC,SAAU3B,EAAOC,GACjB2B,KAAM,+BACNC,aAAc,UACdC,eAAgB,YAChBC,cAAe,UACfG,UAAU,EACVC,aAAc,QAEhBC,kBAAmB,CACjBX,MAAO,yBACPC,KAAM,mBACNC,SAAU3B,EAAOC,GACjB2B,KAAM,uCACNC,aAAc,UACdC,eAAgB,YAChBC,cAAe,UACfM,aAAc,iBACdC,WAAY,gBACZJ,UAAU,EACVC,aAAc,gBAEhBI,YAAa,CACXd,MAAO,yBACPC,KAAM,mBACNC,SAAU3B,EAAOC,GACjB2B,KAAM,gCACNC,aAAc,UACdC,eAAgB,YAChBC,cAAe,UACfM,aAAc,iBACdC,WAAY,gBACZJ,UAAU,EACVC,aAAc,SAEhBK,gBAAiB,CACff,MAAO,8BACPC,KAAM,wBACNC,SAAU3B,EAAOC,GACjB2B,KAAM,oBACNC,aAAc,UACdC,eAAgB,YAChBC,cAAe,WAEjBU,WAAY,CACVhB,MAAO,uBACPC,KAAM,iBACNC,SAAU3B,EAAOC,GACjB2B,KAAM,cAERc,aAAc,CACZjB,MAAO,0BACPC,KAAM,oBACNC,SAAU3B,EAAOC,GACjB2B,KAAM,gBACNC,aAAc,UACdC,eAAgB,UAChBC,cAAe,WAEjBY,OAAQ,CACNlB,MAAO,mBACPC,KAAM,aACNC,SAAU3B,EAAOC,GACjB2B,KAAM,WASGgB,EAAe,CAC1BC,gBAAiB,CAAEC,YAAa,yBAA0BC,KAAMC,OAAQC,QAAS,aACjFC,aAAc,CAAEJ,YAAa,+BAAgCC,KAAMI,OAAQF,QAAS,IACpFG,sBAAuB,CAAEN,YAAa,yCAA0CC,KAAMC,OAAQC,QAAS,aACvGI,yBAA0B,CAAEP,YAAa,6CAA8CC,KAAMC,OAAQC,QAAS,aAC9GK,2BAA4B,CAAER,YAAa,+CAAgDC,KAAMC,OAAQC,QAAS,aAClHM,gBAAiB,CAAET,YAAa,mCAAoCC,KAAMC,OAAQC,QAAS,aAC3FO,8BAA+B,CAAEV,YAAa,mDAAoDC,KAAMC,OAAQC,QAAS,aACzHQ,gCAAiC,CAAEX,YAAa,qDAAsDC,KAAMC,OAAQC,QAAS,aAC7HS,2BAA4B,CAAEZ,YAAa,+CAAgDC,KAAMC,OAAQC,QAAS,aAClHU,qBAAsB,CAAEb,YAAa,yCAA0CC,KAAMC,OAAQC,QAAS,aACtGW,kCAAmC,CAAEd,YAAa,uDAAwDC,KAAMC,OAAQC,QAAS,aACjIY,qCAAsC,CAAEf,YAAa,2DAA4DC,KAAMC,OAAQC,QAAS,aACxIa,uCAAwC,CAAEhB,YAAa,6DAA8DC,KAAMC,OAAQC,QAAS,aAC5Ic,4BAA6B,CAAEjB,YAAa,iDAAkDC,KAAMC,OAAQC,QAAS,aACrHe,iCAAkC,CAAElB,YAAa,sDAAuDC,KAAMC,OAAQC,QAAS,aAC/HgB,oCAAqC,CAAEnB,YAAa,0DAA2DC,KAAMC,OAAQC,QAAS,aACtIiB,sCAAuC,CAAEpB,YAAa,qDAAsDC,KAAMC,OAAQC,QAAS,aACnIkB,2BAA4B,CAAErB,YAAa,gDAAiDC,KAAMC,OAAQC,QAAS,aACnHmB,iBAAkB,CAAEtB,YAAa,oCAAqCC,KAAMC,OAAQC,QAAS,aAC7FoB,mBAAoB,CAAEvB,YAAa,sCAAuCC,KAAMC,OAAQC,QAAS,aACjGqB,kBAAmB,CAAExB,YAAa,qCAAsCC,KAAMC,OAAQC,QAAS,aAC/FsB,sBAAuB,CAAEzB,YAAa,0CAA2CC,KAAMC,OAAQC,QAAS,aACxGuB,wBAAyB,CAAE1B,YAAa,4CAA6CC,KAAMC,OAAQC,QAAS,aAC5GwB,uBAAwB,CAAE3B,YAAa,qCAAsCC,KAAMC,OAAQC,QAAS,cAQzFyB,EAAa,CACxBC,WAAY,aACZC,OAAQ,SACRC,OAAQ,SACRC,eAAgB,kBAQLC,EAAM,CACjBC,eAAgB,IAChBC,cAAe,GACfC,iBAAkB,IAClBC,gBAAiB,GACjBC,cAAe,EACfC,eAAgB,KAQLC,EAAkB,CAC7BC,KAAM,iBACNC,QAAS,cAQEC,EAAiB,CAC5BC,aAAc,CACZC,KAAM,4CACN/D,KAAM,4CACNgE,UAAW,aACXC,eAAgB,OAChBC,MAAO,SACPC,MAAO,SAETC,iBAAkB,CAChBL,KAAM,gDACN/D,KAAM,gDACNgE,UAAW,aACXC,eAAgB,OAChBC,MAAO,SACPC,MAAO,QAETE,aAAc,CACZN,KAAM,4CACNO,MAAO,6CACPtE,KAAM,4CACNgE,UAAW,SACXO,KAAM,0BACN9F,OAAQ,gBAEV+F,YAAa,CACXT,KAAM,2CACNO,MAAO,4CACPtE,KAAM,2CACNgE,UAAW,SACXO,KAAM,gCACN9F,OAAQ,cACR0F,MAAO,UAETM,gBAAiB,CACfV,KAAM,+CACNO,MAAO,gDACPtE,KAAM,+CACNgE,UAAW,SACXO,KAAM,mBACN9F,OAAQ,kBACR0F,MAAO,UASEO,EAAU,CACrBC,gBAAiB,CAAEC,QAAS,CAAC,kBAAmBC,OAAO,GACvDC,MAAO,CAAEF,QAAS,CAAC,kBAAmBC,OAAO,GAC7CE,cAAe,CAAEH,QAAS,CAAC,kBAAmBC,OAAO,GACrD5D,gBAAiB,CAAE,EACnBO,sBAAuB,CAAE,EACzBC,yBAA0B,CAAE,EAC5BC,2BAA4B,CAAE,EAC9BJ,aAAc,CAAE,EAChBM,8BAA+B,CAAE,EACjCC,gCAAiC,CAAE,EACnCC,2BAA4B,CAAE,EAC9BC,qBAAsB,CAAE,EACxBJ,gBAAiB,CAAE,EACnBK,kCAAmC,CAAE,EACrCC,qCAAsC,CAAE,EACxCC,uCAAwC,CAAE,EAC1CC,4BAA6B,CAAE,EAC/BC,iCAAkC,CAAE,EACpCC,oCAAqC,CAAE,EACvCC,sCAAuC,CAAE,EACzCC,2BAA4B,CAAE,EAC9ByC,kBAAmB,CAAEJ,QAAS,CAAC,kBAAmBC,OAAO,GACzDf,aAAc,CAAEc,QAAS,CAAC,iBAAkBC,OAAO,GACnDI,YAAa,CAAE,EACfC,MAAO,CAAEN,QAAS,CAAC,kBAAmBC,OAAO,GAC7CM,UAAW,CAAEP,QAAS,CAAC,kBAAmBC,OAAO,GACjDO,qBAAsB,CAAER,QAAS,CAAC,kBAAmBC,OAAO,GAC5DQ,aAAc,CAAET,QAAS,CAAC,kBAAmBC,OAAO,GACpDS,KAAM,CAAEV,QAAS,CAAC,kBAAmBC,OAAO,GAC5CU,OAAQ,CAAEX,QAAS,CAAC,kBAAmBC,OAAO,GAC9CW,oBAAqB,CAAEZ,QAAS,CAAC,gBAAiB,kBAAmBC,OAAO,GAC5EY,KAAM,CAAEb,QAAS,CAAC,kBAAmBC,OAAO,GAC5Ca,UAAW,CAAE,EACbC,iBAAkB,CAAE,EACpBC,MAAO,CAAE,EACTC,uBAAwB,CAAE,EAC1BC,YAAa,CAAEzE,QAAS,QACxB0E,MAAO,CAAEnB,QAAS,CAAC,kBAAmBC,OAAO,GAC7CmB,YAAa,CAAEpB,QAAS,CAAC,iBAAkBC,OAAO,GAClDoB,QAAS,CAAE,EACXC,MAAO,CAAEtB,QAAS,CAAC,kBAAmBC,OAAO,GAC7CsB,SAAU,CAAEvB,QAAS,CAAC,iBAAkBC,OAAO,GAC/CrC,iBAAkB,CAAE,EACpBC,mBAAoB,CAAE,EACtBC,kBAAmB,CAAE,EACrBC,sBAAuB,CAAE,EACzBC,wBAAyB,CAAE,EAC3BC,uBAAwB,CAAE,EAC1BuB,iBAAkB,CAAEQ,QAAS,CAAC,iBAAkBC,OAAO,ICxUlD,IAAAuB,EAAA,MAAMC,OAMX,WAAOC,CAAKC,EAASC,GAAS,GACxBA,EAAQC,GAAGC,cAAcJ,KAAK,sBAAsBC,KACnDI,QAAQC,IAAI,2BAA2BL,IAC7C,CASD,YAAOM,CAAMN,EAASC,GAAS,GACzBA,EAAQC,GAAGC,cAAcG,MAAM,sBAAsBN,IAAW,CAAEO,WAAW,IAC5EH,QAAQE,MAAM,4BAA4BN,IAChD,CASD,YAAOrB,CAAMqB,EAASQ,EAAO,MAC3B,MAAMC,EAAUC,KAAKC,gBAAgBC,SAASjC,OAASkC,MAAMC,WAAW,SACxE,GAAIL,EAAS,CACX,IAAKD,EAEH,YADAJ,QAAQC,IAAI,4BAA4BL,KAG1C,MAAMe,EAAYF,MAAMG,UAAUR,GAClCJ,QAAQC,IAAI,4BAA4BL,IAAWe,EACpD,CACF,GAQI,MAAME,MACX,WAAAC,CAAYC,GACVC,KAAKD,aAAeA,EACpBC,KAAKC,MAAQ,IACd,CAED,WAAMC,GAEJ,OADIF,KAAKC,OAAOD,KAAKG,QACd,IAAIC,SAAQC,IACjBL,KAAKC,MAAQK,YAAW,KAAQD,GAAS,GAAKL,KAAKD,cAAgB,IAAI,GAE1E,CAED,WAAMI,GACJI,aAAaP,KAAKC,OAClBD,KAAKC,MAAQ,IACd,EAQI,MAAMR,MAaX,iBAAOe,CAAWC,EAAUC,GAC1B,OAAOD,GAAYC,CACpB,CASD,iBAAOC,CAAWC,GAChB,OAAOA,EAAMC,QACX,UACAC,GAAQA,EAAKC,OAAO,GAAGC,cAAgBF,EAAKG,UAAU,GAAGC,eAE5D,CAWD,gBAAOtB,CAAUuB,EAAUC,GAEzB,OAAOC,QAAQC,MAAM1B,UAAUuB,EAAUC,EAC1C,CAaD,eAAOG,CAASC,EAASC,GACvB,IAAIC,EAAQ,KAEZ,OADID,IAASC,EAAQC,OAAOC,OAAOC,WAAWC,MAAKJ,GAASA,EAAMK,KAAON,KACrEC,EAAcA,EAAMM,MACjB1C,KAAK2C,OAAOC,IAAIV,EACxB,CAOD,6BAAOW,CAAuBC,GAC5B,OAAKA,EACEA,EAAMC,OAAOC,QAAQ,2BAA+BF,EAAMC,OAAOC,QAAQ,uBAD7D,IAEpB,CASD,0BAAOC,GACL,MAAMX,EAAStC,KAAKqC,OAAOC,QAAQY,YAAc,GACjD,OAAOZ,EAAOa,KAAIf,GAASA,EAAMM,OAClC,CAUD,sBAAOU,CAAgBV,EAAOW,GAC5B,OAAOX,EAAMY,QAAQd,MAAKe,GAAUA,EAAOC,SAASC,OAAMC,GAAUA,IAAWL,KAChF,CAWD,eAAOM,CAASC,EAAQC,EAAgB,IACtCA,EAAcC,KAAK,6BACnB,IAAIC,EAAS,GAMb,OALI/D,KAAKC,gBAAgBC,SAAS9B,eAChC2F,EAA4B,iBAAXH,EACbA,EACAA,GAAQI,KAAOJ,GAAQtG,MAAQ,IAE7BuG,EAAcI,SAASF,GAAmB,GAATA,CAC1C,CAWD,cAAOG,CAAQxB,EAAOyB,GACpB,OAAOzB,EAAM0B,MAAMxB,IAAIuB,EACxB,CAUD,eAAOE,CAASlC,GACd,OAAOE,OAAOC,OAAOC,WAAWC,MAAKJ,GAASA,EAAMK,KAAON,GAC5D,CASD,0BAAOmC,GACL,OAAOtE,KAAKqC,OAAOC,QAAQY,YAAc,EAC1C,CASD,8BAAOqB,GACL,MAAMC,EAAkBxE,KAAKqC,OAAOC,OAAOY,WAAW,GACtD,GAAIsB,EACF,OAAOA,EAGT,MAAMC,EAAYzE,KAAK0E,MAAMD,UAC7B,OAAIA,EACKpC,OAAOC,OAAOC,WAAWC,MAAKJ,GAASA,EAAMM,OAAOD,KAAOgC,EAAUhC,KAGvE,IACR,CAaD,iBAAOrC,CAAWuE,EAAKC,EAAe,MACpC,IAAItD,EAAQsD,GAAgB,KAC5B,IACEtD,EAAQtB,KAAKlI,SAAS8K,IAAIzL,EAAOC,GAAIuN,EAC3C,CAAM,MACAvF,EAAOnB,MAAM,YAAY0G,eAC1B,CACD,OAAOrD,CACR,CAUD,uBAAauD,CAAWF,EAAKrD,GACvBtB,KAAKlI,SAASA,SAAS8K,IAAI,GAAGzL,EAAOC,MAAMuN,YACvC3E,KAAKlI,SAASgN,IAAI3N,EAAOC,GAAIuN,EAAKrD,GACxClC,EAAOnB,MAAM,YAAY0G,cAAgBrD,OACxB,UAARqD,GACTvF,EAAOnB,MAAM,YAAY0G,eAE5B,CAUD,mBAAOI,CAAaJ,GAClB,OAAO3E,KAAKC,eAAeyC,MAAMsC,QAAQ7N,EAAOC,GAAIuN,EACrD,CAUD,yBAAaM,CAAaN,EAAKrD,SACvBtB,KAAKC,eAAeyC,MAAMwC,QAAQ/N,EAAOC,GAAIuN,EAAKrD,EACzD,CASD,2BAAa6D,CAAeR,SACpB3E,KAAKC,eAAeyC,MAAM0C,UAAUjO,EAAOC,GAAIuN,EACtD,CAUD,kBAAOU,CAAYV,GACjB,OAAO3E,KAAK0E,KAAKM,QAAQ7N,EAAOC,GAAIuN,EACrC,CAUD,wBAAaW,CAAYX,EAAKrD,SACtBtB,KAAK0E,KAAKQ,QAAQ/N,EAAOC,GAAIuN,EAAKrD,EACzC,CASD,0BAAaiE,CAAcZ,SACnB3E,KAAK0E,KAAKU,UAAUjO,EAAOC,GAAIuN,EACtC,CAYD,WAAOa,CAAKC,GACV,OAAOzF,KAAKwF,KAAKE,SAASD,EAC3B,CASD,iBAAOE,GACL,OAAO3F,KAAK4F,MAAMC,MAAKnB,GAAQA,EAAKoB,MAAQpB,EAAKqB,QAClD,CAUD,qBAAOC,CAAelN,GACpB,MAAMmN,EAASjG,KAAKkG,QAAQtD,IAAI9J,GAChC,OAAOmN,GAAUA,EAAOF,MACzB,CAUD,qBAAOI,CAAerN,GACpB,OAAOkH,KAAKkG,QAAQtD,IAAI9J,IAAWsN,OAAS,EAC7C,CAUD,uBAAOC,CAAiBvN,GACtB,OAAOkH,KAAKkG,QAAQtD,IAAI9J,IAAWwN,SAAW,EAC/C,CASD,sBAAOC,CAAgB5B,GACrB,MAAM6B,EAAkBzE,SAAS0E,SAASC,aAAaC,iBAAmBA,gBACpEC,EAAU5G,KAAK6G,YAAYjE,IAAIzL,EAAOC,GAAIuN,GAChD,IAAKiC,EAAS,MAAO,GACrB,MAAME,EAAcF,EAAQ,GAAGG,UAAUC,QAAO,CAACC,EAAOC,KAClDV,EAAgBW,eAAeD,IAAOjD,SAAS2C,EAAQ,GAAGjC,MAC9DsC,EAAMG,QAAQZ,EAAgBa,wBAAwBH,IADqBD,IAG1E,CAACT,EAAgBa,wBAAwBT,EAAQ,GAAGjC,OACvD,OAAOmC,EAAYQ,KAAK,MACzB,CAYD,aAAOC,CAAOC,GACZ,MAAMC,EAAMC,KAAKC,MAAMH,EAAQI,OAAS,GAClCC,EAAO,IAAIL,GAASM,MAAK,CAACC,EAAGC,IAAMD,EAAIC,IAC7C,OAAOR,EAAQI,OAAS,GAAM,EAAIC,EAAKJ,IAAQI,EAAKJ,EAAM,GAAKI,EAAKJ,IAAQ,CAC7E,CASD,8BAAOQ,CAAwBT,GAC7B,MAAMU,EAAgBV,EAAQW,QAAQL,MAAK,CAACC,EAAGC,IAAMD,EAAIC,IACnDJ,EAASM,EAAcN,OACvBQ,EAAaV,KAAKW,KAAc,IAATT,GACvBU,EAAWV,EAAS,EAE1B,IAAIW,EAAM,EACNC,EAAQ,EAEZ,IAAK,IAAIC,EAAIL,EAAYK,GAAKH,EAAUG,IACtCF,GAAOL,EAAcO,GACrBD,IAGF,MAAME,EAAuBH,EAAMC,EAEnC,OAAOE,CACR,CASD,kBAAOC,CAAYC,GACjB,IAAKA,GAAe,IAARA,EAAW,MAAO,GAC9B,MAAMC,EAAQD,GAAO,EAAK,IAAM,GAChC,MAAO,GAAGC,IAAOD,GAClB,CAYD,gBAAOE,CAAU1E,GACf,OAAO,IAAI2E,IAAI,IAAI3E,EAAM4E,WAAWlB,MAAK,CAACC,EAAGC,IAAMD,EAAE,GAAGD,KAAKmB,cAAcjB,EAAE,GAAGF,QACjF,CAUD,sBAAOoB,CAAgB9E,GACrB,OAAO,IAAI2E,IAAI,IAAI3E,EAAM4E,WAAWlB,MAAK,CAACC,EAAGC,IAAMD,EAAE,GAAGhP,KAAKkQ,cAAcjB,EAAE,GAAGjP,QACjF,CAWD,gBAAOoQ,CAAUlK,GACf,MAAMmK,EAAaC,SAASC,cAAc,yBAC1C,GAAIF,EAAY,CACT1Q,EAAUuG,KAAQA,EAAQ,cAC/B,MAAMsK,EAAaxH,QAAQC,MAAMwH,eAAexJ,KAAKsG,QAAS,WAAa,CAAC,aAAc,oBAAqB,eAAerC,SAAShF,GACnI,GAAGvG,EAAUuG,GAAOrG,YACpBF,EAAUuG,GAAOrG,MAErB,GAAIwQ,EAAWK,UAAUC,SAASH,GAAa,OAE/C,MAAMI,EAAW,IAAIC,IAAI,CAAC,eAAgB,aACpCC,EAAkB,IAAIT,EAAWK,WAAWK,QAAOC,IAAMJ,EAASK,IAAID,KACxEF,EAAgBjC,QAAQwB,EAAWK,UAAUQ,OAAOJ,GACxDT,EAAWK,UAAUS,IAAIX,GAEX,WAAVtK,EACFkB,MAAMgK,kBAAkBf,GAExBjJ,MAAMiK,mBAAmBhB,EAE5B,CACF,CASD,wBAAOe,CAAkBE,GACvB,IAAK,MAAO1F,EAAKrD,KAAUgJ,OAAOtB,QAAQjP,GAAe,CACvD,MAAMwQ,EAAQpK,MAAMC,WAAWuE,GAClB,MAAT4F,GACFF,EAAQpL,MAAMuL,YAAYlJ,EAAMrH,YAAasQ,EAEhD,CACF,CASD,yBAAOH,CAAmBC,GACxB,IAAK,MAAM/I,KAASgJ,OAAOG,OAAO1Q,GAChCsQ,EAAQpL,MAAMyL,eAAepJ,EAAMrH,YAEtC,CAUD,yBAAO0Q,GAELC,WAAWC,eAAe,yBAAyB,SAASC,GAC1D,OAAKA,GAAUA,EAAOlD,OAAS,EAAU,GAClCkD,EAAO,GAAGpJ,cAAgBoJ,EAAO3C,MAAM,EACpD,IACI,MAAM4C,SAAW,SAASC,EAAMC,GAC9BD,EAAOE,MAAMC,KAAKH,GAClBA,EAAKI,MACL,MAAMC,EAAQL,EAAKM,QACnB,OAAON,EAAKhE,OAAOiE,EAASI,EAClC,EAGIT,WAAWC,eAAe,CACxBU,uBAAwB,WAAa,OAAOR,SAASS,WAAWzD,GAAKA,GAAK,IAI5E6C,WAAWC,eAAe,gCAAgC,SAASY,GACjE,OAAIzL,KAAKC,gBAAgBC,SAASxC,gBACzB+N,EAAMC,GAAGhL,MAEX+K,EAAME,QAAQjL,KAC3B,GACG,CAYD,4BAAOkL,CAAsBC,GAC3B,IAAKA,EAEH,OADAzM,EAAOnB,MAAM,+BAAgC,CAAE6N,QAAS,0BACjD,KAET,MAAMC,EAAqBF,EAAcG,MAAM,KAC/C,MAAO,CACLC,MAAOF,EAAmB,GAC1BG,MAAOH,EAAmB,GAC1BI,MAAOJ,EAAmB,GAE7B,CAUD,+BAAOK,CAAyBC,GAC9B,IAAKA,EAA2B,OAAO,EAGvC,MAAMC,EAAiC5L,KAAKkL,sBAAsBS,GAC5DE,EAAyB7L,KAAKkL,sBAAsB5L,KAAKkG,QAAQtD,IAAIzL,EAAOC,IAAIkP,SAEtF,GAAIiG,EAAuBN,QAAUK,EAA+BL,OAC9DK,EAA+BJ,OAASK,EAAuBL,QAAUI,EAA+BJ,OACxGI,EAA+BH,OAASI,EAAuBJ,QAAUG,EAA+BH,MAC5G,CACA,MAAMK,EAAkB,GAAGF,EAA+BL,SAASK,EAA+BJ,OAAS,OAAOI,EAA+BH,OAAS,MACpJM,EAAmBzM,KAAKkG,QAAQtD,IAAIzL,EAAOC,IAAIkP,QAKrD,OAJA9G,GAAGC,cAAcG,MACf,8FAA8F4M,kBAAgCC,gEAA+ED,sJAC7M,CAAE3M,WAAW,KAER,CACR,CACD,OAAO,CACR,CAaD,sBAAO6M,CAAgBC,EAAQ7M,EAAO,IACpC,IAAI8M,EAAQ,EACZ,IAAKD,EAAQ,OAAO,KACpB,MAAME,EAAU/M,GAAM2C,GAChBqK,EAAYhN,GAAM5F,KACxByS,EAAUzB,MAAM6B,QAAQJ,GAAWA,EAASrC,OAAOG,OAAOkC,GAC1D,MAAMK,EAAc,CAAA,EACpB,IAAK,MAAMrV,KAASgV,EAAQ,CAC1B,KAAME,GAAWlV,EAAM8K,KAAOoK,GAAcC,GAAanV,EAAMuC,OAAS4S,GAAY,CAClFF,IACA,MAAMK,EAAQtV,EAAMuV,OAAOlB,MAAM,KAAKpE,OACtCoF,EAAYrV,EAAMuV,QAAU,IAAKvV,EAAOiV,QAAOK,QAChD,CACD,GAAItV,EAAMgV,QAAQ/E,OAAS,EAAG,CAC5B,MAAM+E,EAASjM,KAAKgM,gBAAgB/U,EAAMgV,OAAQ7M,GAC9C6M,GAAQrC,OAAO6C,OAAOH,EAAaL,EACxC,CACF,CACD,OAAQrC,OAAO8C,KAAKJ,GAAapF,OAAS,EAAKoF,EAAc,IAC9D,CAWD,6BAAaK,CAAiBV,EAAQ7M,EAAO,IAC3C,MAAMoN,EAA0B,iBAATpN,EAAoBA,EAAOA,GAAMoN,OAClDJ,EAAYhN,GAAM5F,KACxB,IAAKgT,EAAQ,OAAO,KAEpB,MAAMjG,EAAQiG,EAAOlB,MAAM,KAC3B,aAAasB,UAAUX,EAAQ1F,GAU/BsG,eAAeD,UAAUX,EAAQ1F,GAC/B,IAAK0F,EAAQ,OAAO,KACpBA,EAAUzB,MAAM6B,QAAQJ,GAAWA,EAASrC,OAAOG,OAAOkC,GAC1D,IAAK,MAAMhV,KAASgV,EAClB,GAAIhV,EAAM8K,KAAOwE,EAAM,GAAI,CACzB,GAAqB,IAAjBA,EAAMW,OACR,OAAKjQ,EAAMuC,MAAS4S,GAAanV,EAAMuC,OAAS4S,OAChD,EADkEnV,EAIpE,GADAsP,EAAMqE,SACD3T,EAAMgV,OAAQ,SACnB,IAAK,MAAMa,KAAclD,OAAOG,OAAO9S,EAAMgV,QAAS,CACpD,GAA0B,IAAtBa,EAAW5F,OAAc,SAC7B,MAAM6F,QAAmBH,UAAUE,EAAYvG,GAC/C,GAAIwG,EAAY,OAAOA,CACxB,CACF,CAEJ,CACF,CAUD,gCAAaC,CAAoBf,EAAQ7M,EAAO,IAC9C,MAAMoN,EAA0B,iBAATpN,EAAoBA,EAAOA,GAAMoN,OACxD,IAAKA,EAAQ,OAEb,MAAMjG,EAAQiG,EAAOlB,MAAM,WACrB2B,mBAAmBhB,EAAQ1F,EAClC,CASD,+BAAa0G,CAAmBhB,EAAQ1F,GACtC0F,EAAUzB,MAAM6B,QAAQJ,GAAWA,EAASrC,OAAOG,OAAOkC,GAC1D,IAAK,MAAOiB,EAAOjW,KAAUgV,EAAO3D,UAClC,GAAIrR,EAAM8K,KAAOwE,EAAM,GAAI,CACzB,GAAqB,IAAjBA,EAAMW,OAER,YADA+E,EAAOkB,OAAOD,EAAO,GAGvB,GAA4B,IAAxBjW,EAAMgV,OAAO/E,OAAc,OAC/BX,EAAMqE,QACN,MAAMmC,QAAmBE,mBAAmBhW,EAAMgV,OAAQ1F,GAC1D,GAAIwG,EAAY,MACjB,CAEJ,CAUD,6BAAaK,CAAiBnB,EAAQ7M,EAAO,IAC3C,MAAM2C,EAAsB,iBAAT3C,EAAoBA,EAAOA,GAAM2C,GACpD,GAAKA,EAEL,IAAK,IAAIgG,EAAIkE,EAAO/E,OAAS,EAAGa,GAAK,EAAGA,IAClCkE,EAAOlE,GAAGhG,KAAOA,EACnBkK,EAAOkB,OAAOpF,EAAG,GACRkE,EAAOlE,GAAGkE,QAAQ/E,OAAS,GACpCkG,iBAAiBnB,EAAOlE,GAAGkE,OAAQ7M,EAGxC,ECjyBH,MAAMiO,EAAahM,SAASiM,cAAcC,MAAMC,YAAYC,gBAAkBD,WAKvE,MAAME,YACX,WAAA5N,CAAY6N,GACV3N,KAAK2N,OAASA,CACf,CASD,UAAMC,SACE5N,MAAK6N,UACLzN,QAAQ0N,IAAI,CAChB9N,KAAK+N,cAAgB/N,KAAKgO,YAC1BhO,KAAKiO,cAAgBjO,KAAKkO,oBAE7B,CAQD,uBAAIC,GACF,OAAQ9M,QAAQC,MAAMwH,eAAexJ,KAAKsG,QAAS,WAAiC,oBAAbwI,QACxE,CAQD,OAAMP,GACJ,IAAKvO,KAAK0E,KAAKoB,OAAS3F,MAAMC,WAAW,uBAAwB,OAEjE,MAAM2O,EAAc,OACdC,EAAmBtO,KAAwB,oBAC7C,WAAWvJ,EAAOC,aAClBD,EAAOC,GAEL6X,EAAsB,CAC1BD,EACA,GAAGA,KAAmBhP,KAAKkP,MAAMzM,KACjC,GAAGuM,KAAmBhP,KAAKkP,MAAMzM,WACjC,GAAGuM,KAAmBhP,KAAKkP,MAAMzM,WAGnC,IAAK,MAAM0M,KAAaF,QAChBlB,EAAWqB,OAAOL,EAAaI,GAAWE,OAAM9B,gBACxCQ,EAAWuB,gBAAgBP,EAAaI,EAAW,CAAE,IAC/D/P,EAAOnB,MAAM,+BAA+BkR,IAC7C,GAGN,CAUD,QAAII,GACF,OAAQ7O,KAAwB,oBAC5B,WAAWvJ,EAAOC,cAAc4I,KAAKkP,MAAMzM,MAC3C,GAAGtL,EAAOC,MAAM4I,KAAKkP,MAAMzM,KAChC,CASD,YAAA+M,CAAa3W,GACX,MAAMoO,EAAQpO,EAAKmT,MAAM,KACnByD,EAAWxI,EAAMmE,MACjBsE,EAASzI,EAAMK,KAAK,KACpB7E,EAAKgN,EAASzD,MAAM,KAAK,GAC/B,MAAO,CAAE0D,SAAQD,WAAUhN,KAC5B,CAQD,eAAMiM,GACJ,GAAI1O,KAAK0E,KAAKoB,KAAM,OAAO,EAE3B,GAAI9F,KAAK0E,KAAKiL,cAAc,gBAC1B,IAEE,aADM5B,EAAWqB,OAAO,OAAQ1O,KAAK6O,OAC9B,CACf,CAAQ,MACA,OAAO,CACR,CAEH,OAAO,CACR,CAQD,sBAAMX,GACJ,KAAM5O,KAAK0E,KAAKiL,cAAc,iBAAmBjP,KAAK+N,WAAatO,MAAMwF,aAEvE,OADAvG,EAAOC,KAAK,8CAA8C,GACnD,IAAI0J,IAGb,MAAM6G,EAAQ5P,KAAK0E,KAAKiL,cAAc,kBAAoBjP,KAAK+N,cACrD/N,KAAKmP,qBACLnP,KAAK2N,OAAOyB,YAAY,gBAElC,OAAO,IAAI/G,IAAI6G,EAAMzM,KAAItK,IACvB,MAAM4J,GAAEA,GAAO/B,KAAK8O,aAAa3W,GACjC,MAAO,CAAC4J,EAAI5J,EAAK,IAEpB,CAMD,mCAAakX,GACX,aAAa/P,KAAKC,gBAAgB+P,aAAaH,iBAAkB,EAClE,CAQD,kBAAMA,GACJ,MAAOI,EAAYC,SAAmBpP,QAAQ0N,IAAI,CAChDT,EAAWqB,OAAO,OAAQ,GAAG1O,KAAK6O,cAClCxB,EAAWqB,OAAO,OAAQ,GAAG1O,KAAK6O,eAGpC,MAAO,IAAKU,GAAYL,OAAS,MAASM,GAAWN,OAAS,GAC/D,CAUD,eAAIO,GACF,OAASnQ,KAAK0E,KAAKiL,cAAc,kBAAoBjP,KAAK+N,SAAYtO,MAAMwF,YAC7E,CAWD,kBAAMyK,CAAalW,EAAMuI,EAAI3C,GACvBE,KAAK0E,KAAKiL,cAAc,kBAAoBjP,KAAK+N,eAC7C/N,KAAK2P,SAASnW,EAAMuI,EAAI3C,GAG3BK,MAAMwF,mBAKLjF,KAAK2N,OAAOyB,YAAY,WAAY5V,EAAMuI,EAAI3C,GAJlDV,EAAOC,KAAK,yCAAyC,EAKxD,CAID,+BAAaiR,CAAmBpW,EAAMuI,EAAI3C,GACxC,aAAaE,KAAKC,eAAe+P,YAAYK,SAASnW,EAAMuI,EAAI3C,EACjE,CAUD,cAAMuQ,CAASnW,EAAMuI,EAAI3C,GACvB,IAEE,MAAM4P,EAAS,GAAGhP,KAAK6O,OAAOrV,IAGxBqW,EAAWC,UAAU,GAAG/N,UAGxB5J,EAAO,IAAI4X,KAAK,CAACC,KAAKC,UAAU7Q,EAAM,KAAM,KAAMyQ,EAAU,CAAErW,KAAM,qBAGpE0W,QAAiB7C,EAAW8C,OAAO,OAAQnB,EAAQ7W,EAAM,GAAI,CAAE0G,QAAQ,IAEzEqR,EAASrB,KACN7O,KAAKiO,QAAQ3E,IAAIvH,IACpB/B,KAAKiO,QAAQ7J,IAAIrC,EAAImO,EAASrB,MAGhCnQ,EAAOnB,MAAM,2BAA2BsS,cAAqBK,EAAShR,OAAS,kBAElF,CAAC,MAAMA,GACNR,EAAOQ,MAAM,2CAA2C6C,WAAY7C,EAAMN,UAC3E,CACF,CAUD,cAAIwR,GACF,OAAS9Q,KAAK0E,KAAKiL,cAAc,kBAAoBjP,KAAK+N,SAAYtO,MAAMwF,YAC7E,CAUD,iBAAMoL,CAAYjP,GAChB,IACE,KAAM9B,KAAK0E,KAAKiL,cAAc,iBAAmBjP,KAAK+N,WAAatO,MAAMwF,aAEvE,YADAvG,EAAOC,KAAK,wCAAwC,GAItD,MAAMS,EAAQE,KAAK0E,KAAKiL,cAAc,sBAC5BjP,KAAKsQ,QAAQlP,SACbpB,KAAK2N,OAAOyB,YAAY,UAAWhO,GAE7C,OAAOhC,CACR,CAAC,MAAMF,GAEN,OADAR,EAAOQ,MAAM,yCAAyCA,EAAMN,WACrD,IACR,CACF,CAID,8BAAa2R,CAAkBnP,GAC7B,aAAa9B,KAAKC,eAAe+P,YAAYgB,QAAQlP,EACtD,CASD,aAAMkP,CAAQlP,GACZ,MAAMW,GAAEA,EAAE5J,KAAEA,GAASiJ,EAGrB,IAAIoP,EAAYxQ,KAAKiO,QAAQ/L,IAAIH,IAAO,KAGxC,IAAKyO,EAAW,CACd,IAAKrY,EAAM,OAAO,KAClB,MAAM6W,OAAEA,EAAMD,SAAEA,GAAa/O,KAAK8O,aAAa3W,GACzCsY,QAAoBpD,EAAWqB,OAAO,OAAQM,GAEpD,GADAwB,EAAYC,EAAYvB,MAAMpN,MAAK3J,GAAQA,EAAKuY,SAAS3B,MACpDyB,EAAW,OAAO,IACxB,CAED,IACE,MAAMG,EAAKC,KAAKC,MACVX,QAAiBY,MAAM,GAAGN,QAAgBG,KAGhD,IAAKT,EAASa,GAAI,OAAO,KAEzB,MAAMjQ,QAAaoP,EAASpP,OAC5B,OAAKA,EACEkP,KAAKgB,MAAMlQ,GADA,IAEnB,CAAC,MAAM5B,GAEN,OADAF,QAAQE,MAAMA,GACP,IACR,CACF,CAUD,oBAAM+R,CAAezX,EAAMuI,GACzB,MAAMmP,EAAa,GAAGza,EAAOC,MAAM4I,KAAKkP,MAAMzM,MAAMvI,IAC9CqW,EAAWC,UAAU,GAAG/N,UAC9B,IACE,MAAMoP,QAAwB9D,EAAWqB,OAAO,OAAQwC,GAClDE,EAAgBD,EAAgBjC,MAAMpN,MAAK3J,GAAQA,EAAKuY,SAASb,KACvE,GAAIuB,EAAe,CACjB,MAAMT,EAAKC,KAAKC,MAChB,aAAaC,MAAM,GAAGM,QAAoBT,KACvCU,MAAKnB,GACAA,EAASa,GACJb,EAASoB,OAET,OAGV3C,OAAMzP,IACLF,QAAQE,MAAMA,EAAM,GAEhC,CACQ,OAAO,IAEf,CAAM,MACA,OAAO,IACR,CACF,EC3VI,MAAMqS,iBACX,WAAAzR,CAAYwP,EAAa3B,GACvB3N,KAAKsP,YAAcA,EACnBtP,KAAK2N,OAASA,CACf,CAQD,UAAMC,GACJ,IAAKtO,KAAK0E,KAAKoB,KAAM,OAErB,MAAM+F,EAAgB7L,KAAKkG,QAAQtD,IAAIzL,EAAOC,IAAIkP,QAC5C5H,EAAmByB,MAAMC,WAAW,oBAC1C,GAAIyL,IAAkBnN,EAAkB,OAExC,IAAIwT,GAAY,EAChBA,KAAcxT,GAAoBqD,QAAQC,MAAMwH,eAAe,SAAU9K,WAC/DgC,MAAKyR,IAEfD,IAAaxR,KAAKsP,YAAYnB,uBAAyBnQ,GAAoBqD,QAAQC,MAAMwH,eAAe,SAAU9K,YACxGgC,MAAK0R,IAGXF,GACF/R,MAAM0E,WAAW,mBAAoBgH,EAExC,CASD,OAAMsG,GACJ,IACE,MAAMvM,EAAQ5F,KAAK4F,MAAMkE,QAAOpF,GAAQA,EAAKM,QAAQ7N,EAAOC,GAAI,gBAChE,IAAK,MAAMsN,KAAQkB,EACjBlB,EAAKU,UAAUjO,EAAOC,GAAI,cAC1BsN,EAAKU,UAAUjO,EAAOC,GAAI,YAG5B,MAAMuL,EAAS3C,KAAK2C,OAAOmH,QAAOpH,GAASA,EAAMsC,QAAQ7N,EAAOC,GAAI,gBACpE,IAAK,MAAMsL,KAASC,EAClBD,EAAM0C,UAAUjO,EAAOC,GAAI,cAG7B,MAAMkL,EAAStC,KAAKqC,OAAOC,OAAO+P,QAAQC,SAASxI,QAAO1H,GAASA,EAAMM,OAAOsC,QAAQ7N,EAAOC,GAAI,gBACnG,IAAK,MAAMgL,KAASE,EAClBF,EAAMM,OAAO0C,UAAUjO,EAAOC,GAAI,cAGpC,IAAK,MAAMmb,KAASvS,KAAKwS,OAAQ,CAC/B,MAAMlQ,EAASiQ,EAAMjQ,OAAOwH,QAAO1H,GAASA,EAAMM,OAAOsC,QAAQ7N,EAAOC,GAAI,gBAC5E,IAAK,MAAMgL,KAASE,EAClBF,EAAMM,OAAO0C,UAAUjO,EAAOC,GAAI,aAErC,CAED,OAAO,CACR,CAAC,MAAMqb,GAGN,OAFArT,EAAOnB,MAAMwU,EAAInT,QAASmT,IAEnB,CACR,CACF,CAQD,OAAML,GACJ,IACEhT,EAAOC,KAAK,4CAA4C,GACxD,IAAK,MAAMqF,KAAQ1E,KAAK4F,MAAO,CAC7B,MAAM9F,QAAaY,KAAKsP,YAAY2B,eAAe,OAAQjN,EAAKjC,IAC5D3C,SACIY,KAAKsP,YAAYK,SAAS,OAAQ3L,EAAKjC,GAAI3C,EAEpD,CAED,IAAK,MAAM4C,KAAS1C,KAAK2C,OAAQ,CAC/B,MAAM7C,QAAaY,KAAKsP,YAAY2B,eAAe,QAASjP,EAAMD,IAC9D3C,SACIY,KAAKsP,YAAYK,SAAS,QAAS3N,EAAMD,GAAI3C,EAEtD,CAED,OADAV,EAAOC,KAAK,qDAAqD,IAC1D,CACb,CAAM,MAEA,OADAD,EAAOC,KAAK,iDAAiD,IACtD,CACR,CACF,ECxGI,MAAMqT,iBACX,WAAAlS,CAAYmS,GACVjS,KAAKiS,WAAaA,EAClBjS,KAAKkS,aAAeD,EAAWC,aAC/BlS,KAAKmS,cAAgBF,EAAWE,cAChCnS,KAAK7B,YAAc8T,EAAW9T,WAC/B,CAKD,IAAAyP,GACE5N,KAAKoS,gBAAkBpS,KAAKgC,OAAOD,GACnC/B,KAAKqS,cACN,CAQD,eAAIC,GACF,OAAOtS,KAAKgC,OAAShC,KAAKuS,gBAC3B,CAQD,oBAAIA,GACF,MAAMC,EAAmB/S,MAAMmE,sBAC/B,OAAO4O,EAAiBtL,OAAS,IAAMlH,KAAKgC,KAC7C,CAQD,eAAIyQ,GACF,OAAOzS,KAAKoS,kBAAoBpS,KAAKgC,OAAOD,EAC7C,CAQD,YAAAsQ,GACErS,KAAK0S,iBACL,MAAMF,EAAmB/S,MAAMmE,sBAC3B4O,EAAiBtL,OAAS,EAC5BlH,MAAK2S,EAAsBH,GAE3BxS,MAAK4S,EAAmBJ,EAE3B,CAOD,cAAAE,GACE1S,KAAK0B,MAAQ,KACb1B,KAAKgC,MAAQ,KACbhC,KAAK4B,OAAS,GACd5B,KAAKiC,OAAS,EACf,CAQD,EAAA0Q,CAAsBH,GACpBxS,KAAK6S,cAAgBvT,KAAKwF,KAAKE,SAAS,2BAGxChF,KAAK0B,MAAQ,KACb1B,KAAKgC,MAAQ,KAGbhC,KAAK4B,OAAS4Q,EACdxS,KAAKiC,OAASxC,MAAM8C,qBACrB,CASD,EAAAqQ,CAAmBJ,GACjB,MAAMzO,EAAY,CAAErC,MAAO,KAAMM,MAAO,MAER,IAA5BwQ,EAAiBtL,QAAgBlH,MAAK8S,EAAkBN,EAAiB,KAC3EzO,EAAUrC,MAAQ8Q,EAAiB,GACnCzO,EAAU/B,MAAQ+B,EAAUrC,OAAOM,OACE,IAA5BwQ,EAAiBtL,QAAgB5H,KAAK0E,KAAKD,WAAatE,MAAMC,WAAW,mBAClFqE,EAAU/B,MAAQ1C,KAAK0E,KAAKD,UAC5BA,EAAUrC,MAAQC,OAAOC,QAAQC,WAAWC,MAAKiR,GAAKA,EAAE/Q,OAAOD,KAAOgC,EAAU/B,MAAMD,MAAO,MAG1FgC,EAAU/B,QAEfhC,KAAK6S,cAAgB9O,EAAUrC,OAAOrJ,MAAQ0L,EAAU/B,MAAM3J,KAG9D2H,KAAK0B,MAAQqC,EAAUrC,MACvB1B,KAAKgC,MAAQ+B,EAAU/B,MACvBhC,KAAK4B,OAAS,CAACmC,EAAUrC,OACzB1B,KAAKiC,OAAS,CAAC8B,EAAU/B,OAC1B,CAUD,EAAA8Q,CAAkBpR,EAAQ,IACxB,OAAOpC,KAAK0E,KAAKoB,MAAQ1D,EAAMM,OAAOgR,mBAAmB1T,KAAK0E,KAAM,QACrE,ECjII,MAAMiP,cACX,WAAAnT,CAAYoT,EAAe5D,GACzBtP,KAAKkT,cAAgBA,EACrBlT,KAAKsP,YAAcA,EACnBtP,KAAKmT,cAAgB,KACrBnT,KAAK7D,aAAe,IACrB,CASD,UAAMyR,SACExN,QAAQ0N,IAAI,CAChB9N,MAAKoT,IACLpT,MAAKqT,KAER,CAQD,OAAMD,GACJ,GAAIpT,KAAKmT,cAAe,OACxB,MAAMA,EAAgBnT,KAAKkT,cAAcI,UAAUC,OAEnDvT,KAAKmT,cADAA,QACsB1T,MAAMuM,gBAAgBmH,GADN,IAE5C,CAQD,OAAME,GACJ,GAAIrT,KAAK7D,aAAc,OACvB,MAAMhE,EAAOsH,MAAMkF,YAAY,qBAAuBlF,MAAMC,WAAW,iBAAmB,KAC1FM,KAAK7D,aAAe,QAAe6D,KAAKsP,YAAYe,YAAY,CAAElY,SAAU,IAC7E,CASD,SAAAqb,GACExT,KAAKmT,cAAgB,IACtB,CAOD,SAAAM,GACEzT,KAAKwT,YACLxT,KAAK7D,aAAe,IACrB,CAUD,kBAAMO,GACJ,MAAM0C,QAAaY,KAAKsP,YAAYe,YAAY,CAAE7W,KAAM,OAAQuI,GAAIzC,KAAKoU,UAAa1T,KAAK7D,cAAgB6D,KAAKmT,cAC5G/T,GACFuU,eAAe3D,KAAKC,UAAU7Q,EAAM,KAAM,GAAI,YAAa,+BAE9D,CAUD,UAAImU,GACF,OAAOvT,KAAK7D,cAAgB6D,KAAKmT,aAClC,EC1FI,SAASS,WAAWC,EAASxb,GAClC,MAAMmH,EAAUF,KAAKC,gBAAgBC,SAAShB,UAAYiB,MAAMC,WAAW,YAE3E,GAAgB,SAAZF,EAAoB,OAAO,KAC/B,GAAgB,aAAZA,IAA2BqU,EAAS,OAAOxb,EAExB,iBAAZwb,IACTA,EAAU,CAAEC,QAASD,IAGlBA,EAAQC,QAAQvQ,SAAS,yBAC5BsQ,EAAQC,QAAU,oCAAoCD,EAAQC,iBAGhE,IAAItW,EAAY,QAChB,GAAIqW,EAAQrW,UACVA,EAAYqW,EAAQrW,cACf,CACL,MAAMe,EAAQe,KAAKC,eAAe2T,cAAca,OAAOzU,KAAKC,eAAeC,QAAQjB,OAE/E,CAAC,eAAgB,SAASgF,SAAShF,EAAM3F,gBAC3C4E,EAAY,OAEf,CAID,OAFAqW,EAAQrW,UAAYA,EAEbqW,CACT,CC7BO,MAAMG,aACX,WAAAlU,CAAYmS,EAAYiB,EAAe5D,EAAa2E,GAClDjU,KAAKiS,WAAaA,EAClBjS,KAAKkT,cAAgBA,EACrBlT,KAAKsP,YAAcA,EACnBtP,KAAKiU,cAAgBA,EACrBjU,KAAKkU,cAAgB,GACrBlU,KAAKiM,OAAS,GACdjM,KAAKmU,YAAc,GACnBnU,KAAKoU,WAAa,EACnB,CAMD,SAAIpS,GACF,OAAOhC,KAAKiS,YAAYjQ,KACzB,CAED,UAAIC,GACF,OAAOjC,KAAKiS,YAAYhQ,MACzB,CAED,SAAIP,GACF,OAAO1B,KAAKiS,YAAYvQ,KACzB,CAED,UAAIE,GACF,OAAO5B,KAAKiS,YAAYrQ,MACzB,CASD,UAAMgM,GACJ5N,MAAKqU,UACCjU,QAAQ0N,IAAI,CAChB9N,MAAKsU,IACLtU,MAAKuU,KAER,CAQD,EAAAF,GACE,MAAMH,EAAgBlU,KAAKkT,cAAcI,UAAUrH,OACnD,GAAKiI,EACL,IAAK,MAAMM,KAAgBN,EACzBlU,KAAKkU,cAAcM,EAAazS,IAAMyS,CAEzC,CAQD,OAAMF,GACJ,IAAKtU,KAAKgC,MAAO,OAEjB,IAAKvC,MAAMC,WAAW,uBAEpB,YADAM,KAAKmU,YAAc,IAIrB,GAAInU,KAAKyS,aAAe7I,OAAOtB,QAAQtI,KAAKmU,aAAajN,OAAQ,OAEjE,IAAKlH,KAAKsP,YAAYc,WAEpB,YADApQ,KAAKmU,YAAc,IAIrBzV,EAAOnB,MAAM,kCAAmC,CAAEyE,MAAOhC,KAAKgC,QAC9DhC,KAAKmU,YAAc,GACnB,MAAMA,QAAoBnU,KAAKsP,YAAYe,YAAY,CAAE7W,KAAM,QAASuI,GAAI/B,KAAKgC,MAAMD,MAAS,KAChG,GAAKoS,EAAL,CACA,IAAK,MAAMld,KAAS2S,OAAOtB,QAAQ6L,GACjCld,EAAM,GAAGuV,OAASvV,EAAM,GAE1B+I,KAAKmU,YAAcA,EACnBzV,EAAOnB,MAAM,8BAA+B,CAAE4W,YAAanU,KAAKmU,YAAanS,MAAOhC,KAAKgC,OALhE,CAM1B,CAQD,OAAMuS,GACJ,MAAMvQ,EAAO1E,KAAK0E,KACZuP,EAASvT,KAAKiU,cAAcV,OAE5BkB,cAAgBrV,IACpB,MAAMgV,EAAaxK,OAAO8C,KAAKtN,GAAM8H,OAAS9H,EAAOmU,EACrD,IAAK,MAAMtc,KAAS2S,OAAOtB,QAAQ8L,GACjCnd,EAAM,GAAGuV,OAASvV,EAAM,GAE1B,OAAOmd,CAAU,EAGnB,IAAK3U,MAAMC,WAAW,uBAEpB,YADAM,KAAKoU,WAAaK,cAAclB,IAIlC,GAAI3J,OAAOtB,QAAQtI,KAAKoU,YAAYlN,OAAQ,OAE5C,IAAKlH,KAAKsP,YAAYc,WAEpB,YADApQ,KAAKoU,WAAaK,cAAclB,IAIlC7U,EAAOnB,MAAM,iCAAkC,CAAEyG,SACjDhE,KAAKoU,WAAa,GAClB,MAAMM,QAAsB1U,KAAKsP,YAAYe,YAAY,CAAE7W,KAAM,OAAQuI,GAAIiC,EAAKjC,MAAS,CAAA,EAC3F/B,KAAKoU,WAAaK,cAAcC,GAChChW,EAAOnB,MAAM,6BAA8B,CAAE6W,WAAYpU,KAAKoU,WAAYpQ,QAC3E,CAUD,SAAAwP,GACExT,KAAKkU,cAAgB,GACrBlU,KAAKiM,OAAS,KACdjM,KAAKiM,OAAS,EACf,CAOD,SAAAwH,GACEzT,KAAKwT,YACLxT,KAAKmU,YAAc,GACnBnU,KAAKoU,WAAa,EACnB,CAWD,mBAAMO,CAAczd,GAClB,MAAMyB,IAAaX,EAAUyH,MAAMC,WAAW,WAAW/G,SAEzD,GAAIiR,OAAO8C,KAAK1M,KAAKoU,YAAYlN,OAAQ,CACvC,MAAMkN,EAAapU,KAAKyU,gBACxB,IAAK,MAAMG,KAAaR,EACtB,GAAwB,IAApBQ,EAAUrI,MAAa,CACzB,MAAMtV,EAAQ+I,KAAK6U,YAAYD,IACR,IAAnB3d,EAAM6d,UAAoB5d,EAAI+U,OAAO7I,KAAKnM,GAC9C+I,KAAKiM,OAAOhV,EAAMuV,QAAUvV,CACtC,KAAe,CACL,MAAM8d,EAAeH,EAAUpI,OAAOlB,MAAM,IAAKsJ,EAAUrI,MAAQ,GAAG3F,KAAK,KACrEoO,QAAoBvV,MAAMkN,iBAAiBzV,EAAI+U,OAAQ,CAAEO,OAAQuI,IACvE,GAAIC,EAAa,CACf,MAAM/d,EAAQ+I,KAAK6U,YAAYD,IACR,IAAnB3d,EAAM6d,WACHnc,GAAqC,QAAzB1B,EAAMG,SAASmH,MAG9ByW,EAAY/I,OAAOgJ,MAAM7R,KAAKnM,GAF9B+d,EAAY/I,OAAOiJ,KAAK9R,KAAKnM,IAKjC+I,KAAKiM,OAAOhV,EAAMuV,QAAUvV,CAC7B,CACF,CAEJ,CAED,GAAI2S,OAAO8C,KAAK1M,KAAKmU,aAAajN,OAAQ,CACxC,MAAMiN,EAAcnU,KAAKmV,iBAEzB,IAAK,MAAMC,KAAcjB,EAAa,CACpC,MAAMY,EAAeK,EAAW5I,OAAOlB,MAAM,IAAK8J,EAAW7I,MAAQ,GAAG3F,KAAK,KACvEyO,QAAsB5V,MAAMkN,iBAAiBzV,EAAI+U,OAAQ,CAAEO,OAAQ4I,EAAW5I,SACpF,GAAI6I,EACED,EAAWE,SAASpO,SACtBmO,EAAcC,QAAUF,EAAWE,aAEhC,CACL,MAAMN,QAAoBvV,MAAMkN,iBAAiBzV,EAAI+U,OAAQ,CAAEO,OAAQuI,IAEvE,GAAIC,GAAmC,mBAApBI,EAAW5b,KAA2B,CAClDwb,EAAY/I,SAAQ+I,EAAY/I,OAAS,CAAEgJ,MAAO,GAAIC,KAAM,KAEjE,MAAMje,EAAQ+I,KAAK6U,YAAYO,GAAY,GAEvCA,EAAWE,SAASpO,SACtBjQ,EAAMqe,QAAUF,EAAWE,UAGN,IAAnBre,EAAM6d,WACHnc,GAAqC,QAAzB1B,EAAMG,SAASmH,MAG9ByW,EAAY/I,OAAOgJ,MAAM7R,KAAKnM,GAF9B+d,EAAY/I,OAAOiJ,KAAK9R,KAAKnM,IAMjC+I,KAAKiM,OAAOhV,EAAMuV,QAAUvV,CAC7B,CACF,CACF,CACF,CAED,OAAO+I,KAAKiM,MACb,CAgBD,QAAAsJ,EAAS/I,OAAEA,EAAMzK,GAAEA,EAAEwK,MAAEA,EAAK/S,KAAEA,GAAS,IACrC,OAAIgT,EAAexM,KAAKiM,OAAOO,GAExB5C,OAAOG,OAAO/J,KAAKiM,QAAQnK,MAAK7K,KACnC8K,GAAM9K,EAAM8K,KAAOA,GAChBwK,GAAStV,EAAMsV,QAAUA,GACzB/S,GAAQvC,EAAMuC,OAASA,IAE/B,CAeD,SAAAgc,EAAUhJ,OAAEA,EAAMzK,GAAEA,EAAEwK,MAAEA,EAAK/S,KAAEA,EAAIsb,SAAEA,GAAa,IAChD,OAAOlL,OAAOG,OAAO/J,KAAKiM,QAAQ7C,QAAOnS,KACrCuV,GAAUvV,EAAMuV,OAAOiJ,WAAWjJ,OAC/BzK,GAAM9K,EAAM8K,KAAOA,MACnBwK,GAAStV,EAAMsV,QAAUA,MACzB/S,GAAQvC,EAAMuC,OAASA,MACvBsb,GAAY7d,EAAM6d,WAAaA,IAEvC,CAcD,cAAAK,EAAe3I,OAAEA,EAAMzK,GAAEA,EAAEwK,MAAEA,EAAK/S,KAAEA,GAAS,IAC3C,OAAOoQ,OAAOG,OAAO/J,KAAKmU,aAAa/K,QAAOnS,KAC1CuV,GAAUvV,EAAMuV,OAAOiJ,WAAWjJ,OAC/BzK,GAAM9K,EAAM8K,KAAOA,MACnBwK,GAAStV,EAAMsV,QAAUA,MACzB/S,GAAQvC,EAAMuC,OAASA,KAC5B4N,MAAK,CAACC,EAAGC,IAAOD,EAAEkF,MAAQjF,EAAEiF,OAASlF,EAAE6E,MAAQ5E,EAAE4E,OACpD,CAcD,aAAAuI,EAAcjI,OAAEA,EAAMzK,GAAEA,EAAEwK,MAAEA,EAAK/S,KAAEA,GAAS,IAC1C,OAAOoQ,OAAOG,OAAO/J,KAAKoU,YAAYhL,QAAOnS,KACzCuV,GAAUvV,EAAMuV,OAAOiJ,WAAWjJ,OAC/BzK,GAAM9K,EAAM8K,KAAOA,MACnBwK,GAAStV,EAAMsV,QAAUA,MACzB/S,GAAQvC,EAAMuC,OAASA,KAC5B4N,MAAK,CAACC,EAAGC,IAAOD,EAAEkF,MAAQjF,EAAEiF,OAASlF,EAAE6E,MAAQ5E,EAAE4E,OACpD,CAQD,WAAAwJ,GACE,OAAO9L,OAAOG,OAAO/J,KAAKiM,QAAQxJ,KAAIxL,GAASA,EAAM8K,IACtD,CAUD,gBAAA4T,CAAiBC,EAAY,IAC3B,OAAO5V,KAAKuV,SAASK,IAAYxe,UAAY,IAC9C,CAaD,WAAAyd,CAAYe,EAAWC,GAAW,GAChC,MAAMC,EAAiBrW,MAAMG,UAAUgW,GACjCG,EAAcH,EAAUpJ,OAAOlB,MAAM,KACrCiB,EAAQwJ,EAAY7O,QAAU,EAE9B2M,EAAUD,WAAWgC,GAAW/B,QAASiC,GAAgBzd,MAE1Dwd,IACHC,EAAeR,QAAU,GACzBQ,EAAe7J,OAAS,CAAEgJ,MAAO,GAAIC,KAAM,KAG7C,MAAMc,EAAkB,CACtBC,WAAW,EACX1X,MAAkB,IAAVgO,EAAe,MAAQ,QAG3B2J,EAAgBJ,EAAe1e,UAAY,GACjD8e,EAAcD,YAAcD,EAAgBC,UAC5CC,EAAc3X,QAAUyX,EAAgBzX,MAExCuX,EAAeK,cAAiBD,EAAuB,UAAI,GAAK,aAEhE,MAAME,EAAcN,EAAeO,QAAU,GAEvCC,EAAc,CAClBhB,QAASQ,EAAeR,QACxBpd,MAAO4d,EAAe5d,OAAS4d,EAAeS,UAAY,GAC1DtK,OAAQ6J,EAAe7J,OACvBlK,GAAI+T,EAAe/T,GACnByU,MAAOV,EAAeU,OAAS,GAC/BC,MAAOX,EAAeW,OAAS,GAC/BC,MAAOZ,EAAeY,OAAS,GAC/BnK,MAAOuJ,EAAevJ,OAASA,GAAS,EACxCoK,SAAUb,EAAea,UAAYb,EAAezd,KACpDA,KAAMyd,EAAezd,KACrBmU,OAAQsJ,EAAetJ,QAAUsJ,EAAe/T,GAChDmK,MAAO4J,EAAe5J,MACtB4I,SAAUgB,EAAehB,UAAYgB,EAAec,YAAcd,EAAee,kBAAmB,EACpGzf,SAAU8e,EACVG,OAAQD,EACRvC,UACAra,KAAMsc,EAAetc,MAAQ2B,EAAWE,QAO1C,OAJIkR,EAAQ,IACV+J,EAAYH,cAAgBL,EAAeK,eAAiB,IAGvDG,CACR,CAUD,YAAAQ,CAAaC,EAAYC,GAClBxM,MAAM6B,QAAQ0K,KAAaA,EAAa,CAACA,IAE9C,MAAMxK,GAASyK,GAAiBzK,OAAS,GAAK,EACxC0K,EAAiB,CAAE1K,SACrByK,GAAiBxK,SAAQyK,EAAezK,OAASwK,EAAgBxK,QAErE,MAAM0K,EAAiBlX,KAAKwV,UAAUyB,GAGtC,IAAK,MAAM5B,KAAiB6B,EACC,mBAAvB7B,EAAc7b,MAChB6b,EAAcP,UAAW,EACzBO,EAAcnJ,MAAQ,KACZ6K,EAAWjV,MAAK8T,GAAaA,EAAU7T,KAAOsT,EAActT,aAC/D/B,KAAKiM,OAAOoJ,EAAc7I,QAKrC,IAAIN,EAAQ,EACZ,IAAK,MAAM0J,KAAamB,EAAY,CAClCnB,EAAUpJ,OAAUwK,GAAiBxK,OACjC,GAAGwK,EAAgBxK,UAAUoJ,EAAU7T,KACvC6T,EAAU7T,GACd6T,EAAUd,SAAWc,EAAUd,WAAY,EAC3Cc,EAAU1J,MAAQA,EAElB,MAAMmJ,EAAgBrV,KAAKuV,SAASK,GAEpC,GAAIP,EACFzL,OAAO6C,OAAO4I,EAAeO,OACxB,CACL,MAAM3e,EAAQ+I,KAAK6U,YAAYe,GAC/B5V,KAAKiM,OAAO2J,EAAUpJ,QAAUvV,CACjC,CACDiV,GACD,CAGD,GAAI8K,GAAiB5f,SAAU,CAC7B,MAAM+f,EAAsBnX,KAAKuV,SAASyB,GACtCG,IACFA,EAAoB/f,SAAW4f,EAAgB5f,SAElD,CACF,CAWD,iBAAAggB,CAAkBxB,GAChB,MAAM3e,EAAQ+I,KAAKuV,SAASK,GAC5B3e,EAAMG,SAAW,IAAKH,EAAMG,YAAawe,EAAUxe,UACnD4I,KAAKqX,WAAW,CAAEC,WAAW,EAAMC,UAAU,GAC9C,CASD,gBAAMF,CAAWjW,EAAU,CAAEkW,WAAW,EAAOC,UAAU,IAClD9X,MAAMC,WAAW,yBAEtBhB,EAAOnB,MAAM,oBAET6D,GAASkW,iBAAiBtX,KAAKwX,kBAC/BpW,GAASmW,gBAAgBvX,KAAKyX,iBAElC/Y,EAAOnB,MAAM,eAAgB,CAAE0O,OAAQjM,KAAKiM,SAC7C,CAQD,qBAAMuL,GACJ,IAAKxX,KAAKgC,QAAU4H,OAAO8C,KAAK1M,KAAKiM,QAAQ/E,OAAQ,OAErDxI,EAAOnB,MAAM,0BAEb,MAAM4W,EAAc,CAAA,EACpBnU,KAAKmU,YAAc,GAEnB,IAAK,MAAMld,KAAS2S,OAAOG,OAAO/J,KAAKiM,QACrCjM,KAAKmU,YAAYld,EAAMuV,QAAUvV,EACjCkd,EAAYld,EAAMuV,QAAUxM,MAAK0X,EAAqBzgB,GAAO,GAG3D+I,KAAKsP,YAAYG,mBACbzP,KAAKsP,YAAYI,aAAa,QAAS1P,KAAKgC,MAAMD,GAAIoS,GAE5DzV,EAAOnB,MAAM,qBAAsB,CAAE4W,iBAErCzV,EAAOnB,MAAM,0CAEhB,CAQD,oBAAMka,GACJ,IAAK7N,OAAO8C,KAAK1M,KAAKiM,QAAQ/E,OAAQ,OAEtCxI,EAAOnB,MAAM,yBAEb,MAAM6W,EAAa,CAAA,EACnBpU,KAAKoU,WAAa,GAElB,IAAK,MAAMnd,KAAS2S,OAAOG,OAAO/J,KAAKiM,QAClB,mBAAfhV,EAAMuC,OACRwG,KAAKoU,WAAWnd,EAAMuV,QAAUvV,EAChCmd,EAAWnd,EAAMuV,QAAUxM,MAAK0X,EAAqBzgB,GAAO,IAI5D+I,KAAKsP,YAAYG,mBACbzP,KAAKsP,YAAYI,aAAa,OAAQpQ,KAAKoU,OAAQU,GACzD1V,EAAOnB,MAAM,oBAAqB,CAAE6W,gBAEpC1V,EAAOnB,MAAM,yCAEhB,CAoBD,EAAAma,EAAqB3V,GAAEA,EAAE1J,KAAEA,EAAIse,SAAEA,EAAQpK,MAAEA,EAAKL,MAAEA,EAAK4I,SAAEA,EAAQ1d,SAAEA,EAAQoC,KAAEA,EAAI8b,QAAEA,GAAWqC,GAAc,GAC1G,MAAMvY,EAAO,CAAE2C,KAAI1J,OAAMse,WAAUpK,QAAOL,QAAO4I,WAAU1d,WAAUoC,QAMrE,OAJIme,IACFvY,EAAKkW,QAAUA,EAAQ7S,KAAI,EAAGV,KAAI6V,WAAUC,mBAA4B,CAAE9V,KAAI6V,WAAUC,oBAGnFzY,CACR,CAYD,wBAAM0Y,CAAmBlC,GACvB,MAAMmC,QAAsB/X,MAAKgY,EAAkBpC,GAC7CqC,QAAqBjY,MAAKkY,IAC1BC,QAAyBnY,MAAKoY,IAC9BC,QAAoBrY,MAAKsY,IAC/B,MAAO,IAAIP,KAAkBE,KAAiBE,KAAqBE,EACpE,CAWD,EAAAL,EAAkBxL,OAAEA,IAClB,MAAMuL,EAAgB/X,KAAKwV,UAAU,CAAEhJ,SAAQhT,KAAM2B,EAAWI,iBAChE,OAAOwc,GAAetV,KAAIxL,GAAS+I,MAAKuY,EAAUthB,MAAW,EAC9D,CASD,EAAAihB,GACE,OAAOtO,OAAOG,OAAO/J,KAAKkU,eAAezR,KAAIxL,GAAS+I,MAAKuY,EAAUthB,IACtE,CASD,EAAAmhB,GACE,MAAMI,EAAQlZ,KAAKkZ,MAAMpP,QAAOqP,GAC9B1gB,EAAsBwL,SAASkV,EAAKC,gBAC1BrX,QAAQC,MAAMwH,eAAexJ,KAAKsG,QAAS,MAAQ6S,EAAKE,SAAYF,EAAK1K,SAAWzO,KAAK0E,KAAKoB,QAEpG6G,EAASuM,EAAM/V,KAAIgW,IAChB,CACL1W,GAAI0W,EAAKG,SAAS7W,GAAGlB,QAAQ,IAAK,KAClC8V,SAAU,GAAGrX,KAAKwF,KAAKE,SAAS,4BAA4ByT,EAAKG,SAASjc,QAC1EtE,KAAMogB,EAAKG,SAASjc,MACpBnD,KAAM,WAGV,OAAOyS,EAAOxJ,KAAIxL,GAAS+I,MAAKuY,EAAUthB,IAC3C,CASD,EAAAqhB,GACE,MAAO,CAACtY,MAAKuY,EAAU,CACrBxW,GAAI,SACJ4U,SAAU,GAAGrX,KAAKwF,KAAKE,SAAS,4BAA4B1F,KAAKwF,KAAKE,SAAS,2BAC/E3M,KAAMiH,KAAKwF,KAAKE,SAAS,yBACzBxL,KAAM,SAET,CASD,EAAA+e,CAAU3C,GACR,MAAM7T,GAAEA,EAAE1J,KAAEA,EAAImB,KAAEA,EAAImd,SAAEA,GAAaf,EACrC,MAAO,CAAE7T,KAAI1J,OAAMse,SAAUA,GAAYte,EAAMmB,OAChD,CAaD,QAAAqf,CAASjD,EAAWoB,EAAiB8B,GAAS,GAI5C,GAHAlD,EAAUpc,KAAOoc,GAAWpc,MAAQ,iBACpCoc,EAAUrX,MAAQqX,GAAWrX,OAAS,QAEjCyY,GAAiBjV,KAAOiV,GAAiBxK,OAAQ,OAEtD,MAAMuM,EAAe/Y,KAAKwV,UAAUwB,GACpC,GAAK+B,GAAc7R,OAEnB,IAAK,MAAM8N,KAAe+D,EAAc,CACtC,MAAMvM,EAAS,GAAGwI,EAAYxI,UAAUoJ,EAAU7T,KAC5CmV,EAAiBlX,KAAKwV,UAAU,IAAKI,EAAWpJ,WAEtD,GAAI0K,EAAehQ,OACjB,GAAI4R,EACF,IAAK,MAAMzD,KAAiB6B,EAEtBtB,EAAUjX,OACZiL,OAAO6C,OAAOmJ,EAAW,IAAKA,EAAUjX,cACjCiX,EAAUjX,MAGnBiL,OAAO6C,OAAO4I,EAAerV,KAAK6U,YAAY,IAAKQ,KAAkBO,IAAa,SAGpF,IAAK,MAAMP,KAAiB6B,EAAgB,CAC1C,MAAMrD,EAAUD,WAAWgC,EAAU/B,QAASwB,EAAchd,MAC5DuR,OAAO6C,OAAO4I,EAAe,CAAExB,WAChC,KAEE,CACL,MAAM5c,EAAQ+I,KAAK6U,YAAY,IAAKe,EAAWpJ,WAI/C,GAFKwI,EAAY/I,SAAQ+I,EAAY/I,OAAS,CAAEgJ,MAAO,GAAIC,KAAM,MAE1C,IAAnBje,EAAM6d,SAAoB,CAC5B,MAAMnc,IAAaX,EAAUyH,MAAMC,WAAW,WAAW/G,SACpDA,GAAqC,QAAzB1B,EAAMG,SAASmH,MAG9ByW,EAAY/I,OAAOgJ,MAAM7R,KAAKnM,GAF9B+d,EAAY/I,OAAOiJ,KAAK9R,KAAKnM,EAIhC,CACD+I,KAAKiM,OAAOhV,EAAMuV,QAAUvV,CAC7B,CACF,CACF,CAUD,WAAA+hB,CAAYpD,EAAWoB,EAAkB,MACvCpB,EAAUpc,KAAOoc,GAAWpc,MAAQ,iBAEpC,MAAMyf,qBAAuB/B,IAC3B,IAAK,MAAM7B,KAAiB6B,EAEtBtB,EAAUjX,OACZiL,OAAO6C,OAAOmJ,EAAW,IAAKA,EAAUjX,cACjCiX,EAAUjX,MAGnBiL,OAAO6C,OAAO4I,EAAerV,KAAK6U,YAAY,IAAKQ,KAAkBO,IAAa,GACnF,EAGH,GAAIoB,EAAiB,CACnB,MAAM+B,EAAe/Y,KAAKwV,UAAUwB,GACpC,IAAK,MAAMhC,KAAe+D,EAAc,CACtC,MAAMvM,EAAS,GAAGwI,EAAYxI,UAAUoJ,EAAU7T,KAC5CmV,EAAiBlX,KAAKwV,UAAU,IAAKI,EAAWpJ,WAEtDyM,qBAAqB/B,EACtB,CACP,KAAW,CACL,MAAMA,EAAiBlX,KAAKwV,UAAUI,GAEtCqD,qBAAqB/B,EACtB,CACF,CASD,WAAAgC,CAAYtD,IACLA,GAAWpJ,QAAUoJ,GAAW7T,IACnCtC,MAAM2N,iBAAiBpN,KAAK9I,IAAI+U,OAAQ2J,EAAU7T,IAGpD,MAAMkK,EAASjM,KAAKwV,UAAUI,GAC9B,GAAK3J,GAAQ/E,OAEb,IAAK,MAAMjQ,KAASgV,SACXjM,KAAKiM,OAAOhV,EAAMuV,QACrBoJ,GAAWpJ,QACb/M,MAAMuN,oBAAoBhN,KAAK9I,IAAI+U,OAAQhV,EAAMuV,OAGtD,CASD,YAAA2M,CAAavD,GACX,MAAMzJ,EAAUyJ,GAAW7T,GACrBqX,EAAYxD,GAAWjX,KAE7B,IAAKwN,IAAYiN,EAAW,OAE5B,MAAMnN,EAASjM,KAAKwV,UAAUI,GAE9B3J,EAAOoN,SAAQpiB,IACbA,EAAMuf,MAAQ4C,EAAU5C,MACxBvf,EAAMwf,MAAQ2C,EAAU3C,MACxBxf,EAAMyf,MAAQ0C,EAAU1C,KAAK,GAEhC,CAQD,aAAA4C,GACE1P,OAAOG,OAAO/J,KAAKiM,QAAQoN,SAAQpiB,IAC7BA,EAAMqe,QAAQnQ,MAAKrO,GAAUA,EAAOge,WACtC7d,EAAMsiB,YAAa,EAEnBtiB,EAAMsiB,YAAa,CACpB,GAEJ,EC9zBI,MAAMC,WACX,WAAA1Z,CAAYP,EAAgB2T,EAAe5D,EAAa3B,GACtD3N,KAAKT,eAAiBA,EACtBS,KAAKsP,YAAcA,EACnBtP,KAAK2N,OAASA,EACd3N,KAAKiU,cAAgB,IAAIhB,cAAcC,EAAe5D,GACtDtP,KAAKkS,aAAe,IAAI8B,aAAahU,KAAMkT,EAAe5D,EAAatP,KAAKiU,eAC5EjU,KAAKmS,cAAgBe,EAAcuG,qBAAqBzZ,KAAMA,KAAKsP,YAAatP,KAAKkS,cACrFlS,KAAK7B,YAAc+U,EAAcwG,mBAAmB1Z,MACpDA,KAAK2Z,iBAAmB,IAAI3H,iBAAiBhS,KAC9C,CAWD,UAAM4N,CAAKxC,GAGT,GAFApL,KAAK2Z,iBAAiB/L,QAEhB5N,KAAK2Z,iBAAiBrH,cAAgBtS,KAAK4Z,aAAc,OAAO,EAEtE,MAAMxY,EAAuB,iBAAZgK,GAA8BpL,KAAK2Z,iBAAiBlH,YAAe,CAAE6E,WAAW,GAAS,CAAA,EAI1G,aAFMtX,MAAK6Z,EAAUzY,IAEd,CACR,CAUD,YAAA0Y,GACE9Z,KAAK9I,IAAM,KACX8I,KAAK9I,IAAM,GACX8I,KAAKkS,aAAasB,YAClBxT,KAAKiU,cAAcT,YACnBxT,KAAKmS,cAAcqB,WACpB,CAQD,YAAAuG,GACE/Z,KAAK8Z,eACL9Z,KAAKkS,aAAauB,YAClBzT,KAAKiU,cAAcR,WACpB,CAWD,OAAMoG,CAAUzY,GACd1C,EAAOnB,MAAM,kBAAmB,CAAEyE,MAAOhC,KAAKgC,MAAON,MAAO1B,KAAK0B,QAE7D1B,KAAKga,eAAejY,KAAO/B,KAAKgC,OAAOD,GACzC/B,KAAKyS,aAAc,GAEnBzS,KAAKga,cAAgBha,KAAKgC,MAC1BhC,KAAKyS,aAAc,GAGrBzS,KAAK8Z,qBAEC9Z,KAAKiU,cAAcrG,aACnB5N,KAAKkS,aAAatE,OAEnB5N,KAAKsP,YAAYc,YAAepQ,KAAKia,2BACxCvb,EAAOC,KAAK,iDAAiD,GAC7DqB,KAAKia,0BAA2B,GAGlCja,KAAK9I,UAAY8I,MAAKka,UAEhBla,KAAKmS,cAAcgI,mBACzBna,KAAKkS,aAAaoH,sBACZtZ,KAAKkS,aAAamF,WAAWjW,GAEnC1C,EAAOnB,MAAM,YAAa,CAAErG,IAAK8I,KAAK9I,IAAK8K,MAAOhC,KAAKgC,MAAON,MAAO1B,KAAK0B,OAC3E,CASD,OAAMwY,GACJxb,EAAOnB,MAAM,mBAAoB,CAAEyE,MAAOhC,KAAKgC,MAAON,MAAO1B,KAAK0B,QAElE,MAAMrJ,EAAQoH,MAAMC,WAAW,wBAC3BM,KAAK2Z,iBAAiB9G,eAAiBvT,KAAKwF,KAAKE,SAAS,2BAC1D,GACExD,EAAUxB,KAAKgC,OAAOD,IAAM,QAC5BN,EAAUzB,KAAK0B,OAAOK,IAAM,QAC5B7K,EAAM,CAAEmB,OAAMoJ,UAASD,UAASyK,OAAQ,IAExCA,QAAejM,KAAKkS,aAAayC,cAAczd,GAIrD,OAHA8I,KAAKmS,cAAciI,eAAenO,GAElCvN,EAAOnB,MAAM,eAAgB,CAAErG,MAAK8K,MAAOhC,KAAKgC,MAAON,MAAO1B,KAAK0B,QAC5DxK,CACR,CAWD,cAAAmjB,CAAeC,EAAWlY,GACxB,MAAMnL,EAAS,CAAC,cAAcsM,SAAS+W,GAActa,KAAKuV,SAASnT,GAAS,KACtEtL,EAAU,CAAC,cAAe,eAAeyM,SAAS+W,GAActa,KAAKua,UAAUnY,GAAS,KAE9FpC,MAAKwa,EAAepY,GACpBpC,MAAKya,EAAYrY,GAEjB,IACE,OAAQkY,GACN,IAAK,aACH,IAAuE,IAAnEI,MAAMC,KAAK,+BAAgCvY,EAAOnL,EAAO+I,MAAiB,OAC9EA,KAAK7B,YAAYyc,qBAAqBxY,EAAOnL,GAC7C,MACF,IAAK,cACH,IAAyE,IAArEyjB,MAAMC,KAAK,gCAAiCvY,EAAOtL,EAAQkJ,MAAiB,OAChFA,KAAK7B,YAAY0c,sBAAsBzY,EAAOtL,EAAQkJ,KAAKmS,eAC3D,MACF,IAAK,cACHnS,KAAK7B,YAAY2c,sBAAsB1Y,EAAOtL,GAEnD,CAAC,MAAMoI,GACNR,EAAOQ,MAAMkD,EACd,CACF,CAOD,EAAAoY,CAAepY,GACbpC,MAAK+a,EAAiB3Y,GACtBpC,MAAKgb,EAAU5Y,GACfpC,MAAKib,EAAW7Y,GAChBpC,MAAKkb,EAAY9Y,EAClB,CASD,EAAA2Y,CAAiB3Y,GACf,MAAM+Y,EAAS/Y,GAAOgZ,eAAeD,QAAU/Y,EAAM+Y,OACrDnb,KAAKqb,aAA0B,IAAXF,CACrB,CASD,EAAAH,CAAU5Y,GACR,MAAM0D,EAAkBzE,SAAS0E,SAASC,aAAaC,iBAAmBA,gBACpEqV,EAAkBhc,KAAKic,SAASC,iBAAiB1V,EAAgB2V,cAAcC,KACjFtZ,EAAMuZ,SAAWL,GACnB5c,EAAOnB,MAAM,gCACbuI,EAAgB8V,iBAAgB,EAAO,UAAW,CAAED,QAAQ,EAAME,OAAO,IACzEvc,KAAKic,SAASO,SAAStS,IAAI,WAC3BxJ,KAAK+b,OAAQ,GAEb/b,KAAK+b,MAAQT,CAEhB,CASD,EAAAL,CAAW7Y,GACT,MAAM0D,EAAkBzE,SAAS0E,SAASC,aAAaC,iBAAmBA,gBACpEqV,EAAkBhc,KAAKic,SAASC,iBAAiB1V,EAAgB2V,cAAcO,SACjF5Z,EAAM6Z,UAAYX,GACpB5c,EAAOnB,MAAM,iCACbuI,EAAgB8V,iBAAgB,EAAO,cAAe,CAAEK,SAAS,EAAMJ,OAAO,IAC9Evc,KAAKic,SAASO,SAAStS,IAAI,eAC3BxJ,KAAKkc,QAAS,GAEdlc,KAAKkc,OAASZ,CAEjB,CASD,EAAAJ,CAAY9Y,GACV,MAAM0D,EAAkBzE,SAAS0E,SAASC,aAAaC,iBAAmBA,gBACpEqV,EAAkBhc,KAAKic,SAASC,iBAAiB1V,EAAgB2V,cAAcU,OACjF/Z,EAAMga,WAAad,GACrB5c,EAAOnB,MAAM,kCACbuI,EAAgB8V,iBAAgB,EAAO,YAAa,CAAEQ,UAAU,EAAMP,OAAO,IAC7Evc,KAAKic,SAASO,SAAStS,IAAI,aAC3BxJ,KAAKqc,SAAU,GAEfrc,KAAKqc,QAAUf,CAElB,CASD,EAAAb,CAAYrY,GACVpC,KAAKsc,QAAU,CAAC,aAAc,YAAa,gBAAgB/Y,SAASnB,EAAM5I,KAC3E,CAWD,QAAA+b,CAASnT,GACP,MAAMma,EAAe9c,MAAM0C,uBAAuBC,GAC5CoK,EAAS+P,GAAcC,SAAShQ,OACtC,OAAOxM,KAAKkS,aAAaqD,SAAS,CAAE/I,YAAa,IAClD,CASD,SAAA+N,CAAUnY,GACR,IAAKA,EAAO,MAAO,GACnB,MAAMqa,EAAsBra,EAAMC,OAAOC,QAAQ,+BAC5CF,EAAMC,OAAOuG,cAAc,8BAC1B8T,EAAWD,GAAqBD,SAASE,SAC/C,OAAKA,GACE1c,KAAKmS,cAAcwK,iBAAiBza,IAAIwa,IADzB,EAEvB,CAWD,gBAAI9C,GACF,QAAKna,MAAMC,WAAW,cAClBJ,KAAK0E,KAAKoB,MACP3F,MAAMe,WAAWlB,KAAK0E,KAAK4Y,KAAMnd,MAAMC,WAAW,UAC1D,CAMD,iBAAImT,GACF,OAAO7S,KAAK2Z,kBAAkB9G,aAC/B,CAED,SAAI7Q,GACF,OAAOhC,KAAK2Z,kBAAkB3X,KAC/B,CAED,SAAIA,CAAMA,GACRhC,KAAK2Z,iBAAiB3X,MAAQA,CAC/B,CAED,UAAIC,GACF,OAAOjC,KAAK2Z,kBAAkB1X,MAC/B,CAED,UAAIA,CAAOA,GACTjC,KAAK2Z,iBAAiB1X,OAASA,CAChC,CAED,SAAIP,GACF,OAAO1B,KAAK2Z,kBAAkBjY,KAC/B,CAED,SAAIA,CAAMA,GACR1B,KAAK2Z,iBAAiBjY,MAAQA,CAC/B,CAED,UAAIE,GACF,OAAO5B,KAAK2Z,kBAAkB/X,MAC/B,CAED,UAAIA,CAAOA,GACT5B,KAAK2Z,iBAAiB/X,OAASA,CAChC,EChVIiL,eAAegQ,0BACdxb,QAAQiM,aAAawP,IAAIC,SAASC,QAAQ,CAC9CC,OAAQ,CACNvX,MAAOpG,KAAKwF,KAAKE,SAAS,4CAE5B8O,QAAS,MAAMxU,KAAKwF,KAAKE,SAAS,mDAClCkY,OAAO,EACPC,IAAK,CACHxgB,MAAO2C,KAAKwF,KAAKE,SAAS,oCAC1BoY,SAAUvQ,SAAYhQ,eAExBwgB,GAAI,CACF1gB,MAAO2C,KAAKwF,KAAKE,SAAS,qCAGhC,CAOA6H,eAAehQ,cACb,IAAKyC,MAAMC,eAAgB,OAE3B,MAAM+d,EAAsB3U,SAASC,cAAc,4DAC/C0U,UACIhe,KAAKC,eAAege,qBAAqB,eAAgBD,GAAqB1c,OAAS,UACvFnB,MAAM0E,WAAW,eAAgBmZ,GAAqB1c,OAAS,KAGvE,MAAM4c,EAA0B7U,SAASC,cAAc,gEACnD4U,UACIle,KAAKC,eAAege,qBAAqB,mBAAoBC,GAAyB5c,OAAS,UAC/FnB,MAAMmF,YAAY,mBAAoB4Y,GAAyB5c,OAAS,WAG1EtB,KAAKC,eAAe1C,cAC1B6B,EAAOC,KAAK,gBAAgB,EAC9B,CC1CA,MAAM8e,cAAEA,EAAaC,2BAAEA,GAA+Brc,QAAQiM,aAAawP,IAKpE,MAAMa,gBAAgBD,EAA2BD,IACtD,WAAA3d,CAAYV,GACVwe,MAAMxe,GACNY,KAAK8T,QAAU1U,EAAK0U,QACpB9T,KAAK6d,OAASze,EAAKye,OACnB7d,KAAKoB,QAAQ6b,OAAOvX,MAAQtG,EAAKsG,KAClC,CAIDoY,uBAAyB,CACvBxI,QAAS,CACPyI,aAAcJ,QAAQI,aACtBlhB,YAAa8gB,QAAQ9gB,aAEvBI,QAAS,CAAC,GAAGxG,EAAOC,SAAU,aAAc,SAC5CqL,GAAI,0BACJic,KAAM,CACJC,eAAe,EACfC,QAASP,QAAQE,QAEnBM,SAAU,CACRC,MAAO,IACPC,OAAQ,QAEVC,IAAK,OACLrB,OAAQ,CACNsB,aAAa,EACbC,WAAW,IAMf,qBAAMC,GACJ,OAAOze,KAAK8T,OACb,CAQD,yBAAaiK,SACL1c,QAAQiM,aAAawP,IAAIC,SAASC,QAAQ,CAC9CC,OAAQ,CACNvX,MAAOpG,KAAKwF,KAAKE,SAAS,6CAE5B8O,QAAS,MAAMxU,KAAKwF,KAAKE,SAAS,oDAClCkY,OAAO,EACPC,IAAK,CACHxgB,MAAO2C,KAAKwF,KAAKE,SAAS,oCAC1BoY,SAAUvQ,gBACFvN,KAAKC,eAAemf,gBAAgB,GAG9CrB,GAAI,CACF1gB,MAAO2C,KAAKwF,KAAKE,SAAS,qCAG/B,CASD,wBAAanI,SACLggB,mBACP,CAUD,mBAAagB,CAAOzb,EAAO4b,EAAMW,SACzB3e,KAAK6d,OAAOc,EAASC,OAC5B,EAKI,MAAMC,mBAAmBlB,QAC9BG,uBAAyB,CACvBb,OAAQ,CAAErgB,KAAM,8BAGlBkhB,aAAe,CACbE,KAAM,CACJc,SAAUjoB,EAASS,UAOlB,MAAMynB,qBAAqBpB,QAChCG,uBAAyB,CACvBb,OAAQ,CAAErgB,KAAM,4BAGlBkhB,aAAe,CACbE,KAAM,CACJc,SAAUjoB,EAASU,YAOlB,MAAMynB,wBAAwBrB,QACnCG,uBAAyB,CACvBb,OAAQ,CAAErgB,KAAM,qBAGlBkhB,aAAe,CACbE,KAAM,CACJc,SAAUjoB,EAASW,eC7HlB,MAAMynB,cAMX,2BAAaC,CAAehN,GAC1B,MAAMpU,QAAa2B,MAAMC,WAAW,QAE9Byf,EAAa,CACjBzZ,MAAOpG,KAAKwF,KAAKE,SAAS,oCAC1B8O,QAAS,CAAE1c,SAAU,CAAE0G,SACvB+f,OAAQhR,gBACApN,MAAM0E,WAAW,OAAQwa,GAAU7gB,MACzC4c,MAAM0E,QAAQ,4BAA4B,GAI9C,IAAIP,WAAWM,GAAYE,QAAO,EACnC,CAUD,6BAAaC,CAAiBpN,EAAc0D,GAC1C,MAAMpJ,OAAEA,EAAMnU,KAAEA,GAASud,EACnB2J,QAAwBrN,EAAayD,iBAAiBC,IAAc,CAAA,EAEpEuJ,EAAa,CACjBzZ,MAAO,GAAGpG,KAAKwF,KAAKE,SAAS,0CAA0C3M,IACvEyb,QAAS,CACP1c,SAAU,IAAKmoB,EAAiBlnB,SAElCwlB,OAAQhR,UACN,MAAM5V,EAAQib,EAAaqD,SAAS,CAAE/I,WACtC,IAAKvV,EAAO,OACZ,MAAMuoB,GAAWb,GAAUtmB,MAAQ,IAAIonB,OACnCD,IACFvoB,EAAMoB,KAAOmnB,EACbvoB,EAAM0f,SAAW6I,GAEnBvoB,EAAMG,SAAW,IACZH,EAAMG,SACTsoB,eAAgBf,GAAUe,eAC1BC,YAAahB,GAAUgB,YACvB7hB,KAAM6gB,GAAU7gB,KAChB8hB,MAAOjB,GAAUiB,MACjB3J,UAAW0I,GAAU1I,UACrB7O,KAAMuX,GAAUvX,YAEZ8K,EAAamF,WAAW,CAAEC,WAAW,EAAMC,UAAU,IAC3DmD,MAAM0E,QAAQ,4BAA4B,GAI9C,IAAIL,aAAaI,GAAYE,QAAO,EACrC,CAUD,4BAAaQ,CAAgB3N,EAAciM,GACzC,MAAMgB,EAAa,CACjBzZ,MAAOpG,KAAKwF,KAAKE,SAAS,sCAC1B8O,QAAS,CACP1c,SAAU,CACRiB,KAAM,GACN4d,WAAW,EACX2J,MAAO,GACPD,YAAa,KACb7hB,MAAM,EACN4hB,eAAgB,OAGpB7B,OAAQhR,UACN,MAAMxU,GAAQsmB,GAAUtmB,MAAQ,IAAIonB,OACpC,IAAKpnB,EAAM,OAEX,MAAMynB,EAASznB,EAAK0nB,QAAQ,CAAEC,YAAa,IAAKC,QAAQ,KAAW,QAC7DC,EAAc,IAAIhX,IACtBU,OAAOG,OAAOmI,EAAajG,QACxB7C,QAAO+W,GAAiB,IAAZA,EAAE5T,QACd9J,KAAI0d,GAAKA,EAAEpe,MAEhB,IAAIA,EAAK+d,EACLM,EAAS,EACb,KAAOF,EAAY5W,IAAIvH,IAAKA,EAAK,GAAG+d,KAAUM,MAE9C,MAAMtL,EAAWlL,OAAOG,OAAOmI,EAAajG,QACzC7C,QAAO+W,GAAiB,IAAZA,EAAE5T,OAAe4T,EAAErL,WAC/B1N,MAAK,CAACC,EAAGC,IAAMD,EAAE6E,MAAQ5E,EAAE4E,QAC3BzJ,KAAI0d,IAAC,CAAOpe,GAAIoe,EAAEpe,GAAI4U,SAAUwJ,EAAExJ,SAAUte,KAAM8nB,EAAE9nB,KAAMmB,KAAM2mB,EAAE3mB,SAC/D6mB,EAAW,CAAEte,KAAI4U,SAAUte,EAAMA,OAAMmB,KAAM,UAC7C8mB,EAAWtZ,KAAKuZ,IAAI,EAAGvZ,KAAKwZ,IAAIrC,EAAUrJ,EAAS5N,SACzD4N,EAAS3H,OAAOmT,EAAU,EAAGD,SAEvBnO,EAAa4E,aAAahC,EAAU,CAAEvI,MAAO,IAEnD,MAAMkU,EAAevO,EAAaqD,SAAS,CAAE/I,OAAQzK,IACjD0e,IACFA,EAAarpB,SAAW,CACtBsoB,eAAgBf,GAAUe,eAC1BC,YAAahB,GAAUgB,YACvB7hB,KAAM6gB,GAAU7gB,KAChB8hB,MAAOjB,GAAUiB,MACjB3J,UAAW0I,GAAU1I,kBAInB/D,EAAamF,WAAW,CAAEC,WAAW,EAAMC,UAAU,IAC3DmD,MAAM0E,QAAQ,4BAA4B,GAI9C,IAAIL,aAAaI,GAAYE,QAAO,EACrC,CAWD,gCAAaqB,CAAoBxO,EAAcC,EAAeyD,GAC5D,MAAMpJ,OAAEA,EAAMnU,KAAEA,GAASud,EACnB2J,QAAwBrN,EAAayD,iBAAiBC,IAAc,CAAA,EAEpEuJ,EAAa,CACjBzZ,MAAO,GAAGpG,KAAKwF,KAAKE,SAAS,0CAA0C3M,KACvEyb,QAAS,CACP1c,SAAU,IAAKmoB,EAAiBlnB,SAElCwlB,OAAQhR,UACN,MAAM5V,EAAQib,EAAaqD,SAAS,CAAE/I,WACtC,IAAKvV,EAAO,OACZ,MAAMuoB,GAAWb,GAAUtmB,MAAQ,IAAIonB,OACnCD,IACFvoB,EAAMoB,KAAOmnB,EACbvoB,EAAM0f,SAAW6I,GAEnBvoB,EAAMG,SAAW,IACZH,EAAMG,SACTsoB,eAAgBf,GAAUe,eAC1BiB,SAAUhC,GAAUgC,SACpBhB,YAAahB,GAAUgB,YACvB7hB,KAAM6gB,GAAU7gB,KAChB8hB,MAAOjB,GAAUiB,MACjB3J,UAAW0I,GAAU1I,UACrB7O,KAAMuX,GAAUvX,KAChB7I,MAAOogB,GAAUiC,cAEb1O,EAAamF,WAAW,CAAEC,WAAW,EAAMC,UAAU,IAC3DmD,MAAM0E,QAAQ,4BAA4B,GAI9C,IAAIJ,gBAAgBG,GAAYE,QAAO,EACxC,CAYD,wBAAawB,CAAY3O,GAAc1F,OAAEA,EAAMD,MAAEA,IAC/C,GAAc,IAAVA,EAAa,CACf,MAAMuU,EAAWlX,OAAOG,OAAOmI,EAAajG,QACzC7C,QAAO+W,GAAiB,IAAZA,EAAE5T,OAAe4T,EAAErL,UAAYqL,EAAE3T,SAAWA,IACxDpF,MAAK,CAACC,EAAGC,IAAMD,EAAE6E,MAAQ5E,EAAE4E,QAC3BzJ,KAAI0d,IAAC,CAAOpe,GAAIoe,EAAEpe,GAAI4U,SAAUwJ,EAAExJ,SAAUte,KAAM8nB,EAAE9nB,KAAMmB,KAAM2mB,EAAE3mB,eAC/D0Y,EAAa4E,aAAagK,EAAU,CAAEvU,MAAO,GACzD,KAAW,CACL,MAAMwI,EAAevI,EAAOlB,MAAM,KAAK7D,MAAM,GAAI,GAAGb,KAAK,KACnDoQ,EAAkB9E,EAAaqD,SAAS,CAAE/I,OAAQuI,IACxD,IAAKiC,EAAiB,OACtB,MAAM+J,EAAcnX,OAAOG,OAAOmI,EAAajG,QAC5C7C,QAAO+W,GAAKA,EAAE3T,OAAOiJ,WAAW,GAAGV,OAAoBoL,EAAE5T,QAAUA,GAAS4T,EAAErL,UAAYqL,EAAE3T,SAAWA,IACvGpF,MAAK,CAACC,EAAGC,IAAMD,EAAE6E,MAAQ5E,EAAE4E,QACxB+I,EAAQ8L,EACX3X,QAAO+W,GAA2B,QAAtBA,EAAE/oB,UAAUmH,QACxBkE,KAAI0d,IAAC,CAAOpe,GAAIoe,EAAEpe,GAAI4U,SAAUwJ,EAAExJ,SAAUte,KAAM8nB,EAAE9nB,KAAMmB,KAAM2mB,EAAE3mB,SAC/D0b,EAAO6L,EACV3X,QAAO+W,GAA2B,QAAtBA,EAAE/oB,UAAUmH,QACxBkE,KAAI0d,IAAC,CAAOpe,GAAIoe,EAAEpe,GAAI4U,SAAUwJ,EAAExJ,SAAUte,KAAM8nB,EAAE9nB,KAAMmB,KAAM2mB,EAAE3mB,eAC/D0Y,EAAa4E,aAAa,IAAI7B,KAAUC,GAAO8B,EACtD,CAED,MAAMgK,EAAmB,GAAGxU,KAC5B,IAAK,MAAMvI,KAAO2F,OAAO8C,KAAKwF,EAAajG,SACrChI,IAAQuI,GAAUvI,EAAIwR,WAAWuL,YAC5B9O,EAAajG,OAAOhI,SAIzBiO,EAAamF,WAAW,CAAEC,WAAW,EAAMC,UAAU,IAC3DmD,MAAM0E,QAAQ,4BACf,CAaD,yBAAa6B,CAAa/O,EAAcC,GAAe3F,OAAEA,EAAMkQ,SAAEA,IAC/D,MAAMzlB,EAAQib,EAAaqD,SAAS,CAAE/I,WACtC,IAAKvV,EAAO,OACZ,MAAMiqB,EAAYjqB,EAAMqe,QACrBlM,QAAO/B,GAAKA,EAAEyN,UAAYzN,EAAEtF,KAAO2a,IACnCja,KAAI4E,IAAC,CAAOtF,GAAIsF,EAAEtF,GAAI4U,SAAUtP,EAAEsP,SAAUte,KAAMgP,EAAEhP,KAAMmB,KAAM6N,EAAE7N,SACrE2Y,EAAcgP,cAAcD,EAAW,CAAE1U,iBACnC0F,EAAamF,WAAW,CAAEC,WAAW,EAAMC,UAAU,IAC3DmD,MAAM0E,QAAQ,4BACf,ECjPH,MAAM3B,cAAEA,EAAaC,2BAAEA,GAA+Brc,QAAQiM,aAAawP,IAKpE,MAAMsE,uBAAuB1D,EAA2BD,IAC7DK,uBAAyB,CACvB7gB,QAAS,CAAC,GAAGxG,EAAOC,SAAU,uBAC9BqL,GAAI,2BACJkb,OAAQ,CAAEoE,OAAO,IAGnBvD,aAAe,CACbE,KAAM,CAAEc,SAAUjoB,EAASE,aAG7B,WAAA+I,EAAYwhB,UAAEA,EAASC,SAAEA,EAAQC,WAAEA,IACjC5D,QACA5d,KAAKshB,UAAYA,EACjBthB,KAAKuhB,SAAWA,EAChBvhB,KAAKwhB,WAAaA,CACnB,CAID,qBAAM/C,GACJ,MAAO,CAAE6C,UAAWthB,KAAKshB,UAC1B,CAID,SAAAG,CAAUC,EAAStgB,GACjBwc,MAAM6D,UAAUC,EAAStgB,GACzB,MAAMugB,EAAO3hB,KAAK2J,QAEZyU,EAAQ,IACRwD,EAAY,IACZC,EAAYlZ,SAASmZ,gBAAgBC,YACrCC,EAAYrZ,SAASmZ,gBAAgBG,aACrCC,EAAM,EACZ,IAAIC,EAAOnb,KAAKob,MAAMpiB,KAAKwhB,YAAYW,MAAQ,GAC3CE,EAAMrb,KAAKob,OAAOpiB,KAAKwhB,YAAYc,QAAU,GAAKJ,GACtDC,EAAOnb,KAAKuZ,IAAI,EAAGvZ,KAAKwZ,IAAI2B,EAAMN,EAAYzD,EAAQ,IACtDiE,EAAMrb,KAAKuZ,IAAI,EAAGvZ,KAAKwZ,IAAI6B,EAAKL,EAAYJ,EAAY,IACxDhY,OAAO6C,OAAOkV,EAAKpjB,MAAO,CACxB4jB,KAAM,GAAGA,MACTE,IAAK,GAAGA,MACRjE,MAAO,GAAGA,MACVwD,UAAW,GAAGA,QAGhB,MAAMW,EAAQZ,EAAK/Y,cAAc,2BAC3BlF,EAAQie,EAAKa,iBAAiB,kFAC9BC,EAAYd,EAAK/Y,cAAc,2BAC/B8Z,EAAaf,EAAK/Y,cAAc,gCAChC+Z,EAAWhB,EAAK/Y,cAAc,0BAEhC6Z,IAAWA,EAAUlkB,MAAMqkB,QAAU,QACrCD,IAAUA,EAASpkB,MAAMqkB,QAAU,QAEvC,IAAIC,EAAa,EACbC,GAAe,EAEnB,MAAMC,SAAWC,GAA2B,SAArBA,EAAGzkB,MAAMqkB,QAE1BK,aAAe,IACnBzY,MAAMC,KAAKkX,EAAKa,iBAAiB,0BAC9BpZ,QAAO4Z,IAAOD,SAASC,KAAQA,EAAGja,UAAUC,SAAS,2BAEpDka,eAAiB,KACrBvB,EAAKa,iBAAiB,iCAAiCnJ,SAAQ8J,GAAMA,EAAGpa,UAAUQ,OAAO,YAAW,EAGhG6Z,UAAY,KAEhB,GADAF,kBACKJ,EAAc,OACnB,MAAMO,EAAMJ,eACRI,EAAIR,KACNQ,EAAIR,GAAY9Z,UAAUS,IAAI,WAC9B6Z,EAAIR,GAAYS,eAAe,CAAEvY,MAAO,YACzC,EAGGwY,YAAc,KAClB,MAAMC,EAAQjB,EAAM3hB,MAAM6e,OAAOve,cACjC,IAAIuiB,EAAe,EACfC,GAAa,EAEjBhgB,EAAM2V,SAAQ2J,IACZ,MAAM3qB,GAAQ2qB,EAAGxG,QAAQ7F,UAAYqM,EAAGxG,QAAQnkB,MAAQ,IAAI6I,cACtDyiB,GAASH,GAASnrB,EAAKkL,SAASigB,GACtCR,EAAGzkB,MAAMqkB,QAAUe,EAAQ,GAAK,OAC5BA,GAAOF,IACPprB,IAASmrB,IAAOE,GAAa,EAAI,IAGnCF,IAAUE,GACZhB,EAAWkB,YAAc,IAAIrB,EAAM3hB,MAAM6e,UACzCgD,EAAUlkB,MAAMqkB,QAAU,GAC1Ba,KAEAhB,EAAUlkB,MAAMqkB,QAAU,OAG5BD,EAASpkB,MAAMqkB,QAAUa,EAAe,EAAI,OAAS,GACrDZ,EAAa,EACbO,WAAW,EAGPS,KAAOb,IACX,GAAKA,IAAMA,EAAGja,UAAUC,SAAS,yBAAjC,CACA,GAA0B,SAAtBga,EAAGxG,QAAQpjB,OAAmB,CAChC,MAAMf,EAAOkqB,EAAM3hB,MAAM6e,OACzB,IAAKpnB,EAAM,OACX2H,KAAKuhB,SAAS,CAAExf,GAAI,KAAM1J,OAAMse,SAAUte,EAAMmB,KAAM,UAC9D,MACQwG,KAAKuhB,SAAS,CACZxf,GAAIihB,EAAGxG,QAAQza,GACf1J,KAAM2qB,EAAGxG,QAAQnkB,KACjBse,SAAUqM,EAAGxG,QAAQ7F,SACrBnd,KAAMwpB,EAAGxG,QAAQhjB,OAGrBwG,KAAK8jB,OAb6D,CAatD,EAGdvB,EAAMwB,iBAAiB,QAASR,aAChChB,EAAMwB,iBAAiB,WAAWC,IAChC,GAAe,cAAXA,EAAG/f,IACL+f,EAAGC,iBACHpB,EAAaC,EAAe9b,KAAKwZ,IAAIqC,EAAa,EAAGI,eAAe/b,OAAS,GAAK,EAClF4b,GAAe,EACfM,iBACK,GAAe,YAAXY,EAAG/f,IACZ+f,EAAGC,iBACHpB,EAAaC,EAAe9b,KAAKuZ,IAAIsC,EAAa,EAAG,GAAK,EAC1DC,GAAe,EACfM,iBACK,GAAe,UAAXY,EAAG/f,IAAiB,CAC7B+f,EAAGC,iBACH,MAAM5hB,EAASygB,EAAeG,eAAeJ,GAAcI,eAAe,GAC1EY,KAAKxhB,EACb,KAA4B,WAAX2hB,EAAG/f,MACZ+f,EAAGC,iBACHjkB,KAAK8jB,QACN,IAGHnC,EAAKa,iBAAiB,yBAAyBnJ,SAAQ2J,IACrDA,EAAGe,iBAAiB,SAAS,IAAMF,KAAKb,IAAI,IAG9ChjB,KAAKkkB,gBAAkBF,IAChBrC,EAAK3Y,SAASgb,EAAG3hB,SAASrC,KAAK8jB,OAAO,EAE7Cnb,SAASob,iBAAiB,cAAe/jB,KAAKkkB,iBAAiB,GAE/DX,cACAjjB,YAAW,IAAMiiB,EAAM4B,SAAS,EACjC,CAID,WAAML,CAAM1iB,EAAU,IAOpB,OANIpB,KAAKkkB,kBACPvb,SAASyb,oBAAoB,cAAepkB,KAAKkkB,iBAAiB,GAClElkB,KAAKkkB,gBAAkB,MAEzBlkB,KAAK2J,SAASJ,SACdlI,QAAQiM,aAAa+W,UAAUC,OAAOtkB,KAAK+B,IACpC/B,IACR,CAaD,iBAAaukB,EAAKrS,aAAEA,EAAY6C,aAAEA,EAAYyP,YAAEA,EAAWrG,SAAEA,EAAQsG,cAAEA,IACrE,MAAMnD,QAAkBpP,EAAa4F,mBAAmB,CAAEtL,OAAQuI,EAAcxI,MAAOiY,IAEjFjD,SAAW1U,UACf,MAAMkU,EAAcnX,OAAOG,OAAOmI,EAAajG,QAC5C7C,QAAO+W,GAAKA,EAAE3T,OAAOiJ,WAAW,GAAGV,OAAoBoL,EAAE5T,QAAUiY,EAAc,GAAKrE,EAAErL,WACxF1N,MAAK,CAACC,EAAGC,IAAMD,EAAE6E,MAAQ5E,EAAE4E,QAExB+I,EAAQ8L,EACX3X,QAAO+W,GAA2B,QAAtBA,EAAE/oB,UAAUmH,QACxBkE,KAAI0d,IAAC,CAAOpe,GAAIoe,EAAEpe,GAAI4U,SAAUwJ,EAAExJ,SAAUte,KAAM8nB,EAAE9nB,KAAMmB,KAAM2mB,EAAE3mB,SAC/D0b,EAAO6L,EACV3X,QAAO+W,GAA2B,QAAtBA,EAAE/oB,UAAUmH,QACxBkE,KAAI0d,IAAC,CAAOpe,GAAIoe,EAAEpe,GAAI4U,SAAUwJ,EAAExJ,SAAUte,KAAM8nB,EAAE9nB,KAAMmB,KAAM2mB,EAAE3mB,SAE/DkrB,EAAS,CACb3iB,GAAI4iB,EAAO5iB,IAAM4iB,EAAOtsB,KAAK0nB,QAAQ,CAAEC,YAAa,IAAKC,QAAQ,KAAW,WAC5EtJ,SAAUgO,EAAOhO,UAAYgO,EAAOtsB,KACpCA,KAAMssB,EAAOtsB,KACbmB,KAAMmrB,EAAOnrB,MAAQ,UAGjBorB,EAAO,IAAI1b,IAAI,IAAI+L,KAAUC,GAAMzS,KAAI0d,GAAKA,EAAEpe,MACpD,GAAI6iB,EAAKtb,IAAIob,EAAO3iB,IAAK,CACvB,MAAM8iB,EAAOH,EAAO3iB,GACpB,IAAIqe,EAAS,EACb,KAAOwE,EAAKtb,IAAI,GAAGub,KAAQzE,MAAWA,IACtCsE,EAAO3iB,GAAK,GAAG8iB,KAAQzE,GACxB,CAED,MAAME,EAAWtZ,KAAKuZ,IAAI,EAAGvZ,KAAKwZ,IAAIrC,EAAUlJ,EAAM/N,SACtD+N,EAAM9H,OAAOmT,EAAU,EAAGoE,GAE1B,MAAM1N,EAAkB9E,EAAaqD,SAAS,CAAE/I,OAAQuI,IACnDiC,UAEC9E,EAAa4E,aAAa,IAAI7B,KAAUC,GAAO8B,SAC/C9E,EAAamF,WAAW,CAAEC,WAAW,EAAMC,UAAU,IAC3DmD,MAAM0E,QAAQ,6BAA4B,EAGtC0F,EAAOL,EAAcM,wBACrBC,EAAM,IAAI5D,eAAe,CAAEE,YAAWC,kBAAUC,WAAYsD,UAC5DE,EAAI3F,OAAO,CAAExD,OAAO,GAC3B,ECpOH,MAAM4B,cAAEA,EAAaC,2BAAEA,GAA+Brc,QAAQiM,aAAawP,IAKpE,MAAMmI,qBAAqBvH,EAA2BD,IAC3DK,uBAAyB,CACvB7gB,QAAS,CAAC,GAAGxG,EAAOC,SAAU,uBAC9BqL,GAAI,2BACJkb,OAAQ,CAAEoE,OAAO,IAKnBvD,aAAe,CACbE,KAAM,CAAEc,SAAUjoB,EAASE,aAK7B,WAAA+I,EAAYwhB,UAAEA,EAASC,SAAEA,EAAQC,WAAEA,IACjC5D,QACA5d,KAAKshB,UAAYA,EACjBthB,KAAKuhB,SAAWA,EAChBvhB,KAAKwhB,WAAaA,CACnB,CAID,qBAAM/C,GACJ,MAAO,CAAE6C,UAAWthB,KAAKshB,UAC1B,CAID,SAAAG,CAAUC,EAAStgB,GACjBwc,MAAM6D,UAAUC,EAAStgB,GACzB,MAAMugB,EAAO3hB,KAAK2J,QAEZyU,EAAQ,IACRwD,EAAY,IACZC,EAAYlZ,SAASmZ,gBAAgBC,YACrCC,EAAYrZ,SAASmZ,gBAAgBG,aACrCC,EAAM,EACZ,IAAIC,EAAOnb,KAAKob,MAAMpiB,KAAKwhB,YAAYW,MAAQ,GAC3CE,EAAMrb,KAAKob,OAAOpiB,KAAKwhB,YAAYc,QAAU,GAAKJ,GACtDC,EAAOnb,KAAKuZ,IAAI,EAAGvZ,KAAKwZ,IAAI2B,EAAMN,EAAYzD,EAAQ,IACtDiE,EAAMrb,KAAKuZ,IAAI,EAAGvZ,KAAKwZ,IAAI6B,EAAKL,EAAYJ,EAAY,IACxDhY,OAAO6C,OAAOkV,EAAKpjB,MAAO,CACxB4jB,KAAM,GAAGA,MACTE,IAAK,GAAGA,MACRjE,MAAO,GAAGA,MACVwD,UAAW,GAAGA,QAGhB,MAAMW,EAAQZ,EAAK/Y,cAAc,2BAC3BlF,EAAQie,EAAKa,iBAAiB,kFAC9BC,EAAYd,EAAK/Y,cAAc,2BAC/B+Z,EAAWhB,EAAK/Y,cAAc,0BAEhC6Z,GAAWA,EAAUlZ,SACrBoZ,IAAUA,EAASpkB,MAAMqkB,QAAU,QAEvC,IAAIC,EAAa,EACbC,GAAe,EAEnB,MAAMC,SAAWC,GAA2B,SAArBA,EAAGzkB,MAAMqkB,QAE1BK,aAAe,IACnBzY,MAAMC,KAAKkX,EAAKa,iBAAiB,0BAC9BpZ,QAAO4Z,IAAOD,SAASC,KAAQA,EAAGja,UAAUC,SAAS,2BAEpDka,eAAiB,KACrBvB,EAAKa,iBAAiB,iCAAiCnJ,SAAQ8J,GAAMA,EAAGpa,UAAUQ,OAAO,YAAW,EAGhG6Z,UAAY,KAEhB,GADAF,kBACKJ,EAAc,OACnB,MAAMO,EAAMJ,eACRI,EAAIR,KACNQ,EAAIR,GAAY9Z,UAAUS,IAAI,WAC9B6Z,EAAIR,GAAYS,eAAe,CAAEvY,MAAO,YACzC,EAGGwY,YAAc,KAClB,MAAMC,EAAQjB,EAAM3hB,MAAM6e,OAAOve,cACjC,IAAIuiB,EAAe,EAEnB/f,EAAM2V,SAAQ2J,IACZ,MAAM3qB,GAAQ2qB,EAAGxG,QAAQ7F,UAAYqM,EAAGxG,QAAQnkB,MAAQ,IAAI6I,cACtDyiB,GAASH,GAASnrB,EAAKkL,SAASigB,GACtCR,EAAGzkB,MAAMqkB,QAAUe,EAAQ,GAAK,OAC5BA,GAAOF,GAAc,IAG3Bd,EAASpkB,MAAMqkB,QAAUa,EAAe,EAAI,OAAS,GACrDZ,EAAa,EACbO,WAAW,EAGPS,KAAOb,IACNA,IAAMA,EAAGja,UAAUC,SAAS,2BACjChJ,KAAKuhB,SAAS,CACZxf,GAAIihB,EAAGxG,QAAQza,GACf1J,KAAM2qB,EAAGxG,QAAQnkB,KACjBse,SAAUqM,EAAGxG,QAAQ7F,SACrBnd,KAAMwpB,EAAGxG,QAAQhjB,OAEnBwG,KAAK8jB,QAAO,EAGdvB,EAAMwB,iBAAiB,QAASR,aAChChB,EAAMwB,iBAAiB,WAAWC,IAChC,GAAe,cAAXA,EAAG/f,IACL+f,EAAGC,iBACHpB,EAAaC,EAAe9b,KAAKwZ,IAAIqC,EAAa,EAAGI,eAAe/b,OAAS,GAAK,EAClF4b,GAAe,EACfM,iBACK,GAAe,YAAXY,EAAG/f,IACZ+f,EAAGC,iBACHpB,EAAaC,EAAe9b,KAAKuZ,IAAIsC,EAAa,EAAG,GAAK,EAC1DC,GAAe,EACfM,iBACK,GAAe,UAAXY,EAAG/f,IAAiB,CAC7B+f,EAAGC,iBACH,MAAM5hB,EAASygB,EAAeG,eAAeJ,GAAcI,eAAe,GAC1EY,KAAKxhB,EACb,KAA4B,WAAX2hB,EAAG/f,MACZ+f,EAAGC,iBACHjkB,KAAK8jB,QACN,IAGHnC,EAAKa,iBAAiB,yBAAyBnJ,SAAQ2J,IACrDA,EAAGe,iBAAiB,SAAS,IAAMF,KAAKb,IAAI,IAG9ChjB,KAAKkkB,gBAAkBF,IAChBrC,EAAK3Y,SAASgb,EAAG3hB,SAASrC,KAAK8jB,OAAO,EAE7Cnb,SAASob,iBAAiB,cAAe/jB,KAAKkkB,iBAAiB,GAE/DX,cACAjjB,YAAW,IAAMiiB,EAAM4B,SAAS,EACjC,CAID,WAAML,CAAM1iB,EAAU,IAOpB,OANIpB,KAAKkkB,kBACPvb,SAASyb,oBAAoB,cAAepkB,KAAKkkB,iBAAiB,GAClElkB,KAAKkkB,gBAAkB,MAEzBlkB,KAAK2J,SAASJ,SACdlI,QAAQiM,aAAa+W,UAAUC,OAAOtkB,KAAK+B,IACpC/B,IACR,CAaD,iBAAaukB,EAAKrS,aAAEA,EAAYC,cAAEA,EAAa4C,aAAEA,EAAYyP,YAAEA,EAAWC,cAAEA,IAC1E,MAAM7O,EAAY,CAAEpJ,OAAQuI,EAAcxI,MAAOiY,GAC3CU,EAAa/S,EAAcgT,sBAC3BrQ,EAAW3C,EAAciT,mBAAmBxP,IAAc,GAC1DyP,EAAc,IAAInc,IAAI4L,EAASrS,KAAI4E,GAAKA,EAAEtF,MAE1Cuf,EAAY4D,EAAW9b,QAAO/B,IAAMge,EAAY/b,IAAIjC,EAAEtF,MAEtDwf,SAAW1U,UACf,MAAMyY,EAAW,CACfvjB,GAAI4iB,EAAO5iB,GACX4U,SAAUgO,EAAOhO,UAAYgO,EAAOtsB,KACpCA,KAAMssB,EAAOtsB,KACbmB,KAAMmrB,EAAOnrB,MAAQ,UAEjB+rB,EAAW,IAAIzQ,EAAUwQ,SACzBnT,EAAcgP,cAAcoE,EAAU3P,SACtC1D,EAAamF,WAAW,CAAEC,WAAW,EAAMC,UAAU,IAC3DmD,MAAM0E,QAAQ,4BAA4B,EAGtC0F,EAAOL,EAAcM,wBACrBC,EAAM,IAAIC,aAAa,CAAE3D,YAAWC,kBAAUC,WAAYsD,UAC1DE,EAAI3F,OAAO,CAAExD,OAAO,GAC3B,ECnMI,MAAM2J,aACX,WAAA1lB,CAAYP,EAAgB0S,GAC1BjS,KAAKT,eAAiBA,EACtBS,KAAKiS,WAAaA,EAClBjS,KAAKkS,aAAeD,EAAWC,aAC/BlS,KAAKylB,QAAU,EACfzlB,KAAK0lB,eAAgB,EACrB1lB,KAAK5I,SAAW,KAChB4I,KAAK2lB,QAAU,EAChB,CAQD,iBAAMC,CAAYrJ,GACXA,UAECvc,MAAK6lB,EAActJ,GAEpBvc,KAAK8lB,mBAEL9lB,KAAKT,eAAe5G,gBACjBqH,MAAK+lB,UAGP/lB,MAAKgmB,IAEXhmB,MAAKimB,KACN,CASD,OAAMJ,CAActJ,GAClBvc,MAAKimB,IAELjmB,KAAKuc,aAAeA,QAGdvc,MAAKkmB,IACNlmB,KAAK8lB,mBAGV9lB,MAAKmmB,IAGLnmB,MAAKomB,IACN,CAQD,EAAAH,GACEjmB,KAAKqmB,gBAAkB,KACvBrmB,KAAKsmB,gBAAkB,KACvBtmB,KAAKumB,eAAiB,KACtBvmB,KAAKwmB,UAAY,KACjBxmB,KAAKuc,aAAe,KACpBvc,KAAKymB,mBAAqB,KAC1BzmB,KAAK8lB,iBAAmB,KACxB9lB,KAAK0mB,wBAA0B,KAC/B1mB,KAAK2mB,qBAAuB,KAC5B3mB,KAAK0lB,eAAgB,EACrB1lB,KAAKylB,QAAU,EACfzlB,KAAK5I,SAAW,KAChB4I,KAAK2lB,QAAU,EAChB,CAOD,EAAAQ,GACE,MAAMS,EAAqB5mB,KAAKuc,aAAaja,QAAQ,uBAC/CukB,EAAiBD,EAAmBpE,iBAAiB,kBACrDjkB,EAAQ,CAAEqjB,UAAW,GAAIkF,UAAW,IAC1C9mB,MAAK+mB,EAAUF,EAAgBtoB,EAChC,CAQD,OAAMyoB,GAEJ,MAAMC,EAAa,CAAErE,QAAS,GAAIsE,oBAAqB,GAAI9I,MAAO,UAC5Dpe,MAAK+mB,EAAU/mB,KAAKqmB,gBAAiBY,GAC3CjnB,KAAKqmB,gBAAgBhN,SAAQ8J,GAAMA,EAAGpa,UAAUQ,OAAO,sBAEvD,MAAM4d,EAAe,GACfC,EAAwB,GAC9B,IAAK,MAAMC,KAAkBrnB,KAAKqmB,gBAAiB,CACjD,MAAMiB,EAAiBD,EAAe7E,iBAAiB,4BACvD,IAAK,MAAM+E,KAAiBD,EAAgB,CAC1C,MAAME,EAAaD,EAAcxC,wBAC3B0C,EAAczgB,KAAKob,MAAMsF,WAAWF,EAAWpJ,OAAS,GAAK,GAC7DuJ,EAAmBJ,EAAc3e,cAAc,2BAC/Cgf,EAAuBD,GAAkB5C,wBACzC8C,EAAwB7gB,KAAKob,MAAMsF,WAAWE,GAAsBxJ,QAAU,GACpFgJ,EAAsBhkB,KAAKqkB,GAC3BN,EAAa/jB,KAAK,CAAEqkB,cAAaI,yBAClC,CACF,CAED,IAAI7f,EAAuBhB,KAAKW,KAAKlI,MAAM8H,wBAAwB6f,IACnE,MAAMU,EAA2B,GAEjC,IAAK,MAAML,KAAeN,EAAc,CACtC,MAAMY,EAAiC/f,GAClCyf,EAAYA,YAAcA,EAAYI,uBACvCE,EAAiCD,IACnC9f,EAAwBA,EAAuB+f,EAAkCD,EAEpF,CAED9nB,KAAKwmB,UAAYxe,CAClB,CAUD,OAAMggB,CAAYX,EAAgBY,GAChC,IAAKZ,EAAgB,OACrB,MAAMJ,EAAa,CAAErE,QAAS,GAAIsE,oBAAqB,GAAI9I,MAAO,UAC5Dpe,MAAKkoB,EAAWb,EAAgBJ,GAEtC,MAAM3R,EAAU+R,EAAe7E,iBAAiB,eAC1C2F,EAAcnhB,KAAKW,KAAKX,KAAKohB,KAAK9S,EAAQpO,SAC1CmhB,EAAsBJ,GAAoBjoB,KAAKumB,eAC/C+B,EAAgBthB,KAAKC,MAAMohB,EAAsBroB,KAAKwmB,WACtD+B,EAAQJ,EAAcG,GAAiBL,EACzCK,EACChT,EAAQpO,QAAUlH,KAAKylB,QAAWnQ,EAAQpO,OAASihB,EAElD5pB,EAAQ,CAAEqkB,QAAS,OAAQsE,oBAAqB,UAAUqB,MAASvoB,KAAKwmB,gBAC9Ea,EAAete,UAAUS,IAAI,0BACvBxJ,MAAKkoB,EAAWb,EAAgB9oB,EACvC,CAUD,OAAMiqB,CAAQnB,EAAgBY,GAC5B,IAAKZ,EAAgB,OACrBA,EAAete,UAAUQ,OAAO,oBAEhC,IAAI6U,EAAQ,IAEZ,GAAIpe,KAAK0lB,cACPtH,EAAQpe,KAAKumB,oBACR,GAAI0B,EACT7J,EAAQ6J,MACH,CACL,MAAM3S,EAAU+R,EAAe7E,iBAAiB,eAChD,IAAKlN,EAAQpO,OAAQ,OACrB,MAAMuhB,EAAczhB,KAAKW,KAAKX,KAAKohB,KAAK9S,EAAQpO,SAGhD,IAAIwhB,EAAa,EACbC,EAAc,EACdC,EAAW,EAEXtT,EAAQpO,OAAS,GACnBoO,EAAQ+D,SAAQ,CAACviB,EAAQoW,MAClBA,EAAQ,GAAKub,EAAcC,IAC9BE,GAAsB,EACtBD,EAAeC,EAAWD,EAAeC,EAAWD,EACpDC,EAAW,EACXF,KAEF,MAAMlB,EAAa1wB,EAAOiuB,wBACpB0C,EAAczgB,KAAKW,KAAK+f,WAAWF,EAAWpJ,OAAS,GAAK,GAClEwK,GAAYnB,EACRva,EAAQ,IAAMoI,EAAQpO,SACxB0hB,GAAsB,EACtBD,EAAeC,EAAWD,EAAeC,EAAWD,EACrD,IAKLA,GAAe3oB,KAAK0mB,wBAGpBtI,EAASuK,EAAc3oB,KAAKumB,gBAAkBjR,EAAQpO,OAAS,EAAKyhB,EAAc3oB,KAAKumB,eACnFnI,EAAQ,MAAKA,EAAQ,IAC1B,CAED,MAAM7f,EAAQ,CAAEsqB,SAAU,GAAGzK,aACvBpe,MAAKkoB,EAAWb,EAAgB9oB,EACvC,CASD,EAAAuqB,GACE,MAAMnJ,EAAc3f,KAAK5I,UAAUuoB,YAEnC,GAAIA,EAEF,OADA3f,KAAK0lB,eAAgB,EACd/F,EAGT,MAAMoJ,EAAcpnB,OAAOqnB,iBAAiB,IAAM/L,OAAOgM,WACnDC,EAAclpB,KAAK2mB,qBAAqBxE,KACxCgH,EAAUxgB,SAASC,cAAc,aACjCwgB,EAAqBD,EAAQpH,YACnC,OAAO/a,KAAKC,OACVmiB,EAAqB,EACjBL,EAAcK,EACdL,GACF/oB,KAAK2lB,QAAUuD,EACpB,CAQD,OAAMhD,GACJlmB,KAAK8lB,iBAAmB9lB,KAAKuc,aAAa3T,cAAc,2BACnD5I,KAAK8lB,mBACV9lB,KAAK2mB,qBAAuB3mB,KAAK8lB,iBAAiBf,wBAClD/kB,KAAKqpB,yBAA2BC,iBAAiBtpB,KAAK8lB,kBACtD9lB,KAAK0mB,wBACH1f,KAAKW,KAAK+f,WAAW1nB,KAAKqpB,yBAAyBE,cAAgB,GACjEviB,KAAKW,KAAK+f,WAAW1nB,KAAKqpB,yBAAyBG,eAAiB,GACzE,CAQD,EAAApD,GACEpmB,KAAKymB,mBAAqBzmB,KAAKuc,aAAaiG,iBAAiB,0BACtB,IAAnCxiB,KAAKymB,mBAAmBvf,SAAclH,KAAKymB,mBAAqB,CAACzmB,KAAKuc,cAC3E,CAOD,OAAMwJ,GAIJ,GAHA/lB,KAAKqmB,gBAAkBrmB,KAAKuc,aAAaiG,iBAAiB,yBAGtB,IAAhCxiB,KAAKqmB,gBAAgBnf,OAAc,OAGvC,MAAMsF,EAASxM,KAAKuc,aAAaC,QAAQhQ,OACzCxM,KAAK5I,eAAiB4I,KAAKkS,aAAayD,iBAAiB,CAAEnJ,SAAQD,MAAO,IAG1EvM,KAAKumB,eAAiBvmB,MAAK8oB,IAG3B,IAAIW,GAAU,EACd,IAAK,MAAMC,KAAmB1pB,KAAKymB,mBAAoB,CACrD,MAAMY,EAAiBqC,EAAgB9gB,cAAc,yBACrD,IAAKye,EAAgB,SACrB,MAAM7a,EAASkd,EAAgBlN,QAAQhQ,OACjC0J,QAAsBlW,KAAKkS,aAAayD,iBAAiB,CAAEnJ,WAC3Dyb,EAAmB/R,EAAcyJ,YACjC7hB,EAAO2B,MAAMC,WAAW,SAAWM,KAAK5I,UAAU0G,MAAQoY,GAAepY,MAAQupB,EAAe9oB,MAAMqkB,QACxG9kB,GACG2rB,UACGzpB,MAAKgnB,IACXyC,GAAU,SAENzpB,MAAKgoB,EAAYX,EAAgBY,UAEjCjoB,MAAKwoB,EAAQnB,EAAgBY,EAEtC,CACF,CAQD,OAAMjC,SACE,IAAI5lB,SAAQC,IAChBspB,uBAAsB,KACpB3pB,KAAKsmB,gBAAkBtmB,MAAK4pB,IAC5B,MAAMrrB,EAAQ,CAAEqjB,UAAW,GAAG5hB,KAAKsmB,oBAAqBQ,UAAW,QACnEld,OAAO6C,OAAOzM,KAAK8lB,iBAAiBvnB,MAAOA,GAC3C8B,GAAS,GACT,GAEL,CASD,EAAAupB,GACE,MAAMC,EAAeloB,OAAOqnB,iBAAiB,IAAM/L,OAAO6M,YACpDC,EAAgB/pB,KAAK2mB,qBAAqBrE,OAC1C0H,EAAahqB,KAAK2mB,qBAAqBtE,IAE7C,IAAI4H,EAAc,KAClB,GAAIjqB,KAAKT,eAAe5G,SAAU,CAChC,IAAIuxB,EAAiB,EACjBC,EAAUnqB,KAAKuc,aAAa6N,mBAEhC,GAAID,EAAS,CACX,MAAMrJ,EAAW,CAACqJ,GAClB,KAAOA,GACLA,EAAUA,EAAQC,mBACdD,GAASrJ,EAAS1d,KAAK+mB,GAE7B,IAAK,MAAMA,KAAWrJ,EAAU,CAC9B,MAAMuJ,EAAgBF,EAAQpF,wBAAwB1G,OACtD6L,GAAkBG,GAAiB,CACpC,CACF,CAED,MAAMC,EAASjpB,QAAQC,MAAMwH,eAAexJ,KAAKsG,QAAS,UACtD+C,SAASC,cAAc,WACvBD,SAASC,cAAc,cACrB2hB,EAAYD,GAAQvF,wBAAwB1C,KAAOwH,EACnDW,EAAgBxjB,KAAKuZ,IAAI,EAAGsJ,EAAeU,GAEjD,OAAOvjB,KAAKuZ,IAAIsJ,EAAeG,EAAaE,EAAiBM,EAAgBxqB,KAAK2lB,QAAS,IAC5F,CAEGsE,EAFyC,SAAlCjqB,KAAKT,eAAe/B,UACzB6D,QAAQC,MAAMwH,eAAexJ,KAAKsG,QAAS,UAC/B+C,SAASC,cAAc,WAEvBD,SAASC,cAAc,cAE9BvH,QAAQC,MAAMwH,eAAexJ,KAAKsG,QAAS,UACtC+C,SAASC,cAAc,4BAEvBD,SAASC,cAAc,WAEvC,MAAM6hB,EAA0BR,GAAaS,cAAgB,EACvDpE,EAAqD,SAAlCtmB,KAAKT,eAAe/B,UACzCqsB,EAAeG,EAAaS,EAA0BzqB,KAAK2lB,QAC3DoE,EAAgBU,EAA0BzqB,KAAK2lB,QACnD,OAAO3e,KAAKuZ,IAAI+F,EAAiB,IAClC,CAUD,OAAM4B,CAAWve,EAASpL,GACnBoL,GACLggB,uBAAsB,KACpB/f,OAAO6C,OAAO9C,EAAQpL,MAAOA,EAAM,GAEtC,CAUD,OAAMwoB,CAAU4D,EAAUpsB,GACxB,IAAK,MAAMoL,KAAWghB,EACpB/gB,OAAO6C,OAAO9C,EAAQpL,MAAOA,EAEhC,EC/YH,MAAMkf,cAAEA,EAAaC,2BAAEA,GAA+Brc,QAAQiM,aAAawP,IAKpE,MAAM8N,uBAAuBlN,EAA2BD,IAC7D,WAAA3d,CAAYoT,EAAe5D,EAAa3B,GACtCiQ,QACA5d,KAAKkT,cAAgBA,EACrBlT,KAAKsP,YAAcA,EACnBtP,KAAKiS,WAAa,IAAIuH,WAAWxZ,KAAMkT,EAAe5D,EAAa3B,GACnE3N,KAAK2N,OAASA,EACd3N,KAAK6qB,WAAa,IAAI3hB,IACtBlJ,KAAK8qB,mBAAqB,IAAIjrB,MAAM,IACpCG,KAAK+qB,YAAc,IAAIlrB,MAAM,IAC7BG,KAAKgrB,WAAa,KAClBhrB,KAAKirB,YAAc,KACnBjrB,KAAKR,QAAU,EAChB,CAQDse,uBAAyB,CACvBxI,QAAS,CACP4V,WAAY,CACVC,QAAS,CAAC,EAAG,GACbjN,QAAS0M,eAAeM,YAE1BE,cAAe,CACbD,QAAS,CAAC,EAAG,GACbjN,QAAS0M,eAAeQ,eAE1BC,YAAa,CACXF,QAAS,CAAC,EAAG,GACbjN,QAAS0M,eAAeS,aAE1BC,YAAaV,eAAeU,YAC5BC,UAAWX,eAAeW,UAC1BC,QAASZ,eAAeY,QACxBC,UAAWb,eAAea,UAC1BC,QAASd,eAAec,QACxB7S,SAAU+R,eAAe/R,SACzB8S,YAAaf,eAAee,YAC5BC,UAAWhB,eAAegB,WAE5BC,WAAY,OACZ5uB,QAAS,CAAC,YACV8E,GAAI,uBACJoc,SAAU,CACRC,MAAO5iB,EAAIE,cACX2iB,OAAQ7iB,EAAIC,eACZ0mB,KAAM3mB,EAAIG,iBACV0mB,IAAK7mB,EAAII,gBACTwC,MAAO5C,EAAIK,cACXiwB,OAAQtwB,EAAIM,gBAEdmhB,OAAQ,CACNoE,OAAO,EACP3b,MAAO,qBASXoY,aAAe,CACbE,KAAM,CACJc,SAAUjoB,EAASK,MAUvB,qBAAMunB,GACJ,IAAIsN,EAAW/rB,KAAKR,QAAQjB,OAASkB,MAAMC,WAAW,UAAY,aAC9DssB,EAAYhsB,KAAKkT,cAAca,OAAOgY,GACrCC,IACHD,EAAW,aACXC,EAAYhsB,KAAKkT,cAAca,OAAO9b,YAExC,MAAM4Q,EAAaxH,QAAQC,MAAMwH,eAAexJ,KAAKsG,QAAS,WAAa,CAAC,aAAc,oBAAqB,eAAerC,SAASwoB,GACnI,GAAGC,EAAU9zB,YACb8zB,EAAU9zB,MACRwpB,EAAU,CACdxqB,IAAK8I,KAAKiS,WAAW/a,IACrB6K,GAAI,mBACJxD,MAAOsK,GAAc,GACrBzK,MAAO4B,KAAK5B,MACZytB,WAAY,YACZ/yB,aAAckzB,EAAUlzB,cAAgB,gBACxCC,WAAYizB,EAAUjzB,YAAc,iBACpCkzB,qBAAsBxsB,MAAMC,WAAW,yBAIzC,OADAhB,EAAOnB,MAAM,sBAAuB,CAAEmkB,YAC/BA,CACR,CAUD,UAAM9T,GACJ5N,MAAKksB,GACN,CAOD,EAAAA,GACEtiB,OAAOtB,QAAQvL,GAASsc,SAAQ,EAAEpV,EAAKrD,MACjCA,EAAM1D,QACR8C,KAAKR,QAAQyE,GAAOxE,MAAMC,WAAWuE,GACtC,GAEJ,CAUD,0BAAMsZ,CAAqBtZ,EAAKrD,EAAQ,MAMtC,GALKZ,KAAKmsB,wBACRnsB,KAAKmsB,uBAAwB,EAC7BztB,EAAOnB,MAAM,yBAGVR,EAAQkH,IACRlH,EAAQkH,GAAK/G,MAIlB,OAFA8C,KAAKR,QAAQyE,GAAOrD,EAEZqD,GACN,IAAK,eACL,IAAK,mBACHjE,KAAKiS,WAAWgC,cAAc9X,aAAe,KAC7C,MACF,IAAK,cACH6D,KAAKiS,WAAW9T,YAAc6B,KAAKkT,cAAcwG,mBAAmB1Z,KAAKiS,WAAWE,eACpF,MACF,IAAK,QACHnS,KAAKosB,cACL,MACF,IAAK,OACHpsB,MAAKqsB,IAGV,CAWD,SAAA5K,CAAUC,EAAStgB,GACjBwc,MAAM6D,UAAUC,EAAStgB,GACzBpB,KAAK2J,QAAQZ,UAAUQ,OAAO,cAC9B9J,MAAMgJ,UAAUzI,KAAKR,QAAQjB,OAC7BgC,aAAaP,KAAKgrB,YAClBzqB,aAAaP,KAAKirB,aAClBjrB,MAAKssB,IACLtsB,MAAKusB,IACLvsB,MAAKwsB,EAAgBxsB,KAAK2qB,UAErB3qB,KAAKysB,yBACRzsB,MAAK0sB,IACL1sB,KAAKysB,wBAAyB,GAEhCzsB,MAAK2sB,IACL3sB,MAAKqsB,IACLrsB,MAAK4sB,GACN,CASD,EAAAP,CAA4BQ,GAC1B,MAAM1R,EAASnb,KAAK2qB,UAAUmC,WAC9B,IAAK3R,EAAQ,OACb,MAAM4R,EAAaF,GAAsB7sB,KAAK+sB,WACxCpvB,EAAO8B,MAAMC,WAAW,QACxBstB,EAAwB,WAATrvB,GAAgC,iBAATA,GAA2BovB,EACjEE,GAAQjtB,KAAKrH,UAAYq0B,EAC/B7R,EAAOpS,UAAUmkB,OAAO,cAAeD,EACxC,CAOD,EAAAX,GACEtsB,KAAK2qB,SAAW,CACd9X,cAAe7S,KAAK2J,QAAQf,cAAc,+BAC1CukB,UAAWntB,KAAK2J,QAAQ6Y,iBAAiB,wBACzC2I,QAASnrB,KAAK2J,QAAQf,cAAc,yBACpCwkB,eAAgBptB,KAAK2J,QAAQ6Y,iBAAiB,2BAC9CvW,OAAQjM,KAAK2J,QAAQf,cAAc,wBACnCykB,cAAertB,KAAK2J,QAAQf,cAAc,+BAC1C0kB,iBAAkBttB,KAAK2J,QAAQ6Y,iBAAiB,+BAChD+K,sBAAuBvtB,KAAK2J,QAAQ6Y,iBAAiB,oCACrDgL,SAAUxtB,KAAK2J,QAAQ6Y,iBAAiB,uBACxCiL,YAAaztB,KAAK2J,QAAQ6Y,iBAAiB,0BAC3CkL,qBAAsB1tB,KAAK2J,QAAQ6Y,iBAAiB,mCACpDmL,eAAgB3tB,KAAK2J,QAAQ6Y,iBAAiB,6BAC9CoL,kBAAmB5tB,KAAK2J,QAAQ6Y,iBAAiB,gCACjDqL,qBAAsB7tB,KAAK2J,QAAQ6Y,iBAAiB,mCACpDsL,mBAAoB9tB,KAAK2J,QAAQ6Y,iBAAiB,iCAClDsK,WAAY9sB,KAAK2J,QAAQf,cAAc,+BACvCmlB,wBAAyB/tB,KAAK2J,QAAQf,cAAc,yCACpDolB,kBAAmBhuB,KAAK2J,QAAQf,cAAc,mCAC9CqlB,gBAAiBjuB,KAAK2J,QAAQf,cAAc,iCAC5CslB,aAAcluB,KAAK2J,QAAQf,cAAc,iCACzCulB,WAAYnuB,KAAK2J,QAAQf,cAAc,+BAE1C,CAQD,EAAA2jB,GACMvsB,KAAKouB,aAAexD,eAAeU,YAAY3Q,KAAK3a,MAEpDP,MAAMC,WAAW,uBACfM,KAAK+sB,WACPnC,eAAea,UAAU9Q,KAAK3a,MAE9B4qB,eAAeY,QAAQ7Q,KAAK3a,OAG9B4qB,eAAeY,QAAQ7Q,KAAK3a,MAC5BA,KAAK2qB,SAASuD,aAAanlB,UAAUS,IAAI,cAE5C,CAQD,EAAAgjB,CAAgB7B,GACd,IAAKlrB,MAAMC,WAAW,qBAAsB,CAE1C,MAAM2uB,YAAcrK,IACdhkB,KAAK+sB,YAA0B,iBAAZ/I,EAAGxqB,MAC1BwG,KAAKsuB,YAAYtK,EAAG,EAEtB2G,EAASyC,eAAe/T,SAAQ1P,IAC9BA,EAAQoa,iBAAiB,aAAcsK,YAAa,CAAEE,SAAS,IAC/D5kB,EAAQoa,iBAAiB,eAAgBsK,aACzC1kB,EAAQoa,iBAAiB,eAAgBsK,YAAY,GAExD,EAGIruB,KAAKrH,UAAYgyB,EAASmC,aAC7BnC,EAASmC,WAAW/I,iBAAiB,YAAa/jB,MAAKwuB,EAAWC,KAAKzuB,OACvE2qB,EAASmC,WAAW/I,iBAAiB,aAAc/jB,MAAKwuB,EAAWC,KAAKzuB,MAAO,CAAEuuB,SAAS,KAI5F5D,EAASwC,UAAU9T,SAAQ1P,IACzBA,EAAQoa,iBAAiB,eAAgB/jB,KAAK0uB,kBAAkBD,KAAKzuB,OACrE2J,EAAQoa,iBAAiB,eAAgB/jB,KAAK0uB,kBAAkBD,KAAKzuB,MAAM,GAE9E,CAQD,EAAA0sB,GACE1sB,KAAK2J,QAAQoa,iBAAiB,eAAeC,IAC3C,MAAM2K,EAAe3K,EAAG3hB,OAAOC,QAAQ,8BACvC,GAAIqsB,EAAJ,CACE,MAAMC,EAAY5uB,KAAK+sB,YAActtB,MAAMC,WAAW,uBAChDmvB,EAAuD,SAAxCF,EAAanS,QAAQsS,gBACtCF,GAAaC,IACf7uB,KAAK+uB,oBAAoBC,YAAYhL,EAGxC,MAEIhkB,KAAK+sB,YACLttB,MAAMC,WAAW,wBAElBskB,EAAG3hB,OAAOC,QAAQ,uFACpBtC,KAAKivB,mBAAmBD,YAAYhL,EACrC,IAGHhkB,KAAK2J,QAAQoa,iBAAiB,YAAa/jB,MAAKkvB,EAAaT,KAAKzuB,OAClEA,KAAK2J,QAAQoa,iBAAiB,YAAa/jB,MAAKmvB,EAAaV,KAAKzuB,OAClEA,KAAK2J,QAAQoa,iBAAiB,WAAY/jB,MAAKovB,EAAYX,KAAKzuB,OAChEA,KAAK2J,QAAQoa,iBAAiB,YAAa/jB,MAAKqvB,EAAaZ,KAAKzuB,OAClEA,KAAK2J,QAAQoa,iBAAiB,OAAQ/jB,MAAKsvB,EAAQb,KAAKzuB,OACxDA,KAAK2J,QAAQoa,iBAAiB,UAAW/jB,MAAKuvB,EAAWd,KAAKzuB,MAC/D,CASD,UAAAwvB,GACExvB,KAAKyvB,WAAY,EACjBzvB,MAAK0vB,KACL1vB,MAAK2vB,KACA3vB,KAAKouB,cACRpuB,KAAKirB,YAAc3qB,YAAW,KAC5BqpB,uBAAsB,KACpB3pB,KAAK2J,SAASZ,WAAWS,IAAI,eAAe,GAC5C,GACD,IAEN,CAQD,GAAAkmB,GACE,GAAI1vB,KAAKrH,SAAU,OAEnB,MAAMka,cAAEA,EAAa0a,sBAAEA,GAA0BvtB,KAAK2qB,SAE/B,OAAnB3qB,KAAKxC,WACPqV,GAAe9J,WAAWS,IAAI,cAE9B+jB,EAAsBlU,SAAQ1P,IAC5BA,EAAQZ,UAAUQ,OAAO,eACzBI,EAAQZ,UAAUS,IAAI,YAAY,MAG/BxJ,KAAKouB,aACRvb,GAAe9J,WAAWQ,OAAO,cAGnCgkB,EAAsBlU,SAAQ1P,IAC5BA,EAAQZ,UAAUS,IAAI,eACtBG,EAAQZ,UAAUQ,OAAO,YAAY,IAG1C,CAQD,GAAAomB,GACO3vB,KAAK6qB,WAAW+E,MAErB5vB,KAAK6qB,WAAWxR,SAAQlN,IACtB,MAAMlV,EAAQ+I,KAAK2J,QAAQf,cAAc,IAAIuD,KACzClV,GACF+I,KAAKsuB,YAAY,KAAMr3B,EACxB,GAEJ,CASD,cAAOy0B,GACLzM,cAAcC,eAAelf,KAAKiS,WAAWC,aAC9C,CASD,eAAO2G,CAASzW,EAAOC,GACrB,MAAM8Y,EAAS9Y,GAAUD,EAAMC,OAAOC,QAAQ,4BACxC6b,EAAW0R,SAAS1U,GAAQqB,QAAQ2B,SAAU,IACpDc,cAAcY,gBAAgB7f,KAAKiS,WAAWC,aAActY,OAAOk2B,MAAM3R,GAAY,EAAIA,EAC1F,CASD,kBAAOwN,CAAYvpB,EAAOC,GACxB,MAAM8Y,EAAS9Y,GAAUD,EAAMC,OAAOC,QAAQ,+BAC9C,IAAK6Y,EAAQ,OACb,MAAMpG,EAAeoG,EAAOqB,QAAQzH,aAC9ByP,EAAcqL,SAAS1U,EAAOqB,QAAQgI,YAAa,KAAO,EAC1DrG,EAAW0R,SAAS1U,EAAOqB,QAAQ2B,SAAU,IACnDiD,eAAemD,KAAK,CAClBrS,aAAclS,KAAKiS,WAAWC,aAC9B6C,eACAyP,cACArG,SAAUvkB,OAAOk2B,MAAM3R,GAAY,EAAIA,EACvCsG,cAAetJ,GAElB,CAUD,gBAAOyQ,CAAUxpB,EAAOC,GACtB,MAAM8Y,EAAS9Y,GAAUD,EAAMC,OAAOC,QAAQ,6BAC9C,IAAK6Y,EAAQ,OACb,MAAMpG,EAAeoG,EAAOqB,QAAQzH,aAC9ByP,EAAcqL,SAAS1U,EAAOqB,QAAQgI,YAAa,KAAO,EAChES,aAAaV,KAAK,CAChBrS,aAAclS,KAAKiS,WAAWC,aAC9BC,cAAenS,KAAKiS,WAAWE,cAC/B4C,eACAyP,cACAC,cAAetJ,GAElB,CASD,qBAAM4U,GACJ,MAAM7pB,EAAUzG,MAAMoG,gBAAgB,oBAChCmqB,EAAShwB,KAAc,UAAI,WAAa,UAC1CA,KAAKiwB,UACPjwB,MAAK8jB,KAELpJ,MAAM0E,QAAQ,mCAEV3f,MAAM0E,WAAW,UAAWnE,KAAKiwB,WACvCvxB,EAAOC,KAAKW,KAAKwF,KAAKorB,OAAO,uCAAuCF,IAAS,CAAE9pB,aAAY,EAC5F,CASD,kBAAOolB,GACLtrB,KAAKmwB,kBAAkB,WACxB,CAOD,gBAAO5E,GACLvrB,KAAKmwB,kBAAkB,SACxB,CAQD,iBAAAA,CAAkBH,GAChBA,EAAQA,IAAWhwB,KAAgB,YAAI,SAAW,YAClD,MAAMowB,EAAyB,aAAVJ,GACfnd,cAAEA,EAAamb,kBAAEA,EAAiBC,gBAAEA,EAAehiB,OAAEA,EAAMkf,QAAEA,GAAYnrB,KAAK2qB,SAEpFqD,EAAkBjlB,UAAUmkB,OAAO,aAAckD,GACjDnC,EAAgBllB,UAAUmkB,OAAO,cAAekD,GAE5CpwB,KAAKrH,SACPqH,KAAK2J,QAAQZ,UAAUmkB,OAAO,gBAAiBkD,IAExB,SAAnBpwB,KAAKxC,WAAwBqV,EAAc9J,UAAUmkB,OAAO,aAAckD,GAC9EnkB,EAAOlD,UAAUmkB,OAAO,aAAckD,GACtCjF,EAAQpiB,UAAUmkB,OAAO,aAAckD,IAGzCpwB,KAAKouB,YAAcgC,CACpB,CAUD,sBAAa3E,CAAUrpB,EAAQ,MAC7BpC,KAAKqwB,cAAc,SAAUjuB,EAC9B,CAQD,oBAAaopB,CAAQppB,EAAQ,MAC3BpC,KAAKqwB,cAAc,OAAQjuB,EAC5B,CASD,aAAAiuB,CAAcL,EAAO5tB,EAAQ,MACvBA,GAAOA,EAAM6hB,iBAEjB,MAAMqM,EAAwB,WAAVN,GACd9B,aAAEA,EAAYC,WAAEA,EAAUd,cAAEA,EAAaI,YAAEA,EAAWE,eAAEA,EAAcC,kBAC1EA,EAAiBC,qBAAEA,EAAoBC,mBAAEA,EAAkB7hB,OAAEA,EAAMqhB,iBAAEA,EAAgBF,eACrFA,EAAcM,qBAAEA,GAAyB1tB,KAAK2qB,SAGhDuD,EAAanlB,UAAUmkB,OAAO,aAAcoD,GAC5CnC,EAAWplB,UAAUmkB,OAAO,cAAeoD,GAC3CjD,EAActkB,UAAUmkB,OAAO,cAAeoD,GAG9CrkB,EAAOlD,UAAUmkB,OAAO,eAAgBoD,GAGxC,MAAMC,eAAiB,CAAC5F,EAAU6F,EAAWtD,KAC3CvC,EAAStR,SAAQ1P,GAAWA,EAAQZ,UAAUmkB,OAAOsD,EAAWtD,IAAQ,EAIpEuD,EAAeH,GAAe7wB,MAAMC,WAAW,uBAQrD,GAPA6wB,eAAe3C,EAAmB,cAAe6C,GACjDF,eAAe1C,EAAsB,cAAe4C,GACpDF,eAAezC,EAAoB,cAAe2C,GAElDF,eAAe5C,EAAgB,gBAAiB2C,GAChDC,eAAe7C,EAAsB,gBAAiB4C,GAElDA,EAEFC,eAAe9C,EAAa,cAAe6C,GAC3CC,eAAejD,EAAkB,cAAegD,GAChDC,eAAenD,EAAgB,cAAekD,GAC9CC,eAAe7C,EAAsB,cAAe4C,OAC/C,CAEL,MAAMI,YAAc/F,IAClBA,EAAStR,SAAQ1P,IACf,MAAM4P,EAAa5P,EAAQ6Y,iBAAiB,eAAetb,OAAS,EAC/DqS,GAAY5P,EAAQZ,UAAUS,IAAI,aAAa,GACpD,EAGJknB,YAAYtD,GACZsD,YAAYjD,GACZiD,YAAYpD,GAEZI,EAAqBrU,SAAQ1P,IAC3B,MAAM4S,EAAe5S,EAAQrH,QAAQ,iBACG,UAApCia,EAAaC,SAASvG,WACxBtM,EAAQZ,UAAUS,IAAI,aACvB,GAEJ,CAEDxJ,KAAK+sB,WAAauD,EAClBtwB,MAAKqsB,EAA4BiE,GACjCtwB,MAAK4sB,EAAsB0D,GAC3BtwB,MAAK2wB,GAAqBL,GAE1B5V,MAAM0E,QAAQ,gCAAiCkR,EAAatwB,KAAKiS,WAClE,CASD,GAAA0e,CAAqB9D,GACnB,MAAME,EAAaF,GAAsB7sB,KAAK+sB,WACxC6D,EAAe,+FACjB7D,EACF/sB,KAAK2J,QAAQ6Y,iBAAiB,kBAAkBnJ,SAAQ8J,IAClDA,EAAG0N,QAAQD,KACfzN,EAAG2N,aAAa,wBAAyB3N,EAAG4N,aAAa,iBACzD5N,EAAG6N,gBAAgB,gBAAe,IAGpChxB,KAAK2J,QAAQ6Y,iBAAiB,2BAA2BnJ,SAAQ8J,IAC/DA,EAAG2N,aAAa,eAAgB3N,EAAG4N,aAAa,0BAChD5N,EAAG6N,gBAAgB,wBAAwB,GAGhD,CAUD,iBAAO9F,CAAW9oB,GAChBpC,KAAKixB,eAGL7uB,EAAM8uB,cAAcC,OAEC,IAAjB/uB,EAAM+Y,OAKN1b,MAAMC,WAAW,sBACnBM,KAAKsuB,YAAYlsB,GALZpC,KAAK+sB,YAAY/sB,KAAKoxB,iBAAiBhvB,EAO/C,CAQD,oBAAOgpB,CAAchpB,GACnB,GAAqB,IAAjBA,EAAM+Y,OAER,YADKnb,KAAK+sB,YAAY/sB,KAAKoxB,iBAAiBhvB,IAI9C,GAAIpC,KAAK+sB,WAAY,OAErB,MAAM91B,EAAQwI,MAAM0C,uBAAuBC,GACV,QAA7BnL,EAAMulB,SAASpQ,UACjBpM,KAAKsuB,YAAYlsB,EAAOnL,GAExB+I,KAAKqxB,uBAAuBjvB,EAE/B,CASD,WAAAksB,CAAYlsB,EAAQ,KAAMnL,EAAQ,MAChCA,EAAQA,GAASwI,MAAM0C,uBAAuBC,GAC9C,MAAMkvB,EAASr6B,EAAM8R,UAAUC,SAAS,SAClCuoB,GAAcD,EACpB,KAAKA,GAA0B,iBAAhBlvB,GAAO5I,OAA8B83B,GAA0B,iBAAhBlvB,GAAO5I,MAArE,CAEA,GADAvC,EAAM8R,UAAUmkB,OAAO,QAASqE,GAC5BA,EAAY,CACdvxB,MAAKwxB,GAAmBv6B,GACxB,MAAMw6B,EAAe,IAAIjM,aAAaxlB,KAAMA,KAAKiS,YACjDwf,EAAa7L,YAAY3uB,GAEzB+I,KAAK6qB,WAAWrhB,IAAIvS,EAAM8K,GAChC,MACM/B,KAAK6qB,WAAWvG,OAAOrtB,EAAM8K,IAG3BK,GAAOA,EAAM8uB,cAAcC,MAZuE,CAavG,CASD,GAAAK,CAAmBE,GACZ1xB,KAAK6qB,WAAW+E,MAErB5vB,KAAK6qB,WAAWxR,SAAQlN,IACtB,GAAIA,IAAYulB,EAAc3vB,GAAI,OAClC,MAAM9K,EAAQ+I,KAAK2J,QAAQf,cAAc,IAAIuD,KAE7C,IAAKlV,EAEH,YADA+I,KAAK6qB,WAAWvG,OAAOnY,GAGzB,MAAMwlB,EAAmB16B,EAAM2R,cAAc,IAAI8oB,EAAc3vB,MAC1D4vB,GAAkB3xB,KAAKsuB,YAAY,KAAMr3B,EAAM,GAEvD,CAQD,sBAAAo6B,CAAuBjvB,GACrB,IAAK3C,MAAMC,WAAW,wBAAyB,OAE/C,MAAM2C,EAASD,EAAMC,OAAOC,QAAQ,mCAE9Bia,EAAe9c,MAAM0C,uBAAuBC,GAC5CoK,EAAS+P,GAAcC,SAAShQ,OAChColB,EAAevvB,EAAOC,QAAQ,4BAA8BD,EAAOC,QAAQ,uBAC3EuvB,EAAgBtV,GAAc3T,cAAc,2BAC5C9P,EAAeuJ,EAAOuG,cAAc,sBACpC7P,EAAasJ,EAAOuG,cAAc,oBAClCkpB,EAAevV,EAAa3T,cAAc,mBAE1CmpB,sBAAwB,KAC5BF,GAAe9oB,UAAUmkB,OAAO,cAChCp0B,GAAciQ,UAAUmkB,OAAO,cAC/Bn0B,GAAYgQ,UAAUmkB,OAAO,cAC7B4E,GAAc/oB,UAAUmkB,OAAO,aAAa,EAGxC9V,kBAAoBuJ,IACpBlhB,MAAMC,WAAW,wBACnBM,KAAKiS,WAAWC,aAAakF,kBAAkB,CAAE5K,SAAQpV,SAAU,CAAEupB,aACtE,EAGH,GAAIkR,GAAe9oB,UAAUC,SAAS,cAAe,CACnD+oB,wBACA3a,mBAAkB,GAClB,MAAMqa,EAAe,IAAIjM,aAAaxlB,KAAMA,KAAKiS,YACjDwf,EAAa7L,YAAYgM,EAC/B,MACMG,wBACA3a,mBAAkB,EAErB,CAQD,gBAAAga,CAAiBhvB,GACfpC,KAAKiS,WAAWoI,eAAe,aAAcjY,EAC9C,CAQD,gBAAAkd,CAAiB0S,GACf,MAAM/6B,EAAQ+6B,GAAgB1vB,QAAQ,2BACjC0vB,GAAgB1vB,QAAQ,uBAC7B,IAAKrL,EAAO,OACZ,MAAMuV,OAAEA,EAAMD,MAAEA,EAAK/S,KAAEA,GAASvC,EAAMulB,QACtC,IAAKhQ,EAAQ,OACb,MAAMnU,EAAO2H,KAAKiS,WAAWC,aAAajG,OAAOO,IAASnU,KACpD45B,EAAcpC,SAAStjB,EAAO,KAAO,KAEvB,IAAhB0lB,EACFhT,cAAcK,iBACZtf,KAAKiS,WAAWC,aAChB,CAAE1F,SAAQnU,OAAMkU,MAAO0lB,EAAaz4B,SAGtCylB,cAAcyB,oBACZ1gB,KAAKiS,WAAWC,aAChBlS,KAAKiS,WAAWE,cAChB,CAAE3F,SAAQnU,OAAMkU,MAAO0lB,EAAaz4B,QAGzC,CAWD,GAAA04B,GACE,MAAO,CACL,CACEv1B,MAAO,sCACPC,KAAM,uCACN+b,QAAStW,IAAsD,IAA5CrC,MAAKmyB,GAA2B9vB,GACnD+vB,QAAS,CAAChwB,EAAOC,IAAWrC,MAAKqyB,GAAuBhwB,IAE1D,CACE1F,MAAO,oCACPC,KAAM,yCACN+b,QAAStW,IAAsD,IAA5CrC,MAAKmyB,GAA2B9vB,GACnD+vB,QAAS,CAAChwB,EAAOC,IAAWrC,MAAKqyB,GAAuBhwB,IAE1D,CACE1F,MAAO,kCACPC,KAAM,4CACNw1B,QAAS,CAAChwB,EAAOC,IAAWrC,KAAKsf,iBAAiBjd,IAEpD,CACE1F,MAAO,oCACPC,KAAM,oCACNK,QAAS,qBACTm1B,QAAS,CAAChwB,EAAOC,IAAWrC,MAAKsyB,GAAoBjwB,IAG1D,CAUD,GAAAkwB,CAA2BlwB,GACzB,OAAOA,GAAQC,UAAU,2BAA+B,IACzD,CAUD,GAAA6vB,CAA2B9vB,GACzB,MAAMmwB,EAAKxyB,MAAKuyB,GAA2BlwB,GAC3C,IAAKmwB,EAAI,OAAO,KAChB,GAA6B,QAAzBA,EAAGhW,QAAQpQ,UACb,OAAOomB,EAAGzpB,UAAUC,SAAS,SAG/B,MAAMypB,EAAQD,EAAG5pB,cAAc,yDAC/B,OAAK6pB,GACGA,EAAM1pB,UAAUC,SAAS,cADd,IAEpB,CASD,GAAAqpB,CAAuBhwB,GACrB,MAAMmwB,EAAKxyB,MAAKuyB,GAA2BlwB,GAC3C,IAAKmwB,EAAI,OACT,GAA6B,QAAzBA,EAAGhW,QAAQpQ,UAEb,YADApM,KAAKsuB,YAAY,KAAMkE,GAGzB,MAAM9sB,EAAQ8sB,EAAG5pB,cAAc,iEAC3BlD,GAAO1F,KAAKqxB,uBAAuB,CAAEhvB,OAAQqD,GAClD,CAID,GAAAgtB,GACE,MAAO,CACL,CACE/1B,MAAO,oCACPC,KAAM,oCACNK,QAAS,qBACT0b,QAAS,IAAM3Y,KAAK+sB,WACpBqF,QAAS,CAAChwB,EAAOC,IAAWrC,MAAK2yB,GAAqBtwB,IAG3D,CAQD,EAAAsqB,GACE,MAAMiG,EAAcvxB,QAAQiM,aAAaulB,GAAGD,YAAYnlB,eAClDqlB,EAAgB,CAAEC,OAAO,EAAMC,UAAW,YAAaC,QAAQ,GAE/DC,EAAalzB,MAAKkyB,KACxBxX,MAAM0E,QAAQ,qCAAsC8T,EAAYlzB,KAAKiS,YAErE,MAAMkhB,EAAcnzB,MAAK0yB,KACzBhY,MAAM0E,QAAQ,sCAAuC+T,EAAanzB,KAAKiS,YAEvEjS,KAAKivB,kBAAoB,IAAI2D,EAC3B5yB,KAAK2J,QACL,qFACA3J,MAAKozB,GAAyBF,GAC9BJ,GAGF9yB,KAAK+uB,mBAAqB,IAAI6D,EAC5B5yB,KAAK2J,QACL,6BACA3J,MAAKozB,GAAyBD,GAC9BL,EAEH,CAUD,GAAAM,CAAyB1vB,GACvB,OAAIrC,QAAQC,MAAMwH,eAAexJ,KAAKsG,QAAS,UAAkBlC,EAG1DA,EAAMjB,KAAI4wB,IACf,MAAMC,EAAM,IAAKD,GAUjB,OATIA,EAAK12B,QAAU02B,EAAKh7B,OAAMi7B,EAAIj7B,KAAOg7B,EAAK12B,OAC1C02B,EAAKjB,UAAYiB,EAAKjW,WACxBkW,EAAIlW,SAAW,CAAC/a,EAAQD,IAAUixB,EAAKjB,QAAQhwB,EAAOC,SAEnCkxB,IAAjBF,EAAK1a,cAA4C4a,IAAnBF,EAAKG,YACrCF,EAAIE,UAAoC,mBAAjBH,EAAK1a,QACxBtW,GAAUgxB,EAAK1a,QAAQtW,GACvBgxB,EAAK1a,SAEJ2a,CAAG,GAEb,CASD,QAAMhB,CAAoBN,GACxB,MAAMyB,EAAUzB,GAAgB1vB,QAAQ,2BACnC0vB,GAAgB1vB,QAAQ,uBAC7B,IAAKmxB,EAAS,OACd,MAAMjnB,EAASinB,EAAQjX,QAAQhQ,OACzBylB,EAAcpC,SAAS4D,EAAQjX,QAAQjQ,MAAO,KAAO,EACrDlU,EAAO2H,KAAKiS,WAAWC,aAAajG,OAAOO,IAASnU,MAAQ,GAC5Dq7B,QAAkBryB,QAAQiM,aAAawP,IAAIC,SAASC,QAAQ,CAChEC,OAAQ,CAAEvX,MAAOpG,KAAKwF,KAAKE,SAAS,wCACpC8O,QAAS,MAAMxU,KAAKwF,KAAKorB,OAAO,wCAAyC,CAAE73B,eAC3E6kB,OAAO,IAEJwW,SACCzU,cAAc4B,YAAY7gB,KAAKiS,WAAWC,aAAc,CAAE1F,SAAQD,MAAO0lB,GAChF,CASD,QAAMU,CAAqBX,GACzB,MAAM7W,EAAS6W,GAAgB1vB,QAAQ,8BACjCqxB,EAAa3B,GAAgB1vB,QAAQ,0BAC3C,IAAK6Y,IAAWwY,EAAY,OAC5B,MAAMjX,EAAWvB,EAAOqB,QAAQE,SAC1BlQ,EAASmnB,EAAWnX,QAAQhQ,OAC5BnU,EAAO8iB,EAAOvS,cAAc,qBAAqBgb,aAAanE,QAAU,GACxEiU,QAAkBryB,QAAQiM,aAAawP,IAAIC,SAASC,QAAQ,CAChEC,OAAQ,CAAEvX,MAAOpG,KAAKwF,KAAKE,SAAS,wCACpC8O,QAAS,MAAMxU,KAAKwF,KAAKorB,OAAO,wCAAyC,CAAE73B,eAC3E6kB,OAAO,IAEJwW,SACCzU,cAAcgC,aAClBjhB,KAAKiS,WAAWC,aAChBlS,KAAKiS,WAAWE,cAChB,CAAE3F,SAAQkQ,YAEb,CAYD,EAAAkQ,CAAsBC,GACpB,MAAME,EAAaF,GAAsB7sB,KAAK+sB,WACxC6G,EAAU7G,GAActtB,MAAMC,WAAW,uBACzCm0B,MAAQ1Q,IACRyQ,EAASzQ,EAAG2N,aAAa,YAAa,QACrC3N,EAAG6N,gBAAgB,YAAY,EAEtChxB,KAAK2qB,UAAU6C,UAAUnU,QAAQwa,OACjC7zB,KAAK2qB,UAAU8C,aAAapU,QAAQwa,OACpC7zB,KAAK2qB,UAAUwC,WAAW9T,QAAQwa,MACnC,CAUD,GAAAC,CAAkB9P,GAChB,MAAM+P,EAAO/P,EAAG3hB,OAAOC,UAAU,qEACjC,OAAKyxB,GACAA,EAAKC,aAAa,aAChBD,EAFW,IAGnB,CAUD,GAAAE,CAAmBC,GACjB,MAAMC,EAASD,GAAQE,cACvB,OAAKD,EACE3pB,MAAMC,KAAK0pB,EAAOviB,UACtBxI,QAAO+Z,GAA2B,WAArBA,EAAG3G,SAAShW,MAAqB2c,IAAO+Q,IAFpC,EAGrB,CAYD,GAAAG,CAA0BH,EAAQI,EAASC,GACzC,MAAMzT,EAAW9gB,MAAKi0B,GAAmBC,GACzC,IAAIM,EAAU,KACVC,EAAUC,IACd,IAAK,MAAMvK,KAAWrJ,EAAU,CAC9B,MAAMgE,EAAOqF,EAAQpF,wBACf4P,EAAK7P,EAAK3C,KAAQ2C,EAAK1G,MAAQ,EAC/BwW,EAAK9P,EAAKzC,IAAOyC,EAAKzG,OAAS,EAC/BwW,EAAI7tB,KAAK8tB,MAAMR,EAAUK,EAAIJ,EAAUK,GACzCC,EAAIJ,IAAWA,EAAUI,EAAGL,EAAUrK,EAC3C,CACD,OAAOqK,CACR,CAUD,GAAAO,CAAyBb,GACvB,IAAKA,EAAQ,MAAO,GACpB,GAA4B,UAAxBA,EAAO1X,QAAQhW,KACjB,OAAOgE,MAAMC,KAAKzK,KAAK2J,QAAQ6Y,iBAAiB,iCAGlD,MAAMwS,EAAcnF,SAASqE,EAAO1X,QAAQjQ,MAAO,IAC7CiY,EAAcwQ,EAAc,EAC5BjgB,GAAgBmf,EAAO1X,QAAQhQ,QAAU,IAAIlB,MAAM,KAAK7D,MAAM,GAAI,GAAGb,KAAK,KAC1EkH,EAAM9N,KAAK2J,QAAQ6Y,iBAAiB,mCAC1C,OAAOhY,MAAMC,KAAKqD,GAAK1E,QAAO6rB,GAC5BA,EAAIzY,QAAQzH,eAAiBA,GAC1BkgB,EAAIzY,QAAQgI,cAAgB/qB,OAAO+qB,IAEzC,CAYD,GAAA0Q,CAAuBhB,EAAQI,EAASC,GACtC,MAAMY,EAAUn1B,MAAK+0B,GAAyBb,GAC9C,IAAIM,EAAU,KACVC,EAAUC,IACd,IAAK,MAAMO,KAAOE,EAAS,CACzB,MAAMrQ,EAAOmQ,EAAIlQ,wBACX4P,EAAK7P,EAAK3C,KAAQ2C,EAAK1G,MAAQ,EAC/BwW,EAAK9P,EAAKzC,IAAOyC,EAAKzG,OAAS,EAC/BwW,EAAI7tB,KAAK8tB,MAAMR,EAAUK,EAAIJ,EAAUK,GACzCC,EAAIJ,IAAWA,EAAUI,EAAGL,EAAUS,EAC3C,CACD,OAAOT,CACR,CAID,EAAAtF,CAAalL,GACX,MAAMkQ,EAASl0B,MAAK8zB,GAAkB9P,GACtC,GAAKkQ,EAAL,CAEA,GADAlQ,EAAGoR,kBACyB,WAAxBlB,EAAO1X,QAAQhW,KAAmB,CACpC,MAAM6uB,EAAiBnB,EAAO5xB,QAAQ,0BAChCqsB,EAAeuF,EAAOtrB,cAAc,8BAC1C5I,KAAKs1B,WAAa,CAChB9uB,KAAM,SACNkW,SAAUiS,GAAcnS,QAAQE,SAChC3H,aAAcsgB,GAAgB7Y,QAAQhQ,OAE9C,MACMxM,KAAKs1B,WAAa,CAChB9uB,KAAM0tB,EAAO1X,QAAQhW,KACrBgG,OAAQ0nB,EAAO1X,QAAQhQ,OACvBD,MAAOsjB,SAASqE,EAAO1X,QAAQjQ,MAAO,KAAO,GAKjD,GAFA2nB,EAAOnrB,UAAUS,IAAI,gBACrBxJ,KAAK2qB,SAAS1e,QAAQlD,UAAUS,IAAI,mBAChCwa,EAAGuR,aAAc,CACnBvR,EAAGuR,aAAaC,cAAgB,OAChC,IAAMxR,EAAGuR,aAAaE,QAAQ,aAAcvB,EAAO1X,QAAQhQ,OAAU,CAAC,MAAQ,CAC9E,MAAMkpB,EAAmB/sB,SAASgtB,cAAc,OAChDD,EAAiBE,IAAM,iFACvB5R,EAAGuR,aAAaM,aAAaH,EAAkB,EAAG,EACnD,CAzBmB,CA0BrB,CAID,EAAAvG,CAAanL,GACNhkB,KAAKs1B,aACVtR,EAAGC,iBACCD,EAAGuR,eAAcvR,EAAGuR,aAAaO,WAAa,QACnD,CAID,EAAA1G,CAAYpL,GACV,IAAKhkB,KAAKs1B,WAAY,OAItB,GAFAtR,EAAGC,iBACHD,EAAGuR,aAAaO,WAAa,OACA,WAAzB91B,KAAKs1B,WAAW9uB,KAElB,YADAxG,MAAK+1B,GAAkB/R,GAGzB,MAAMkQ,EAASl0B,KAAK2J,QAAQf,cAAc,kBAAkBotB,IAAIC,OAAOj2B,KAAKs1B,WAAW9oB,aACvF,IAAK0nB,EAAQ,OACb,MAAMgC,EAAOl2B,MAAKk1B,GAAuBhB,EAAQlQ,EAAGsQ,QAAStQ,EAAGuQ,SAC3D2B,IACLl2B,MAAKm2B,KACLD,EAAKntB,UAAUS,IAAI,sBACpB,CAID,GAAAusB,CAAkB/R,GAChB,MAAMkQ,EAASl0B,MAAKo2B,KACpB,IAAKlC,EAAQ,OACb,MAAM7xB,EAASrC,MAAKq0B,GAA0BH,EAAQlQ,EAAGsQ,QAAStQ,EAAGuQ,SACrE,IAAKlyB,EAAQ,OACb,MAAMyiB,EAAOziB,EAAO0iB,wBACdsR,EAASr2B,KAAKrH,SAChBqrB,EAAGuQ,QAAUzP,EAAKzC,IAAOyC,EAAKzG,OAAS,EACvC2F,EAAGsQ,QAAUxP,EAAK3C,KAAQ2C,EAAK1G,MAAQ,EAC3Cpe,MAAKm2B,KACL9zB,EAAO0G,UAAUS,IAAI6sB,EAAS,yBAA2B,wBAC1D,CASD,GAAAD,GACE,MAAM1Z,SAAEA,EAAQ3H,aAAEA,GAAiB/U,KAAKs1B,YAAc,CAAA,EACtD,IAAK5Y,IAAa3H,EAAc,OAAO,KACvC,MAAMof,EAASn0B,KAAK2J,QAAQf,cAC1B,wCAAwCotB,IAAIC,OAAOlhB,QAErD,IAAKof,EAAQ,OAAO,KACpB,MAAMhZ,EAASgZ,EAAOvrB,cAAc,oBAAoBotB,IAAIC,OAAOvZ,QACnE,OAAOvB,GAAQ7Y,QAAQ,yBAA6B,IACrD,CAID,EAAA+sB,CAAarL,GACNA,EAAGsS,eAAkBt2B,KAAK2J,QAAQX,SAASgb,EAAGsS,gBACjDt2B,MAAKm2B,IAER,CAID,OAAM7G,CAAQtL,GACZ,IAAKhkB,KAAKs1B,WAAY,OACtB,GAA6B,WAAzBt1B,KAAKs1B,WAAW9uB,KAElB,kBADMxG,MAAKu2B,GAAcvS,GAG3B,MAAMkQ,EAASl0B,KAAK2J,QAAQf,cAAc,kBAAkBotB,IAAIC,OAAOj2B,KAAKs1B,WAAW9oB,aACvF,IAAK0nB,EAAQ,OACb,MAAMgC,EAAOl2B,MAAKk1B,GAAuBhB,EAAQlQ,EAAGsQ,QAAStQ,EAAGuQ,SAChE,IAAK2B,EAAM,OACXlS,EAAGC,iBACHD,EAAGoR,kBAEH,MAAMjX,EAAW0R,SAASqG,EAAK1Z,QAAQ2B,SAAU,KAAO,EACxDne,MAAKm2B,WAECn2B,MAAKw2B,GAAwB,CACjCjqB,MAAOvM,KAAKs1B,WAAW/oB,MACvBkqB,aAAcz2B,KAAKs1B,WAAW9oB,OAC9B2R,YAEH,CAID,QAAMoY,CAAcvS,GAClB,MAAMkQ,EAASl0B,MAAKo2B,KACpB,IAAKlC,EAAQ,OACb,MAAM7xB,EAASrC,MAAKq0B,GAA0BH,EAAQlQ,EAAGsQ,QAAStQ,EAAGuQ,SACrE,IAAKlyB,EAAQ,OACb2hB,EAAGC,iBACHD,EAAGoR,kBACH,MAAMsB,EAAar0B,EAAO0G,UAAUC,SAAS,0BAC7ChJ,MAAKm2B,KACL,MAAMQ,EAAet0B,EAAOuG,cAAc,8BACpCguB,EAAiBD,GAAcna,QAAQE,SACxCka,SACC52B,MAAK62B,GAAyB,CAClC9hB,aAAc/U,KAAKs1B,WAAWvgB,aAC9B+hB,eAAgB92B,KAAKs1B,WAAW5Y,SAChCka,iBACAF,cAEH,CAaD,QAAMG,EAAyB9hB,aAAEA,EAAY+hB,eAAEA,EAAcF,eAAEA,EAAcF,WAAEA,IAC7E,MAAMxkB,EAAelS,KAAKiS,WAAWC,aAC/BC,EAAgBnS,KAAKiS,WAAWE,cAChClb,EAAQib,EAAaqD,SAAS,CAAE/I,OAAQuI,IAC9C,IAAK9d,EAAO,OACZ,MAAMqe,EAAUre,EAAMqe,QAAQlM,QAAO/B,GAAKA,EAAEyN,WAAUrN,QAChDsvB,EAAOzhB,EAAQ0hB,WAAU3vB,GAAKA,EAAEtF,KAAO+0B,IAC7C,GAAIC,EAAO,EAAG,OACd,MAAOE,GAAS3hB,EAAQnI,OAAO4pB,EAAM,GACrC,IAAIG,EAAO5hB,EAAQ0hB,WAAU3vB,GAAKA,EAAEtF,KAAO60B,IAC3C,GAAIM,EAAO,EAAG,OACTR,IAAYQ,GAAQ,GACzB5hB,EAAQnI,OAAO+pB,EAAM,EAAGD,GACxB,MAAME,EAAU7hB,EAAQ7S,KAAI4E,IAAM,CAAEtF,GAAIsF,EAAEtF,GAAI4U,SAAUtP,EAAEsP,SAAUte,KAAMgP,EAAEhP,KAAMmB,KAAM6N,EAAE7N,SAC1F2Y,EAAcgP,cAAcgW,EAAS,CAAE3qB,OAAQuI,UACzC7C,EAAamF,WAAW,CAAEC,WAAW,EAAMC,UAAU,IAC3DmD,MAAM0E,QAAQ,4BACf,CAID,EAAAmQ,GACEvvB,MAAKm2B,KACLn2B,KAAK2qB,SAAS1e,QAAQlD,UAAUQ,OAAO,mBACvCvJ,KAAK2J,QAAQ6Y,iBAAiB,iBAAiBnJ,SAAQ8J,GAAMA,EAAGpa,UAAUQ,OAAO,kBACjFvJ,KAAKs1B,WAAa,IACnB,CAID,GAAAa,GACEn2B,KAAK2J,QAAQ6Y,iBAAiB,wEAC3BnJ,SAAQ8J,GAAMA,EAAGpa,UAAUQ,OAAO,qBAAsB,yBAA0B,0BACtF,CAYD,QAAMitB,EAAwBjqB,MAAEA,EAAKkqB,aAAEA,EAAYtY,SAAEA,IACnD,MAAMjM,EAAelS,KAAKiS,WAAWC,aAErC,GAAc,IAAV3F,EAAa,CACf,MAAMuU,EAAWlX,OAAOG,OAAOmI,EAAajG,QACzC7C,QAAO+W,GAAiB,IAAZA,EAAE5T,OAAe4T,EAAErL,WAC/B1N,MAAK,CAACC,EAAGC,IAAMD,EAAE6E,MAAQ5E,EAAE4E,QACxB6qB,EAAOjW,EAASkW,WAAU7W,GAAKA,EAAE3T,SAAWiqB,IAClD,GAAIM,EAAO,EAAG,OACd,MAAOE,GAASnW,EAAS3T,OAAO4pB,EAAM,GAEhC10B,EAAS00B,EAAO5Y,EAAWA,EAAW,EAAIA,EAC1CiZ,EAAUpwB,KAAKuZ,IAAI,EAAGvZ,KAAKwZ,IAAIne,EAAQye,EAAS5Z,SACtD,GAAIkwB,IAAYL,EAAM,OACtBjW,EAAS3T,OAAOiqB,EAAS,EAAGH,GAC5B,MAAME,EAAUrW,EAASre,KAAI0d,IAAM,CAAEpe,GAAIoe,EAAEpe,GAAI4U,SAAUwJ,EAAExJ,SAAUte,KAAM8nB,EAAE9nB,KAAMmB,KAAM2mB,EAAE3mB,eACrF0Y,EAAa4E,aAAaqgB,EAAS,CAAE5qB,MAAO,GACxD,KAAW,CACL,MAAMwI,EAAe0hB,EAAanrB,MAAM,KAAK7D,MAAM,GAAI,GAAGb,KAAK,KACzDoQ,EAAkB9E,EAAaqD,SAAS,CAAE/I,OAAQuI,IACxD,IAAKiC,EAAiB,OACtB,MAAM+J,EAAcnX,OAAOG,OAAOmI,EAAajG,QAC5C7C,QAAO+W,GAAKA,EAAE3T,OAAOiJ,WAAW,GAAGV,OAAoBoL,EAAE5T,QAAUA,GAAS4T,EAAErL,WAC9E1N,MAAK,CAACC,EAAGC,IAAMD,EAAE6E,MAAQ5E,EAAE4E,QAIxB+I,EAAQ8L,EAAY3X,QAAO+W,GAA2B,QAAtBA,EAAE/oB,UAAUmH,QAC5C2W,EAAO6L,EAAY3X,QAAO+W,GAA2B,QAAtBA,EAAE/oB,UAAUmH,QAC3Cw4B,EAAO9hB,EAAM+hB,WAAU7W,GAAKA,EAAE3T,SAAWiqB,IAC/C,GAAIM,EAAO,EAAG,OACd,MAAOE,GAAShiB,EAAM9H,OAAO4pB,EAAM,GAC7B10B,EAAS00B,EAAO5Y,EAAWA,EAAW,EAAIA,EAC1CiZ,EAAUpwB,KAAKuZ,IAAI,EAAGvZ,KAAKwZ,IAAIne,EAAQ4S,EAAM/N,SACnD,GAAIkwB,IAAYL,EAAM,OACtB9hB,EAAM9H,OAAOiqB,EAAS,EAAGH,GAEzB,MAAMI,EAAcpiB,EAAMxS,KAAI0d,IAAM,CAAEpe,GAAIoe,EAAEpe,GAAI4U,SAAUwJ,EAAExJ,SAAUte,KAAM8nB,EAAE9nB,KAAMmB,KAAM2mB,EAAE3mB,SACtF89B,EAAapiB,EAAKzS,KAAI0d,IAAM,CAAEpe,GAAIoe,EAAEpe,GAAI4U,SAAUwJ,EAAExJ,SAAUte,KAAM8nB,EAAE9nB,KAAMmB,KAAM2mB,EAAE3mB,eACpF0Y,EAAa4E,aAAa,IAAIugB,KAAgBC,GAAatgB,EAClE,OAEK9E,EAAamF,WAAW,CAAEC,WAAW,EAAMC,UAAU,IAC3DmD,MAAM0E,QAAQ,4BACf,CAUD,kBAAOiM,CAAYjpB,GAGjB,GAFAA,EAAM6hB,iBAEFjkB,KAAK+sB,WACP3qB,EAAM8uB,eAAeC,aADvB,CAKA,GAAqB,IAAjB/uB,EAAM+Y,OAAc,CACtB,MAAMA,EAAS/Y,EAAMC,QAAQC,UAAU,8BACvC,GAAwC,SAApC6Y,GAAQqB,SAASsS,eAEnB,YADA3T,EAAOgW,QAGV,CAEDnxB,KAAKiS,WAAWoI,eAAe,cAAejY,GAC9CA,EAAM8uB,eAAeC,QAXpB,CAYF,CAQD,iBAAAzC,CAAkBtsB,GAChBpC,KAAKiS,WAAWoI,eAAe,cAAejY,EAC/C,CAWD,EAAAosB,CAAWpsB,GACT,IAAKpC,KAAKgtB,YAAa,OAGvB,MAAMrjB,EAAU3J,KAAK2J,QAEf2qB,EAAUlyB,EAAMkyB,SAAWlyB,EAAMm1B,eAAe,GAAGjD,QACnDC,EAAUnyB,EAAMmyB,SAAWnyB,EAAMm1B,eAAe,GAAGhD,QAGzD,IAAIiD,EAAO,EACPC,EAAO,EACPC,EAAOpD,EACPqD,EAAOpD,EACX,MAAMqD,EAAqBjuB,EAAQkuB,UAC7BC,EAAsBnuB,EAAQouB,WACpC,IAAIC,EAAgBJ,EAChBK,EAAiBH,EAMrB,MAAMI,eAAiB91B,IACrB,MAAMkyB,EAAUlyB,EAAMkyB,SAAWlyB,EAAMm1B,eAAe,GAAGjD,QACnDC,EAAUnyB,EAAMmyB,SAAWnyB,EAAMm1B,eAAe,GAAGhD,QACzDiD,EAAOE,EAAOpD,EACdmD,EAAOE,EAAOpD,EACdmD,EAAOpD,EACPqD,EAAOpD,EAGHiD,IAASE,GAAQD,IAASE,IAE9BK,GAAgCP,EAChCQ,GAAkCT,EAElCx3B,KAAKm4B,OAASH,EAGdrO,uBAAsB,KACpB/f,OAAO6C,OAAO9C,EAAQpL,MAAO,CAAE4jB,KAAM,GAAG8V,MAAoB5V,IAAK,GAAG2V,OAAoB,IACxF,EAQEI,aAAe,KAEnBzvB,SAAS0vB,YAAc,KACvB1uB,EAAQ2uB,YAAc,KAGtB3vB,SAAS4vB,UAAY,KACrB5uB,EAAQ6uB,WAAa,KAGjBR,IAAkBJ,GAAsBK,IAAmBH,IAE/D93B,KAAKm4B,OAASH,EAEdh4B,MAAK0vB,KAGL1vB,KAAKy4B,YAAc,CAAEpW,IAAK2V,EAAe7V,KAAM8V,GAAgB,EAIjEtvB,SAAS0vB,YAAcH,eACvBvuB,EAAQ2uB,YAAcJ,eAGtBvvB,SAAS4vB,UAAYH,aACrBzuB,EAAQ6uB,WAAaJ,YACtB,CAUD,WAAAhM,GACOpsB,KAAKiS,WAAW/a,MACjB8I,KAAKrH,SACPqH,MAAK04B,KAEL14B,MAAK24B,KAER,CAOD,GAAAD,GACE14B,KAAK2J,QAAQpL,MAAM8jB,IAAM,EACzBriB,KAAK2J,QAAQpL,MAAM4jB,KAAO,EAE1B,MAAMyW,EAAmBjwB,SAASC,cAAc,cAC1ChQ,EAAeoH,KAAKkT,cAAca,OAAO/T,KAAKR,QAAQjB,QAAQ3F,aAC9DigC,EAAQx3B,QAAQC,MAAMwH,eAAexJ,KAAKsG,QAAS,UAEzD,OAAQhN,GACN,IAAK,QACH,GAAIigC,EAAO,CACT,MAAMC,EAAiBnwB,SAASC,cAAc,YAC9CkwB,EAAeC,QAAQ/4B,KAAK2J,QACtC,MACUivB,EAAiBI,YAAYh5B,KAAK2J,SAEpC,MACF,IAAK,eACH,MAAMsvB,EAAiBL,EAAiBhwB,cAAc,aAClDiwB,EACFI,EAAeF,QAAQ/4B,KAAK2J,SAE5BivB,EAAiBM,aAAal5B,KAAK2J,QAASsvB,GAE9C,MACF,IAAK,OACH,MAAME,EAAgBP,EAAiBhwB,cAAc,YACjDiwB,EACFM,EAAcJ,QAAQ/4B,KAAK2J,SAE3BivB,EAAiBM,aAAal5B,KAAK2J,QAASwvB,GAInD,CAOD,GAAAR,GACEhwB,SAASywB,KAAKJ,YAAYh5B,KAAK2J,SAC/B3J,MAAKq5B,KACLr5B,MAAK0vB,IACN,CAQD,GAAA2J,GACE,OAAKr5B,KAAKy4B,YAMH,IAAIr4B,SAAQC,IACjB,MAAMi5B,MAAQ,KACRt5B,KAAK2J,SACP3J,KAAK2J,QAAQpL,MAAM+jB,OAAS,KAC5BtiB,KAAKm4B,OAASn4B,KAAKy4B,YAAYpW,IAAM,GAAKriB,KAAKy4B,YAAYpW,IAAMpF,OAAO6M,YAAc,EAClFtuB,EAAII,gBACJoE,KAAKy4B,YAAYpW,KAAO7mB,EAAII,gBAChCoE,KAAKu5B,QAAUv5B,KAAKy4B,YAAYtW,KAAO,GAAKniB,KAAKy4B,YAAYtW,KAAOlF,OAAOgM,WAAa,EACpFztB,EAAIG,iBACJqE,KAAKy4B,YAAYtW,MAAQ3mB,EAAIG,iBACjCqE,KAAK2J,QAAQpL,MAAM8jB,IAAM,GAAGriB,KAAKm4B,WACjCn4B,KAAK2J,QAAQpL,MAAM4jB,KAAO,GAAGniB,KAAKu5B,YAClCl5B,KAEAC,WAAWg5B,MAAO,GACnB,EAGHA,OAAO,KAvBPt5B,KAAK2J,QAAQpL,MAAM8jB,IAAM,GAAG7mB,EAAII,yBAChCoE,KAAK2J,QAAQpL,MAAM4jB,KAAO,GAAG3mB,EAAIG,sBAwBpC,CAUD,mBAAM69B,GACJ96B,EAAOnB,MAAM,yBACbyC,KAAKy4B,YAAc,CAAEpW,IAAK7mB,EAAII,gBAAiBumB,KAAM3mB,EAAIG,iBAC1D,CAUD,UAAM89B,CAAKC,EAAYC,SACf35B,MAAK45B,GAAcF,EAAYC,EACtC,CAUD,QAAMC,CAAcF,EAAYC,GAC9B,IAAKr6B,KAAK0E,KAAKoB,KAEb,YADA1G,EAAOC,KAAK,iCAAiC,GAI/C,IAAK+6B,IAAeC,EAAUzyB,OAE5B,YADAxI,EAAOC,KAAK,mCAAmC,GAIjDD,EAAOnB,MAAM,iCAEb,MAAMs8B,QAAkB75B,KAAKsP,YAAYe,YAAY,CAAE7W,KAAM,OAAQuI,GAAI23B,IAEzE,GAAyB,iBAAdC,QACH35B,KAAKsP,YAAYI,aAAa,OAAQiqB,EAAWE,QAClD,GAAIrvB,MAAM6B,QAAQstB,GACvB,IAAK,MAAMjmB,KAAUimB,QACb35B,KAAKsP,YAAYI,aAAa,OAAQgE,EAAQmmB,GAIxDn7B,EAAOnB,MAAM,4BACd,CAOD,kCAAau8B,GACXx6B,MAAMC,gBAAgB1C,aACvB,CAOD,iBAAMA,GACJ6B,EAAOnB,MAAM,6BACPyC,KAAK+5B,wBACX/5B,KAAKw5B,gBACL96B,EAAOnB,MAAM,eACd,CAOD,oBAAMmhB,GACJhgB,EAAOnB,MAAM,iCAEPyC,KAAKsP,YAAYI,aAAa,QAAS1P,KAAKiS,WAAWjQ,MAAMD,GAAI,CAAA,GAEvErD,EAAOnB,MAAM,oBAEbyC,KAAKiS,WAAW8H,eAChB,MAAM3O,EAAU,CAAEA,QAAS,CAAE5R,KAAM,SAAUnB,KAAM,kCACnD2H,KAAK8Y,OAAO1N,EACb,CAQD,uBAAM4uB,GACJt7B,EAAOnB,MAAM,+BAEb,IAAK,MAAMyE,KAAS1C,KAAK2C,OACvBvD,EAAOnB,MAAM,8BAA8ByE,EAAMD,MAAO,CAAEC,gBACpDhC,KAAKsP,YAAYI,aAAa,QAAS1N,EAAMD,GAAI,CAAA,GAGzDrD,EAAOnB,MAAM,wBACbyC,KAAKiS,WAAW8H,eAChB,MAAM3O,EAAU,CAAEA,QAAS,CAAE5R,KAAM,SAAUnB,KAAM,qCACnD2H,KAAK8Y,OAAO1N,EACb,CAQD,mBAAM6uB,GACJv7B,EAAOnB,MAAM,gCACPyC,KAAKsP,YAAYI,aAAa,OAAQpQ,KAAKoU,OAAQ,CAAA,GACzDhV,EAAOnB,MAAM,mBACbyC,KAAKiS,WAAW8H,eAChB,MAAM3O,EAAU,CAAEA,QAAS,CAAE5R,KAAM,SAAUnB,KAAM,iCACnD2H,KAAK8Y,OAAO1N,EACb,CAQD,sBAAM8uB,GACJx7B,EAAOnB,MAAM,8BACb,IAAK,MAAMyG,KAAQ1E,KAAK4F,YAChBlF,KAAKsP,YAAYI,aAAa,OAAQ1L,EAAKjC,GAAI,CAAA,GAEvDrD,EAAOnB,MAAM,uBACbyC,KAAKiS,WAAW8H,eAChB,MAAM3O,EAAU,CAAEA,QAAS,CAAE5R,KAAM,SAAUnB,KAAM,oCACnD2H,KAAK8Y,OAAO1N,EACb,CAOD,2BAAM2uB,GACJr7B,EAAOnB,MAAM,gCACPyC,KAAKsP,YAAYI,aAAa,OAAQpQ,KAAKoU,OAAQ,CAAA,GACzDhV,EAAOnB,MAAM,mBAEbmB,EAAOnB,MAAM,iCACPyC,KAAKsP,YAAYI,aAAa,QAAS1P,KAAKiS,WAAWjQ,MAAMD,GAAI,CAAA,GACvErD,EAAOnB,MAAM,oBAEbyC,KAAKiS,WAAW8H,eAChB,MAAM3O,EAAU,CAAEA,QAAS,CAAE5R,KAAM,SAAUnB,KAAM,yCACnD2H,KAAK8Y,OAAO1N,EACb,CAWD,YAAM0N,CAAO1N,EAAU,MAGrB,GAAsB,wBAAlBA,GAAS/S,KAAgC,CAC3C,IAAK2H,KAAKmsB,sBAAuB,OACjCnsB,KAAKmsB,uBAAwB,EAC7BztB,EAAOnB,MAAM,mBACd,OAEKyC,MAAKm6B,WACLn6B,MAAKo6B,GAAehvB,EAC3B,CAOD,QAAM+uB,GAEAn6B,KAAKq6B,iBAAiBr6B,KAAK8qB,mBAAmB3qB,QAElDH,KAAKq6B,iBAAkB,QACjBr6B,KAAK8qB,mBAAmB5qB,QAC9BF,KAAKq6B,iBAAkB,EAIvB,MAAMC,wBAA0BztB,UAC9B,MAAM0tB,EAAc,IACdC,EAAW,GACXC,EAAaF,EAAcC,EAEjC,IAAIzyB,EAAI,EACR,KAAOA,EAAI0yB,GAAcz6B,KAAK06B,kBACtB16B,KAAK+qB,YAAY7qB,QACvB6H,IAGF,OAAQ/H,KAAK06B,UAAU,EAGzB,GAAI16B,KAAK06B,WAAY,CACnB,MAAMC,QAAqBL,0BACtBK,GACHj8B,EAAOnB,MAAM,oCAEhB,CACF,CAQD,QAAM68B,CAAehvB,GACnBpL,KAAK06B,YAAa,EAClBh8B,EAAOnB,MAAM,kBAAmB6N,GAGhC,MAAMwvB,QAAoB56B,KAAKiS,WAAWrE,KAAKxC,GAC1CwvB,GAKLlgB,MAAM0E,QAAQ,8BAA+Bpf,KAAKiS,WAAW/a,IAAK8I,KAAKiS,YAEvEjS,KAAKyvB,WAAY,EACjBzvB,KAAKqf,OAAO,CAAExD,OAAO,EAAMsC,SAAU,CAAE,IAEvCne,KAAK06B,YAAa,EAElBhgB,MAAM0E,QAAQ,+BAAgC3oB,GAC9CiI,EAAOnB,MAAM,gBAZXyC,MAAK66B,IAaR,CAQD,GAAAA,GACE76B,MAAK8jB,KACLplB,EAAOnB,MAAM,kEACbyC,KAAK06B,YAAa,CACnB,CAQD,QAAAI,GACE96B,MAAK8jB,IACN,CAQD,GAAAA,GACE6F,uBAAsB,KACpB3pB,KAAK2J,SAASZ,WAAWQ,OAAO,gBAChCvJ,KAAK2J,SAASZ,WAAWS,IAAI,aAAa,IAG5CxJ,KAAK6qB,WAAa,IAAI3hB,IACtBlJ,KAAKgrB,WAAa1qB,YAAW,KAC3BN,KAAK8jB,MAAM,CAAEiX,SAAS,GAAQ,GAC7B,IACJ,CAaD,kBAAAC,CAAmBt5B,EAAOtC,EAAO,MAC/B,OAAIA,EAAK67B,QACFj7B,MAAKk7B,GAAiBx5B,IAAWjC,MAAMC,WAAW,kBAAoBgC,EAAMF,UAAYlC,KAAK0E,KAAKD,WAAWhC,GACrH,CAUD,GAAAm5B,CAAiBx5B,GACf,MAAM8Q,EAAmB/S,MAAMmE,sBAC/B,OACE4O,GAAkBrN,MAAKrB,GAAmBA,EAAgB/B,KAAOL,EAAMK,OAChEyQ,GAAkBtL,QAClBvF,QAAQC,QAAQC,YAAYsD,MAAKzD,GAASA,EAAMK,KAAO/B,KAAKiS,WAAWvQ,OAAOK,IAExF,CASD,iBAAAo5B,CAAkBn5B,GAChB,OAAOA,GAAOD,KAAO/B,KAAKiS,WAAWjQ,OAAOD,EAC7C,CAUD,wBAAAq5B,CAAyBp5B,EAAO5C,GAC9B,OAAK4C,EAKDhC,KAAKm7B,kBAAkBn5B,IACzBtD,EAAOnB,MAAM,2BAA4B,CAAEyE,QAAO5C,UAC3C,IAEPV,EAAOnB,MAAM,uCAAwC,CAAEyE,QAAO5C,UACvD,IATPV,EAAOnB,MAAM,yBAA0B,CAAE6B,UAClC,EAUV,CAUD,aAAI5B,GACF,MAAMA,EAAYiC,MAAMC,WAAW,aACnC,MAAkB,OAAdlC,GAAqC,SAAdA,GAAwBwC,KAAKm4B,OAASlb,OAAO6M,YAAc,EAAW,KAC1F,MACR,CAQD,eAAI2O,GACF,OAAOh5B,MAAMkF,YAAY,WAC1B,CAQD,eAAI8zB,CAAY4C,GACd57B,MAAMmF,YAAY,WAAYy2B,GAC9B38B,EAAOnB,MAAM,sBAAsB89B,EAAIhZ,aAAagZ,EAAIlZ,SACzD,CAQD,aAAI8N,GACF,OAAOxwB,MAAMC,WAAW,SACzB,CAED,aAAIuwB,CAAUqL,GACZ77B,MAAM0E,WAAW,SAAUm3B,EAC5B,CAQD,eAAIlN,GACF,OAAO3uB,MAAMkF,YAAY,cAC1B,CAED,eAAIypB,CAAYkN,GACd77B,MAAMmF,YAAY,cAAe02B,EAClC,CAQD,YAAI3iC,GACF,MAAM4F,EAAQyB,KAAKkT,cAAca,OAAO/T,KAAKR,QAAQjB,QAAUyB,KAAKkT,cAAca,OAAO9b,WACzF,OAAOsG,GAAO5F,UAAY4F,GAAO3F,YAClC,CAQD,cAAIm0B,GACF,OAAOttB,MAAMkF,YAAY,aAC1B,CAED,cAAIooB,CAAWuO,GACb77B,MAAMmF,YAAY,aAAc02B,EACjC,CAQD,eAAItO,GACF,MAAMrvB,EAAO8B,MAAMC,WAAW,QAC9B,MAAkB,WAAT/B,GAAgC,iBAATA,GAA2BqC,KAAK+sB,UACjE,CASD,SAAI3uB,GACF,GAAI4B,KAAKrH,SAAU,OAAO,EAC1B,MAAMyF,EAAQspB,WAAWjoB,MAAMC,WAAW,WAAa,EACvD,OAAOsH,KAAKwZ,IAAIxZ,KAAKuZ,IAAIniB,EAAO,IAAM,EACvC,ECnkEH,IAAIuP,EAKG,SAAS4tB,iBACd5tB,EAAS6tB,UAAUC,eAAehlC,EAAOC,IACzCiX,EAAO+tB,SAAS,eAAgBhuB,YAAY2B,wBAC5C1B,EAAO+tB,SAAS,UAAWhuB,YAAY6C,mBACvC5C,EAAO+tB,SAAS,WAAYhuB,YAAYkC,oBACxCjC,EAAO+tB,SAAS,QAAS9Q,eAAekP,sBAC1C,CAQO,SAAS6B,oBACd,QAAIr8B,KAAKkG,QAAQtD,IAAI,cAAcmD,SAEnC3G,OAAOQ,MAAM,4EAA4E,IAClF,EACT,CAQO,SAAS08B,YACd,OAAOjuB,CACT,CChCO,MAAMkuB,qBACX,WAAA/7B,CAAYqS,GACVnS,KAAKmS,cAAgBA,EACrBnS,KAAKgC,MAAQmQ,EAAcnQ,MAC3BhC,KAAK0B,MAAQyQ,EAAczQ,KAC5B,CAUD,YAAAo6B,GACE97B,MAAK+7B,IACN,CAQD,GAAAA,GACM/7B,KAAKgC,MACPhC,MAAKg8B,KAELh8B,MAAKi8B,IAER,CAQD,GAAAD,GACE,IAAKh8B,KAAK0B,MAAO,OACjB,MAAMw6B,EAAc,GAGdC,EAAiB,eACjBC,EAAmBp8B,KAAK0B,OAAO26B,SACjC/8B,KAAKwF,KAAKE,SAAS,mCACnB1F,KAAKwF,KAAKE,SAAS,8BACjBs3B,EAAqB,CACzBv6B,GAAIo6B,EACJ9jC,KAAM+jC,EACNhK,QAASvlB,UACP,MAAMnL,EAAQjC,MAAMoE,0BACpBnC,EAAMiH,SAAS4zB,iBAAiB,GAOpC,GAHAL,EAAY94B,KAAKk5B,GAGbh9B,KAAK0E,KAAKoB,KAAM,CAClB,MAAMo3B,EAAqB,mBACrBC,EAAuBz8B,KAAK0B,OAAOiH,UAAU+zB,OAC/Cp9B,KAAKwF,KAAKE,SAAS,8BACnB1F,KAAKwF,KAAKE,SAAS,gCACjB23B,EAAyB,CAC7B56B,GAAIy6B,EACJnkC,KAAMokC,EACNrK,QAASvlB,UACP,MAAMnL,EAAQjC,MAAMoE,0BACdkf,EAAWrhB,EAAMiH,SAAS+zB,aAC1Bh7B,EAAMiH,SAASmQ,OAAO,CAAE4jB,QAAS3Z,GAAW,GAGtDmZ,EAAY94B,KAAKu5B,EAClB,CAED,MAAM/mB,EAAY,CAAE7T,GAAI,QAASvI,KAAM2B,EAAWG,QAGlD0E,KAAKmS,cAAcyqB,WAAWV,EAAatmB,EAC5C,CAQD,GAAAqmB,GACE,MAAMr6B,EAASnC,MAAMmE,sBACfs4B,EAAc,GAGdC,EAAiB,eACjBC,EAAmBx6B,EAAOmB,OAAMrB,GAASA,EAAM26B,WACjD/8B,KAAKwF,KAAKE,SAAS,mCACnB1F,KAAKwF,KAAKE,SAAS,8BACjBs3B,EAAqB,CACzBv6B,GAAIo6B,EACJ9jC,KAAM+jC,EACNhK,QAASvlB,UACP,MAAM2F,EAAmB/S,MAAMmE,sBAC/B,IAAK,MAAMlC,KAAS8Q,QACZ9Q,EAAMiH,SAAS4zB,iBACtB,GAML,GAHAL,EAAY94B,KAAKk5B,GAGbh9B,KAAK0E,KAAKoB,KAAM,CAClB,MAAMo3B,EAAqB,mBACrBK,EAAuBj7B,EAAOmB,OAAMrB,GAASA,EAAMiH,UAAU+zB,SAC/Dp9B,KAAKwF,KAAKE,SAAS,8BACnB1F,KAAKwF,KAAKE,SAAS,gCACjB23B,EAAyB,CAC7B56B,GAAIy6B,EACJnkC,KAAMwkC,EACNzK,QAASvlB,UACP,MAAM2F,EAAmB/S,MAAMmE,sBAC/B,IAAK,MAAMlC,KAAS8Q,EAAkB,CACpC,MAAMuQ,EAAWrhB,EAAMiH,SAAS+zB,aAC1Bh7B,EAAMiH,SAASmQ,OAAO,CAAE4jB,QAAS3Z,GACxC,IAGLmZ,EAAY94B,KAAKu5B,EAClB,CAED,MAAM/mB,EAAY,CAAE7T,GAAI,QAASvI,KAAM2B,EAAWG,QAGlD0E,KAAKmS,cAAcyqB,WAAWV,EAAatmB,EAC5C,ECtII,MAAMknB,wBACX3qB,cAEA4qB,kBAEAC,QAEA,WAAAl9B,CAAYqS,GACVnS,KAAKmS,cAAgBA,EACrBnS,KAAK+8B,kBAAoB,IAAI10B,IAC7BrI,KAAKg9B,QAAU,EAChB,CASD,kBAAMlB,GACJ,GAAKr8B,MAAMC,WAAW,2BAAtB,CAEA,GAAoC,IAAhCM,KAAK+8B,kBAAkBnN,KAAY,CASrC,GARA5vB,KAAKg9B,QAAU19B,KAAKkZ,MACjBpP,QACCqP,GACE1gB,EAAsBwL,SAASkV,EAAKC,gBAC9BrX,QAAQC,MAAMwH,eAAexJ,KAAKsG,QAAS,MAAQ6S,EAAKE,SAAWF,EAAK1K,SAAWzO,KAAK0E,KAAKoB,QAEtG3C,KAAIgW,GAAQA,EAAKG,SAAS7W,KAED,IAAxB/B,KAAKg9B,QAAQ91B,OAAc,aAEzB9G,QAAQ0N,IAAI9N,KAAKg9B,QAAQv6B,KAAIw6B,GAAUj9B,MAAKk9B,GAAYD,KAC/D,CAED,IAAK,MAAMxkB,KAAQzY,KAAK+8B,kBAAkBhzB,SACxC/J,KAAKmS,cAAcyqB,WAAWnkB,EAAKnD,QAASmD,EAAK7C,UAjBM,CAmB1D,CAQD,QAAMsnB,CAAYD,GAChB,MAAMxkB,EAAOnZ,KAAKkZ,MAAMtW,IAAI+6B,GACtB30B,EAAUmQ,EAAOA,EAAKvL,MAAM0iB,KAAO,EAAInX,EAAKvL,YAAcuL,EAAK0kB,WAAa,KAClF,IAAK70B,EAAS,OACd,MAAM80B,EAAap9B,MAAKq9B,GAAyB5kB,GAAMC,cACvD,IAAK0kB,EAAY,OACjB,MAAM9nB,EAAUhN,EAAQ7F,KAAI66B,GAC1Bt9B,KAAKmS,cAAcorB,aACjB,CACEx7B,GAAIu7B,EAAME,IACVnlC,KAAMilC,EAAMjlC,KACZse,SAAU,GAAGrX,KAAKwF,KAAKE,SAAStN,EAAY0lC,QAAiBE,EAAMjlC,OACnEiL,IAAK7D,MAAMwD,SAASq6B,GACpBlL,QAASpyB,MAAKy9B,GAAYL,EAAY3kB,EAAM6kB,EAAME,SAGlD5nB,EAAY,CAAE7T,GAAI/B,MAAK09B,GAAYT,GAASzjC,KAAM,QACxDwG,KAAK+8B,kBAAkB34B,IAAI64B,EAAQ,CAAE3nB,UAASM,aAC/C,CAWD,GAAAynB,CAAyB3kB,GACvB,MACO,UADCA,EAEG,kBAEA,iBAEZ,CAWD,GAAA+kB,CAAYL,EAAY3kB,EAAMklB,GAC5B,MACO,oBADCP,EAEGp9B,MAAK49B,GAAoBnlB,EAAMklB,GAE/B39B,MAAK69B,GAAiBplB,EAAMklB,EAExC,CAUD,GAAAE,CAAiBplB,EAAMklB,GACrB,OAAO9wB,UACL,MAAMixB,QAAqBrlB,EAAKslB,YAAYJ,GAC5CG,EAAaE,MAAM3e,QAAO,EAAK,CAClC,CAUD,GAAAue,CAAoBnlB,EAAMklB,GACxB,OAAO9wB,gBACC4L,EAAKslB,YAAYJ,GAAYtsB,MAAKvZ,GAASA,EAAMmmC,WAAU,CAEpE,CASD,GAAAP,CAAYT,GACV,OAAOA,EAAOp8B,QAAQ,IAAK,IAC5B,CAYD,kBAAAq9B,CAAmBjB,GACjB,QAAQj9B,KAAKg9B,QAAc,QACvBh9B,KAAKg9B,SAASz5B,SAAS05B,EAE5B,EC7JI,MAAMkB,mBACX,WAAAr+B,CAAYqS,GACVnS,KAAKmS,cAAgBA,CACtB,CASD,UAAAisB,GACEp+B,KAAKq+B,aAAe,IACrB,CAUD,kBAAMvC,GACCr8B,MAAMC,WAAW,wBAEjBM,KAAKq+B,eACRr+B,KAAKq+B,aAAe,CAClB/oB,cAAetV,MAAKs+B,KACpB1oB,UAAW,CAAE7T,GAAI,SAAUvI,KAAM,UAIrCwG,KAAKmS,cAAcyqB,WAAW58B,KAAKq+B,aAAa/oB,QAAStV,KAAKq+B,aAAazoB,WAC5E,CASD,QAAM0oB,GACJ,MAAMlB,EAAa,QACbmB,EAASj/B,KAAKi/B,OAAOn1B,QAAOtR,GAASkI,MAAKiP,GAAenX,KAE/D,OAAOymC,EAAO97B,KAAI3K,GAChBkI,KAAKmS,cAAcorB,aAAa,CAC9Bx7B,GAAIjK,EAAMiK,GACV1J,KAAMP,EAAMO,KACZse,SAAU3W,MAAKw+B,GAAapB,EAAYtlC,EAAMO,MAC9CiL,IAAK7D,MAAMwD,SAASnL,GACpBs6B,QAAS,KACP9yB,KAAKi/B,OAAOr8B,IAAIpK,EAAMiK,IAAIk8B,SAAS,KAI1C,CAYD,GAAAhvB,CAAenX,GACb,MAAM2mC,UAAEA,GAAc3mC,EACtB,OAAO2mC,EAAUn/B,KAAKoU,QAAU+qB,EAAUn/B,KAAKoU,QAAU,EAAI+qB,EAAU/kC,QAAU,CAClF,CAUD,GAAA8kC,CAAapB,EAAY/kC,GACvB,MAAMqmC,EAAiB,GAAGp/B,KAAKwF,KAAKE,SAAStN,EAAY0lC,SAAoB,GAC7E,MAAO,GAAGsB,IAAiBrmC,GAC5B,ECnFI,MAAMsmC,cACX,WAAA7+B,GACEE,KAAKiS,WAAa,GAClBjS,KAAKkS,aAAe,GACpBlS,KAAK4+B,qBAAuB,IAAI/C,qBAAqB77B,MACrDA,KAAK6+B,wBAA0B,IAAI/B,wBAAwB98B,MAC3DA,KAAK8+B,mBAAqB,IAAIX,mBAAmBn+B,MACjDA,KAAKsV,QAAU,GACftV,KAAK2c,iBAAmB,IAAItU,IAC5BrI,KAAK++B,UAAYtnC,EACjBuI,KAAKg/B,uBAAyB,EAC/B,CASD,SAAAxrB,GACExT,KAAK4+B,qBAAuB,IAAI/C,qBAAqB77B,MACrDA,KAAKsV,QAAU,GACftV,KAAK2c,iBAAmB,IAAItU,GAC7B,CAUD,cAAA+R,CAAenO,GACb,IAAK,MAAMhV,KAAS2S,OAAOG,OAAOkC,GAChC,GAAIhV,EAAMqe,SAASpO,OAAQ,CACzBlH,KAAKsV,QAAQlS,QAAQnM,EAAMqe,SAC3B,IAAK,MAAMxe,KAAUG,EAAMqe,QACzBxe,EAAOge,UAAW,CAErB,CAEJ,CASD,sBAAMqF,SACE/Z,QAAQ0N,IAAI,CAChB9N,MAAKi/B,KACLj/B,MAAKk/B,KACLl/B,MAAKm/B,KACLn/B,MAAKo/B,aAEDp/B,MAAKq/B,KACXr/B,MAAKs/B,KACLt/B,MAAKu/B,IACN,CAQD,QAAMN,GACJvgC,EAAOnB,MAAM,6BAA8B,CAAEyE,MAAOhC,KAAKgC,MAAON,MAAO1B,KAAK0B,QAC5E,MAAM89B,EAAWx/B,KAAKkS,aAAawD,oBAC7B1V,KAAKy/B,mBAAmBD,GAC9B9gC,EAAOnB,MAAM,uBAAwB,CAAErG,IAAK8I,KAAK9I,IAAK8K,MAAOhC,KAAKgC,MAAON,MAAO1B,KAAK0B,OACtF,CASD,wBAAM+9B,CAAmBD,GAAY,CAQrC,QAAML,GACJzgC,EAAOnB,MAAM,wCACPyC,KAAK6+B,wBAAwB/C,eACnCp9B,EAAOnB,MAAM,2BAA4B,CAAErG,IAAK8I,KAAK9I,KACtD,CAQD,GAAAgoC,GACExgC,EAAOnB,MAAM,8BAA+B,CAAEyE,MAAOhC,KAAKgC,MAAON,MAAO1B,KAAK0B,QAC7E1B,KAAK4+B,qBAAqB9C,eAC1Bp9B,EAAOnB,MAAM,wBAAyB,CAAErG,IAAK8I,KAAK9I,IAAK8K,MAAOhC,KAAKgC,MAAON,MAAO1B,KAAK0B,OACvF,CAQD,QAAM09B,GACJ1gC,EAAOnB,MAAM,mCACPyC,KAAK8+B,mBAAmBhD,eAC9Bp9B,EAAOnB,MAAM,sBAAuB,CAAErG,IAAK8I,KAAK9I,KACjD,CAQD,QAAMmoC,SACEj/B,QAAQ0N,IAAI9N,KAAKg/B,uBAAuBv8B,KAC5CoK,eAAwB6yB,EAASC,wBAEpC,CAQD,GAAAL,GACE,MAAMM,EAAmB5/B,KAAKsV,QAAQlM,QAAOtS,IAAWA,GAAQ8gB,WAEhE,IAAK,MAAMioB,KAAmBD,EAAkB,CAC9C,MAAME,EAAkB9/B,KAAK2c,iBAAiBza,IAAI29B,EAAgB99B,IAElE,GAAI+9B,EAAiB,CACnB,MAAMC,EAAiBD,EAAgBC,gBAAkBF,EAAgBE,eACnEloB,EAAegoB,EAAgBhoB,cAAgBioB,EAAgBjoB,aACrEjO,OAAO6C,OAAOozB,EAAiB7/B,KAAKu9B,aAAa,IAAKuC,EAAiBC,iBAAgBloB,iBACxF,CACF,CACF,CAQD,GAAA0nB,GACE,MAAMtzB,EAASjM,KAAKkS,aAAasD,UAAU,CAAEjJ,MAAO,IAEpD,IAAK,MAAMtV,KAASgV,EAAQ,CAC1B,MAAM+zB,EAAsB/oC,GAAOG,UAAUsoB,eAEvCugB,EAAYjgC,KAAKkS,aAAasD,UAAU,CAAEhJ,OAAQvV,EAAMuV,SAE9D,IAAK,MAAM0zB,KAAYD,EAAW,CAChC,MAAM3qB,EAAU4qB,EAAS5qB,QACzB,IAAKA,GAASpO,OAAQ,SAEtB,MAAMi5B,EAAyBD,GAAU9oC,UAAUsoB,eAC7CA,EAAkBygB,GAA0B,EAC9CA,EACAH,EAGJ,MAAMtgB,GAAqC,IAAnBA,GAAyBA,EAAiB,GAElE,IAAK,MAAM5oB,KAAUwe,EACfxe,EAAOuB,KAAK6O,QAAUwY,IAM1B5oB,EAAOuB,KALgB,IAAnBqnB,EAKU5oB,EAAOuB,KAClBiT,MAAM,KACN7I,KAAI29B,GAAQA,EAAK34B,MAAM,EAAGiY,KAC1B9Y,KAAK,KAPQ,GASnB,CACF,CACF,CAUD,GAAAy5B,CAAmBppC,GACjB,QAA8Bs8B,IAA1Bt8B,GAAOG,UAAUgQ,KAAoB,QAASnQ,EAAMG,SAASgQ,KACjE,MAAMk5B,EAAiBrpC,GAAOuV,QAAQlB,MAAM,KAAK,GACjD,GAAIg1B,GAAkBA,IAAmBrpC,EAAMuV,OAAQ,CACrD,MAAM+zB,EAAgBvgC,KAAKkS,aAAaqD,SAAS,CAAE/I,OAAQ8zB,IAC3D,QAAsC/M,IAAlCgN,GAAenpC,UAAUgQ,KAAoB,QAASm5B,EAAcnpC,SAASgQ,IAClF,CACD,QAAS3H,MAAMC,WAAW,cAC3B,CAYD,UAAA4+B,CAAWkC,GACT,OAAOxgC,KAAKsV,QAAQlM,QAAOtS,GAAUA,EAAOiL,KAAOy+B,EAAWz+B,IAC/D,CAYD,YAAAw7B,CAAaiD,GACX,MAAMC,EAAWD,EAAWC,UAAYD,EAAWnoC,KAC7Cwb,EAAUD,WAAW4sB,EAAW3sB,QAAS4sB,GAEzCC,UAAY/hC,GACXA,EACE,IACDA,EAAKzG,OAAS,CAAEA,MAAOyG,EAAKzG,UAC5ByG,EAAK/B,MAAQ,CAAEA,KAAM+B,EAAK/B,SAC1B+B,EAAKmC,MAAQ,CAAEA,KAAMnC,EAAKmC,SAC1BnC,EAAK+G,OAAS,CAAEA,MAAO/G,EAAK+G,QALhB,GASpB,MAAO,CACL3D,GAAIy+B,EAAWz+B,GACf1J,KAAMmoC,EAAWnoC,MAAQmoC,EAAWz+B,IAAM,GAC1C0+B,WACA9pB,SAAU6pB,EAAW7pB,UAAY6pB,EAAWnoC,MAAQmoC,EAAWz+B,IAAM,MACjEy+B,EAAWpO,SAAW,CAAEA,QAASoO,EAAWpO,YAC5CoO,EAAWG,SAAW,CAAEvO,QAASoO,EAAWG,YAC5CH,EAAWI,cAAgB,CAAEA,aAAcJ,EAAWI,iBACtDJ,EAAWjqB,UAAY,CAAEA,SAAUiqB,EAAWjqB,UAClDsqB,MAAOL,EAAWK,OAAS,CAAE,KACzBL,EAAWM,OAAS,CAAEA,MAAON,EAAWM,UACxCN,EAAWO,OAAS,CAAEA,MAAOP,EAAWO,UACxCP,EAAWQ,OAAS,CAAEA,MAAOR,EAAWQ,UACxCR,EAAWl9B,KAAO,CAAEA,IAAKk9B,EAAWl9B,QACpCk9B,EAAW1R,gBAAkB,CAAEA,eAAgB0R,EAAW1R,gBAC9DtY,MAAOkqB,UAAUF,EAAWhqB,OAC5BC,MAAOiqB,UAAUF,EAAW/pB,OAC5BC,MAAOgqB,UAAUF,EAAW9pB,OAC5BL,OAAQmqB,EAAWnqB,QAAU,CAAE,EAC/B4qB,UAAU,KACNT,EAAWU,QAAU,CAAEA,OAAQV,EAAWU,WAC1CV,EAAW5oB,UAAY,CAAEA,SAAU4oB,EAAW5oB,UAClDC,aAAc2oB,EAAW3oB,eAAgB,EACzCkoB,eAAgBS,EAAWT,iBAAkB,EAC7CjrB,WAAU0rB,EAAWT,iBACjBS,EAAW3oB,cAAgB2oB,EAAWT,iBAAkB,GAE5DlsB,aACI2sB,EAAWW,gBAAkB,CAAEA,eAAgBX,EAAWW,gBAEjE,CAUD,UAAAvE,CAAWV,EAAatmB,GACtB,IAAKsmB,EAAYh1B,OAAQ,OAGzB,MAAMoO,EAAU,IAAIjN,IAAI6zB,EAAYz5B,KAAI+9B,GAAc,CACpDA,EAAWz+B,GACVy+B,EAAmB,SAAIA,EAAaxgC,KAAKu9B,aAAaiD,OAIzD,GAFAxgC,MAAKohC,GAAuB9rB,IAEvBM,GAAW7T,GAAI,OAEf6T,GAAWpc,OAAQoc,EAAUpc,KAAO,UAEzC,MAAMyS,EAASjM,KAAKkS,aAAasD,UAAUI,GAE3C,GAAK3J,EAAO/E,OAEZ,IAAK,MAAMjQ,KAASgV,EAAQ,CAE1B,MAAMo1B,EAAkB,IAAIh5B,IAAIpR,EAAMqe,QAAQ7S,KAAI3L,GAAU,CAACA,EAAOiL,GAAIjL,MAElEwqC,EAAmB,GAGzBD,EAAgBhoB,SAAQ,CAACkoB,EAAgBC,KACvC,MAAM1qC,EAASwe,EAAQpT,IAAIs/B,GAC3B,GAAI1qC,EAAQ,CACV,MAAMipC,EAAiBjpC,EAAOipC,gBAAkBwB,EAAexB,eACzDloB,EAAe0pB,EAAe1pB,cAAgB/gB,EAAO+gB,aACrD/C,IAAairB,IAEfloB,GAAgBkoB,IAAkB,GACtCn2B,OAAO6C,OAAO80B,EAAgB,IAAKzqC,EAAQ8gB,UAAU,EAAM9C,WAAUirB,iBAAgBloB,gBACtF,MAAM,IAAK0pB,EAAezsB,UAAYysB,EAAe3pB,SAAU,CAC9D,MAAMmoB,GAAiB,EACvBn2B,OAAO6C,OAAO80B,EAAgBvhC,KAAKu9B,aAAa,IAAKgE,EAAgBxB,mBACtE,KAIHzqB,EAAQ+D,SAAQ,CAACviB,EAAQ4lB,KACvB,MAAM6kB,EAAiBF,EAAgBn/B,IAAIwa,GACtC6kB,GAAgBD,EAAiBl+B,KAAKpD,KAAKu9B,aAAa,IAAKzmC,EAAQ8gB,UAAU,IAAQ,IAI9F3gB,EAAMqe,QAAQlS,QAAQk+B,GAGlBthC,MAAKqgC,GAAmBppC,IAC1BA,EAAMqe,QAAQlO,MAAK,CAACC,EAAGC,KAAOD,EAAEhP,MAAQ,IAAIkQ,cAAcjB,EAAEjP,MAAQ,KAEvE,CACF,CAUD,aAAA8oB,CAAc+a,EAAatmB,GACzB,MAAM3e,EAAQ+I,KAAKkS,aAAaqD,SAASK,GACnCN,EAAUre,EAAMqe,QAEhBgsB,EAAmB,GAIzB,IAAK,MAAMd,KAActE,EAAa,CACpC,GAAIsE,EAAWz+B,GAAGwB,SAAS,aAAc,SACzC,MAAMg+B,EAAiBtqC,EAAMqe,QAAQxT,MAAKhL,GAAUA,EAAOiL,KAAOy+B,EAAWz+B,KAC7E,GAAIw/B,EAAgB,CAClB,MAAME,EAAc,IAAKF,EAAgB1pB,cAAc,GACvDypB,EAAiBl+B,KAAKq+B,EAC9B,KAAa,CACL,MAAM3B,EAAkB9/B,KAAK2c,iBAAiBza,IAAIs+B,EAAWz+B,IAC7D,GAAI+9B,EAAiB,CACnB,MAAM2B,EAAc,IAAK3B,EAAiBjoB,cAAc,GACxDypB,EAAiBl+B,KAAKq+B,EACvB,CACF,CACF,CAED,IAAK,MAAM3qC,KAAUwe,EAAS,CAC5B,IAAKxe,EAAOiL,IAAMjL,GAAQiL,GAAGwB,SAAS,aAAc,SAEpD,MAAMi9B,EAAatE,EAAYp6B,MAAK0+B,GAAcA,EAAWz+B,KAAOjL,EAAOiL,KAC3E,IAAKy+B,GAAc1pC,EAAO8gB,SAAU,CAClC,MAAM6pB,EAAc,IAAK3qC,EAAQ+gB,cAAc,GAC/CypB,EAAiBl+B,KAAKq+B,EACvB,CACF,CAGGzhC,MAAKqgC,GAAmBppC,IAC1BqqC,EAAiBl6B,MAAK,CAACC,EAAGC,KAAOD,EAAEhP,MAAQ,IAAIkQ,cAAcjB,EAAEjP,MAAQ,MAIzEpB,EAAMqe,QAAUgsB,CACjB,CASD,GAAAF,CAAuB9rB,GACrB,IAAK,MAAOoH,EAAU5lB,KAAWwe,EAC1BtV,KAAK2c,iBAAiBrT,IAAIoT,IAC7B1c,KAAK2c,iBAAiBvY,IAAIsY,EAAU5lB,EAGzC,CAWD,mBAAAquB,GACE,MAAO,IAAInlB,KAAK2c,iBAAiB5S,UAC9BtH,KAAI3L,GAAUkJ,MAAKuY,EAAUzhB,KAC7BsQ,MAAK,CAACC,EAAGC,IAAMD,EAAEsP,SAASpO,cAAcjB,EAAEqP,WAC9C,CAUD,kBAAAyO,CAAmBxP,GACjB,MAAM3e,EAAQ+I,KAAKkS,aAAaqD,SAASK,GACzC,OAAK3e,EACEA,EAAMqe,QACVlM,QAAOtS,IAA8B,IAApBA,EAAOge,WACxBrS,KAAI3L,GAAUkJ,MAAKuY,EAAUzhB,KAHb,EAIpB,CAUD,EAAAyhB,CAAUioB,GACR,MAAMz+B,GAAEA,EAAE1J,KAAEA,EAAIse,SAAEA,GAAa6pB,EAC/B,MAAO,CAAEz+B,KAAI1J,OAAMse,SAAUA,GAAYte,EAAMmB,KAAM,SACtD,CAWD,wBAAAkoC,CAAyBC,GACvBjjC,EAAOnB,MAAM,oCAAqC,CAAEokC,0BACpDA,EAAsB1vB,WAAajS,KAAKiS,WACxC0vB,EAAsBzvB,aAAelS,KAAKkS,aAC1CyvB,EAAsBxvB,cAAgBnS,KACtCA,KAAKg/B,uBAAuB57B,KAAKu+B,EAClC,CAUD,iBAAI9uB,GACF,OAAO7S,KAAKiS,YAAYY,aACzB,CAQD,SAAI7Q,GACF,OAAOhC,KAAKiS,YAAYjQ,KACzB,CAOD,SAAIA,CAAMA,GACRhC,KAAKiS,WAAWjQ,MAAQA,CACzB,CAQD,UAAIC,GACF,OAAOjC,KAAKiS,YAAYhQ,MACzB,CAQD,UAAIA,CAAOA,GACTjC,KAAKiS,WAAWhQ,OAASA,CAC1B,CAQD,SAAIP,GACF,OAAO1B,KAAKiS,YAAYvQ,KACzB,CAOD,SAAIA,CAAMA,GACR1B,KAAKiS,WAAWvQ,MAAQA,CACzB,CAQD,UAAIE,GACF,OAAO5B,KAAKiS,YAAYrQ,MACzB,CAQD,UAAIA,CAAOA,GACT5B,KAAKiS,WAAWrQ,OAASA,CAC1B,CAQD,gBAAIyZ,GACF,OAAOrb,KAAKiS,YAAYoJ,YACzB,CAQD,SAAIU,GACF,OAAO/b,KAAKiS,YAAY8J,KACzB,CAQD,UAAIG,GACF,OAAOlc,KAAKiS,YAAYiK,MACzB,CAQD,WAAIG,GACF,OAAOrc,KAAKiS,YAAYoK,OACzB,CAQD,WAAIC,GACF,OAAOtc,KAAKiS,YAAYqK,OACzB,ECzmBI,MAAMslB,8BAA8BjD,cACzC,WAAA7+B,GACE8d,OACD,CAMD,mBAAA+hB,GAAwB,ECRnB,MAAMkC,YACX,WAAA/hC,GACEE,KAAKiS,WAAa,KAClBjS,KAAK++B,UAAYtnC,EACjBuI,KAAK8hC,gBAAkB,GACvB9hC,KAAK+hC,qBAAuB,EAC7B,CAOD,oBAAAC,CAAqBjwB,GACnB,MAAM,IAAIkwB,MACR,gCAAgClwB,IAEnC,CAOD,sBAAAmwB,CAAuBC,GACrBzjC,EAAOnB,MAAM,kCAAmC,CAAE4kC,wBAClDniC,KAAK+hC,qBAAqB3+B,KAAK++B,EAChC,CASD,2BAAMtnB,CAAsBzY,EAAOtL,EAAQqb,GACzC,IAOE,GANAzT,EAAOnB,MAAM,8BAA+B,CAAE6E,UAG9CpC,KAAKlJ,OAASA,EAGiB,mBAApBA,GAAQs7B,QAGjB,OAFAt7B,EAAOs7B,eACP1X,MAAM0E,QAAQ,6BAKhB,MAAMgjB,EAAcpiC,MAAKqiC,GAAgBjgC,GAGzC,IAAK,IAAI8b,KAAWle,KAAK+hC,qBAEvB,GADA7jB,EAAQpnB,OAASkJ,KAAKlJ,OAClBonB,EAAQokB,qBAAqBlgC,EAAOggC,EAAajwB,GACnD,OAKJ,IAAK,IAAI+L,KAAWle,KAAK8hC,gBAEvB,GADA5jB,EAAQpnB,OAASkJ,KAAKlJ,OAClBonB,EAAQokB,qBAAqBlgC,EAAOggC,EAAajwB,GACnD,OAKJ,IAAK,IAAI+L,KAAWle,KAAK+hC,qBAEvB,GADA7jB,EAAQpnB,OAASkJ,KAAKlJ,OAClBonB,EAAQqkB,kBAAkBngC,EAAOggC,EAAajwB,GAChD,OAKJnS,KAAKuiC,kBAAkBngC,EAAOggC,EAC/B,CAAC,MAAMljC,GACNR,EAAOQ,MAAM,oCAAqC,CAAEA,QAAOkD,QAAOtL,UACnE,CACF,CAUD,iBAAAyrC,CAAkBngC,EAAOggC,GAAe,CASxC,2BAAMtnB,CAAsB1Y,EAAOtL,GAOjC,GANA4H,EAAOnB,MAAM,8BAA+B,CAAE6E,UAG9CpC,KAAKlJ,OAASA,EAGiB,mBAApBA,GAAQ6pC,QAEjB,YADA7pC,EAAO6pC,UAKT,MAAMyB,EAAcpiC,MAAKqiC,GAAgBjgC,GAEzCpC,KAAK0uB,kBAAkBtsB,EAAOggC,EAC/B,CAUD,iBAAA1T,CAAkBtsB,EAAOggC,GAAe,CASxC,0BAAMxnB,CAAqBxY,EAAOnL,GAChCyH,EAAOnB,MAAM,mCAAmCtG,EAAMoB,QAAS,CAAE+J,UAEjEpC,KAAKoxB,iBAAiBhvB,EAAOnL,EAC9B,CAUD,gBAAAm6B,CAAiBhvB,EAAOnL,GAAS,CASjC,iBAAAurC,CAAkBtkB,GAChBxf,EAAOnB,MAAM,2BAA2B2gB,EAAQpe,YAAYzH,QAC5D2H,KAAK8hC,gBAAgB1+B,KAAK8a,EAC3B,CAUD,GAAAmkB,CAAgBjgC,GACd,IAAKA,EAAO,OAAO,KACnB,MAAMqgC,EAAgBrgC,EAAMC,OAAOuG,cAAc,uBAAyBxG,EAAMC,OAAOC,QAAQ,sBAC/F,OAAOmgC,GAAe7hC,OAAS,IAChC,CAWD,UAAA8hC,CAAW1gC,EAAOyB,GAEXzB,IACHA,EAAQhC,KAAKgC,OAIf,MAAMqxB,EAAO5zB,MAAM+D,QAAQxB,EAAOyB,GAGlC,QAAK4vB,IAGLA,EAAK2K,MAAM3e,QAAO,IACX,EACR,CASD,YAAAsjB,GACE,OAAQ3iC,KAAKqb,gBAAkBrb,KAAK+b,OAAS/b,KAAKkc,QAAUlc,KAAKqc,QAClE,CAUD,SAAIra,GACF,OAAOhC,KAAKiS,YAAYjQ,KACzB,CAQD,UAAIC,GACF,OAAOjC,KAAKiS,YAAYhQ,MACzB,CAQD,SAAIP,GACF,OAAO1B,KAAKiS,YAAYvQ,KACzB,CAQD,UAAIE,GACF,OAAO5B,KAAKiS,YAAYrQ,MACzB,CAQD,gBAAIyZ,GACF,OAAOrb,KAAKiS,WAAWoJ,YACxB,CAQD,SAAIU,GACF,OAAO/b,KAAKiS,WAAW8J,KACxB,CAQD,UAAIG,GACF,OAAOlc,KAAKiS,WAAWiK,MACxB,CAQD,WAAIG,GACF,OAAOrc,KAAKiS,WAAWoK,OACxB,CAQD,WAAIC,GACF,OAAOtc,KAAKiS,YAAYqK,OACzB,EChTI,MAAMsmB,uBAAuBf,YAQlC,oBAAAS,CAAqBlgC,EAAOggC,EAAajwB,GACvC,OAAO,CACR,ECZI,MAAM0wB,4BAA4BhB,YACvC,WAAA/hC,GACE8d,OACD,CASD,oBAAA0kB,CAAqBlgC,EAAOggC,EAAajwB,GACvC,OAAO,CACR,CAYD,iBAAAowB,CAAkBngC,EAAOggC,EAAajwB,GACpC,OAAO,CACR,EC9BH,MAAMsL,cAAEA,EAAaC,2BAAEA,GAA+Brc,QAAQiM,aAAawP,IAEpE,MAAMgmB,wBAAwBplB,EAA2BD,IAC9D,WAAA3d,IAAewK,GACbsT,MAAMtT,EACP,CAIDwT,uBAAyB,CACvBxI,QAAS,CACPrX,MAAO6kC,gBAAgB7kC,OAEzBhB,QAAS,CAAC,GAAGxG,EAAOC,SAAU,SAC9BqL,GAAI,iCACJic,KAAM,CACJC,eAAe,EACfC,QAAS4kB,gBAAgBjlB,QAE3BM,SAAU,CACRC,MAAO,IACPC,OAAQ,KAEVC,IAAK,OACLrB,OAAQ,CACNsB,aAAa,EACbC,WAAW,EACX9Y,MAAO,iDACP9I,KAAM,wBAMVkhB,aAAe,CACbE,KAAM,CACJc,SAAUjoB,EAASG,kBAMvB,qBAAMynB,GA2BJ,OA1BAze,KAAK0hB,QAAU,CACbpoB,gBAAiBmG,MAAMC,WAAW,kBAAmBrG,EAAaC,gBAAgBI,SAClFC,aAAc8F,MAAMC,WAAW,eAAgBrG,EAAaM,aAAaD,SACzEG,sBAAuB4F,MAAMC,WAAW,wBAAyBrG,EAAaQ,sBAAsBH,SACpGS,2BAA4BsF,MAAMC,WAAW,6BAA8BrG,EAAac,2BAA2BT,SACnHW,kCAAmCoF,MAAMC,WAAW,oCAAqCrG,EAAagB,kCAAkCX,SACxIe,iCAAkCgF,MAAMC,WAAW,mCAAoCrG,EAAaoB,iCAAiCf,SACrIM,gBAAiByF,MAAMC,WAAW,kBAAmBrG,EAAaW,gBAAgBN,SAClFU,qBAAsBqF,MAAMC,WAAW,uBAAwBrG,EAAae,qBAAqBV,SACjGc,4BAA6BiF,MAAMC,WAAW,8BAA+BrG,EAAamB,4BAA4Bd,SACtHkB,2BAA4B6E,MAAMC,WAAW,6BAA8BrG,EAAauB,2BAA2BlB,SACnHI,yBAA0B2F,MAAMC,WAAW,2BAA4BrG,EAAaS,yBAAyBJ,SAC7GK,2BAA4B0F,MAAMC,WAAW,6BAA8BrG,EAAaU,2BAA2BL,SACnHO,8BAA+BwF,MAAMC,WAAW,gCAAiCrG,EAAaY,8BAA8BP,SAC5HQ,gCAAiCuF,MAAMC,WAAW,kCAAmCrG,EAAaa,gCAAgCR,SAClIY,qCAAsCmF,MAAMC,WAAW,uCAAwCrG,EAAaiB,qCAAqCZ,SACjJa,uCAAwCkF,MAAMC,WAAW,yCAA0CrG,EAAakB,uCAAuCb,SACvJgB,oCAAqC+E,MAAMC,WAAW,sCAAuCrG,EAAaqB,oCAAoChB,SAC9IiB,sCAAuC8E,MAAMC,WAAW,wCAAyCrG,EAAasB,sCAAsCjB,SACpJmB,iBAAkB4E,MAAMC,WAAW,mBAAoBrG,EAAawB,iBAAiBnB,SACrFoB,mBAAoB2E,MAAMC,WAAW,qBAAsBrG,EAAayB,mBAAmBpB,SAC3FqB,kBAAmB0E,MAAMC,WAAW,oBAAqBrG,EAAa0B,kBAAkBrB,SACxFsB,sBAAuByE,MAAMC,WAAW,wBAAyBrG,EAAa2B,sBAAsBtB,SACpGuB,wBAAyBwE,MAAMC,WAAW,0BAA2BrG,EAAa4B,wBAAwBvB,SAC1GwB,uBAAwBuE,MAAMC,WAAW,yBAA0BrG,EAAa6B,uBAAuBxB,UAElGsG,KAAK0hB,OACb,CAID,SAAAD,CAAUC,EAAStgB,GACjBwc,MAAM6D,UAAUC,EAAStgB,GACE,oBAAhB2hC,aAA+BA,YAAYC,SACvD,CAID,kBAAa/kC,GACX,MAAMyK,EAAaC,SAASC,cAAc,yBAC1C,IAAK,MAAO3E,EAAKrD,KAAUgJ,OAAOtB,QAAQjP,GACxCoG,MAAM0E,WAAWF,EAAKrD,EAAMlH,SAC5BgP,GAAYnK,MAAMuL,YAAYlJ,EAAMrH,YAAaqH,EAAMlH,SAEzDsG,KAAKqf,QAAO,EACb,CAID,mBAAaxB,CAAOzb,EAAO4b,EAAMW,GAC/B,MAAMskB,EAAyC,WAA9BxjC,MAAMC,WAAW,SAC5BgJ,EAAaC,SAASC,cAAc,yBAC1C,IAAK,MAAO3E,EAAKrD,KAAUgJ,OAAOtB,QAAQqW,EAASC,QAAS,CAC1D,MAAMthB,EAAcjE,EAAa4K,GAC7BrD,IAAUZ,KAAK0hB,QAAQzd,KACzBxE,MAAM0E,WAAWF,EAAKrD,GAClBqiC,GAAYv6B,GACdA,EAAWnK,MAAMuL,YAAYxM,EAAY/D,YAAaqH,GAG3D,CACF,ECrGIiM,eAAeq2B,8BACd7hC,QAAQiM,aAAawP,IAAIC,SAASC,QAAQ,CAC9CC,OAAQ,CACNvX,MAAOpG,KAAKwF,KAAKE,SAAS,gDAE5B8O,QAAS,MAAMxU,KAAKwF,KAAKE,SAAS,uDAClCkY,OAAO,EACPC,IAAK,CACHxgB,MAAO2C,KAAKwF,KAAKE,SAAS,oCAC1BoY,SAAUvQ,SAAY/P,mBAExBugB,GAAI,CACF1gB,MAAO2C,KAAKwF,KAAKE,SAAS,qCAGhC,CAQA6H,eAAe/P,kBACb,IAAKwC,KAAKC,eAAgB,OAE1B,MAAM+d,EAAsB3U,SAASC,cAAc,4DAC/C0U,SACI7d,MAAM0E,WAAW,eAAgBmZ,GAAqB1c,OAAS,IAGvE,MAAM4c,EAA0B7U,SAASC,cAAc,gEACnD4U,SACI/d,MAAMmF,YAAY,mBAAoB4Y,GAAyB5c,OAAS,UAG1EtB,KAAKC,eAAeoO,OAAOw1B,mBAAmB,SACpDzkC,EAAOC,KAAK,qBAAqB,EACnC,CCvCA,MAAM8e,cAAEA,EAAaC,2BAAEA,GAA+Brc,QAAQiM,aAAawP,IAEpE,MAAMsmB,wBAAwB1lB,EAA2BD,IAC9D,WAAA3d,IAAewK,GACbsT,MAAMtT,GAENtK,KAAK5I,SAAW,EACjB,CAID0mB,uBAAyB,CACvBxI,QAAS,CACP5Y,aAAc0mC,gBAAgB1mC,aAC9BG,YAAaggB,kBACb/f,gBAAiBomC,sBACjBjlC,MAAOmlC,gBAAgBnlC,OAEzBhB,QAAS,CAAC,GAAGxG,EAAOC,SAAU,SAC9BqL,GAAI,iCACJic,KAAM,CACJC,eAAe,EACfC,QAASklB,gBAAgBvlB,QAE3BM,SAAU,CACRC,MAAO,IACPC,OAAQ,QAEVC,IAAK,OACLrB,OAAQ,CACNsB,aAAa,EACbC,WAAW,IAMfV,aAAe,CACbE,KAAM,CACJc,SAAUjoB,EAASO,WAMvB,qBAAMqnB,GACJ,MAAMrnB,EAAW,GACXsqB,EAAU,CAAEtqB,YAElB,IAAK,MAAO6M,EAAKzE,KAAYoK,OAAOtB,QAAQtI,KAAK5I,UAAW,CAC1D,MAAMoF,MAAEA,EAAKJ,KAAEA,EAAIQ,KAAEA,EAAID,MAAEA,EAAKtE,KAAEA,EAAImB,KAAEA,EAAI6C,UAAEA,EAASgnC,MAAEA,EAAKC,QAAEA,EAAOxsC,OAAEA,GAAW0I,EAEpF,GAAc,UAAVhD,IAAsB8C,KAAK0E,KAAKoB,KAAM,SAE1C,MAAMxE,EAASpB,GAAShD,MACT,SAAVA,QACOiD,MAAMkF,YAAYV,SAClBxE,MAAMC,WAAWuE,GACzB,GACEs/B,EAAc/pC,aAAgBgqC,SAAWhqC,EAAKnB,KAAO,SACrDorC,EAAyB,WAAdpnC,EACXqnC,EAA2B,aAAdrnC,EACbsnC,EAA6B,eAAdtnC,EACfC,EAAgC,eAAdD,EAA8BknC,GAAe,MAAQ,GACvEK,EAAyB,WAAdvnC,EACXwnC,EAAyB,UAAdxnC,GAA0BgnC,EACrCS,OAAuBvQ,IAAZ+P,EACjBlsC,EAASgM,KAAK,CACZrB,GAAIkC,EACJ7H,KAAMkD,KAAKwF,KAAKE,SAAS5I,GACzBQ,OACAD,MAAO2C,KAAKwF,KAAKE,SAASrI,GAC1BtE,KAAMiH,KAAKwF,KAAKE,SAAS3M,GACzBuI,QACApH,OACAiqC,WACA3sC,SACA4sC,aACAC,eACArnC,iBACAsnC,WACAC,UACAC,YAEH,CACD,OAAOpiB,CACR,CAID,mBAAOhlB,GACA4C,KAAKC,gBACVD,KAAKC,eAAe0S,WAAWgC,cAAcvX,cAC9C,CAED,mBAAamhB,CAAOzb,EAAO4b,EAAMW,GAC/B,IAAK,MAAO1a,EAAKrD,KAAUgJ,OAAOtB,QAAQqW,EAASC,QAAS,CAC1D,OAAQ5e,KAAK5I,SAAS6M,GAAKzH,OACzB,IAAK,SACL,IAAK,cACGiD,MAAM0E,WAAWF,EAAKrD,GAAQ,MACtC,IAAK,aACGnB,MAAMmF,YAAYX,EAAKrD,SAG3BtB,KAAKC,eAAege,qBAAqBtZ,EAAKrD,EACrD,CAEDtB,KAAKC,eAAeuZ,QACrB,EAKI,MAAMirB,8BAA8BX,gBACzC,WAAAtjC,GACE8d,QACA5d,KAAK5I,SAAW8E,CACjB,CAID4hB,uBAAyB,CACvBb,OAAQ,CACNvX,MAAO,4CACP9I,KAAM,kCCxHZ,SAASonC,iBAAiB//B,EAAKrD,GACzBtB,KAAKC,gBAAgBD,KAAKC,eAAege,qBAAqBtZ,EAAKrD,EACzE,CAKA8Z,MAAMupB,GAAG,QAAQp3B,UACfvN,KAAK6G,YAAYu1B,SAASjlC,EAAOC,GAAI,mBAAoB,CACvD2B,KAAMiH,KAAKwF,KAAKE,SAAS,mCACzBk/B,SAAU,GACVC,OAAQ,KAAY7kC,KAAKC,gBAAgBD,KAAKC,eAAewwB,iBAAiB,IAGhFzwB,KAAK6G,YAAYu1B,SAASjlC,EAAOC,GAAI,oBAAqB,CACxD2B,KAAMiH,KAAKwF,KAAKE,SAAS,oCACzBk/B,SAAU,GACVC,OAAQ,KAAY7kC,KAAKC,gBAAgBD,KAAKC,eAAe4wB,mBAAmB,GAChF,IAWG,MAAMiU,qBAAuB,SAASlxB,EAAemxB,EAActwB,GACxEzU,KAAKlI,SAASktC,aAAa7tC,EAAOC,GAAI,cAAe,CACnD0F,KAAMkD,KAAKwF,KAAKE,SAAS,4CACzBrI,MAAO2C,KAAKwF,KAAKE,SAAS,6CAC1B3M,KAAMiH,KAAKwF,KAAKE,SAAS,4CACzBpI,KAAM,iBACNpD,KAAMspC,gBACNyB,YAAY,EACZ/nC,MAAO,WAKT8C,KAAKlI,SAASktC,aAAa7tC,EAAOC,GAAI,SAAU,CAC9C0F,KAAMkD,KAAKwF,KAAKE,SAAS,uCACzBrI,MAAO2C,KAAKwF,KAAKE,SAAS,wCAC1B3M,KAAMiH,KAAKwF,KAAKE,SAAS,uCACzBpI,KAAM,sBACNpD,KAAMuqC,sBACNQ,YAAY,EACZ/nC,MAAO,WAKT8C,KAAKlI,SAASskC,SAASjlC,EAAOC,GAAI,UAAW,CAC3C2B,KAAM,0BACNmE,MAAO,QACPgoC,QAAQ,EACRhrC,KAAMirC,QACN/qC,SAAS,IAKX4F,KAAKlI,SAASskC,SAASjlC,EAAOC,GAAI,mBAAoB,CACpD2B,KAAM,oBACNmE,MAAO,QACPgoC,QAAQ,EACRhrC,KAAMC,OACNC,QAAS,QAKX4F,KAAKlI,SAASskC,SAASjlC,EAAOC,GAAI,SAAU,CAC1C2B,KAAMiH,KAAKwF,KAAKE,SAAS,uCACzB5I,KAAMkD,KAAKwF,KAAKE,SAAS,uCACzBxI,MAAO,SACPgoC,QAAQ,EACRhrC,KAAMirC,QACN/qC,SAAS,EACTgrC,SAAU9jC,IACRojC,iBAAiB,SAAUpjC,EAAM,IAMrCtB,KAAKlI,SAASskC,SAASjlC,EAAOC,GAAI,cAAe,CAC/C2B,KAAMiH,KAAKwF,KAAKE,SAAS,4CACzB5I,KAAMkD,KAAKwF,KAAKE,SAAS,4CACzBxI,MAAO,QACPgoC,QAAQ,EACRhrC,KAAMC,OACN6pC,QAASe,EACT3qC,QAAS,OACTgrC,SAAU9jC,IACRojC,iBAAiB,cAAepjC,EAAM,IAM1C,MAAM+jC,EAAe/6B,OAAOg7B,YAAYh7B,OAAOtB,QAAQyL,GAAQtR,KAAI,EAAEwB,EAAKrD,KAAW,CAACqD,EAAKrD,EAAMvI,SAEjGiH,KAAKlI,SAASskC,SAASjlC,EAAOC,GAAI,QAAS,CACzC2B,KAAMiH,KAAKwF,KAAKE,SAAS,sCACzB5I,KAAMkD,KAAKwF,KAAKE,SAAS,sCACzBxI,MAAO,SACPgoC,QAAQ,EACRhrC,KAAMC,OACNC,QAAS,aACT4pC,QAASqB,EACTD,SAAU9jC,IACRnB,MAAMgJ,UAAU7H,GAChBojC,iBAAiB,QAASpjC,EAAM,IAMpCtB,KAAKlI,SAASskC,SAASjlC,EAAOC,GAAI,eAAgB,CAChD2B,KAAMiH,KAAKwF,KAAKE,SAAS,6CACzB5I,KAAMkD,KAAKwF,KAAKE,SAAS,6CACzBxI,MAAO,QACPgoC,QAAQ,EACRhrC,KAAMC,SAKR6F,KAAKlI,SAASskC,SAASjlC,EAAOC,GAAI,mBAAoB,CACpD2B,KAAMiH,KAAKwF,KAAKE,SAAS,iDACzB5I,KAAMkD,KAAKwF,KAAKE,SAAS,iDACzBxI,MAAO,SACPgoC,QAAQ,EACRhrC,KAAMC,SAKR6F,KAAKlI,SAASskC,SAASjlC,EAAOC,GAAI,QAAS,CACzC2B,KAAMiH,KAAKwF,KAAKE,SAAS,sCACzB5I,KAAMkD,KAAKwF,KAAKE,SAAS,sCACzBxI,MAAO,QACPgoC,QAAQ,EACRhrC,KAAMC,OACN6pC,QAAS,CACP,EAAGhkC,KAAKwF,KAAKE,SAAS,0CACtB,EAAG1F,KAAKwF,KAAKE,SAAS,0CACtB,EAAG1F,KAAKwF,KAAKE,SAAS,0CACtB,EAAG1F,KAAKwF,KAAKE,SAAS,2CAExBtL,QAAS,EACTmrC,gBAAgB,IAKlBvlC,KAAKlI,SAASskC,SAASjlC,EAAOC,GAAI,sBAAuB,CACvD2B,KAAMiH,KAAKwF,KAAKE,SAAS,oDACzB5I,KAAMkD,KAAKwF,KAAKE,SAAS,oDACzBxI,MAAO,QACPgoC,QAAQ,EACRhrC,KAAMirC,QACN/qC,SAAS,EACTgrC,SAAU9jC,IACRojC,iBAAiB,sBAAuBpjC,EAAM,IAMlDtB,KAAKlI,SAASskC,SAASjlC,EAAOC,GAAI,0BAA2B,CAC3D2B,KAAMiH,KAAKwF,KAAKE,SAAS,wDACzB5I,KAAMkD,KAAKwF,KAAKE,SAAS,wDACzBxI,MAAO,QACPgoC,QAAQ,EACRhrC,KAAMirC,QACN/qC,SAAS,EACTgrC,SAAU9jC,IACRojC,iBAAiB,0BAA2BpjC,EAAM,IAMtDtB,KAAKlI,SAASskC,SAASjlC,EAAOC,GAAI,qBAAsB,CACtD2B,KAAMiH,KAAKwF,KAAKE,SAAS,mDACzB5I,KAAMkD,KAAKwF,KAAKE,SAAS,mDACzBxI,MAAO,QACPgoC,QAAQ,EACRhrC,KAAMirC,QACN/qC,SAAS,EACTgrC,SAAU9jC,IACRojC,iBAAiB,qBAAsBpjC,EAAM,IAMjDtB,KAAKlI,SAASskC,SAASjlC,EAAOC,GAAI,YAAa,CAC7C2B,KAAMiH,KAAKwF,KAAKE,SAAS,0CACzB5I,KAAMkD,KAAKwF,KAAKE,SAAS,0CACzBxI,MAAO,SACPgoC,QAAQ,EACRhrC,KAAMC,OACNC,QAAS,OACT4pC,QAAS,CACPwB,KAAMxlC,KAAKwF,KAAKE,SAAS,iDACzB+/B,GAAIzlC,KAAKwF,KAAKE,SAAS,+CACvBggC,KAAM1lC,KAAKwF,KAAKE,SAAS,kDAE3B0/B,SAAU9jC,IACRojC,iBAAiB,YAAapjC,EAAM,IAMxCtB,KAAKlI,SAASskC,SAASjlC,EAAOC,GAAI,OAAQ,CACxC2B,KAAMiH,KAAKwF,KAAKE,SAAS,qCACzB5I,KAAMkD,KAAKwF,KAAKE,SAAS,qCACzBxI,MAAO,SACPgoC,QAAQ,EACRhrC,KAAMirC,QACN/qC,SAAS,EACTgrC,SAAU9jC,IACRojC,iBAAiB,OAAQpjC,EAAM,IAMnCtB,KAAKlI,SAASskC,SAASjlC,EAAOC,GAAI,QAAS,CACzC2B,KAAMiH,KAAKwF,KAAKE,SAAS,sCACzB5I,KAAMkD,KAAKwF,KAAKE,SAAS,sCACzBxI,MAAO,SACPgoC,QAAQ,EACRhrC,KAAMI,OACNypC,MAAO,CACL7iB,IAAK,GACLD,IAAK,EACL0kB,KAAM,KAERvrC,QAAS,EACTgrC,SAAU9jC,IACRojC,iBAAiB,QAASpjC,EAAM,IAMpCtB,KAAKlI,SAASskC,SAASjlC,EAAOC,GAAI,OAAQ,CACxC2B,KAAMiH,KAAKwF,KAAKE,SAAS,qCACzB5I,KAAMkD,KAAKwF,KAAKE,SAAS,qCACzBxI,MAAO,SACPgoC,QAAQ,EACRhrC,KAAMC,OACNC,QAAS,eACT4pC,QAAS,CACP4B,OAAQ5lC,KAAKwF,KAAKE,SAAS,+CAC3BmgC,aAAc7lC,KAAKwF,KAAKE,SAAS,qDACjCogC,MAAO9lC,KAAKwF,KAAKE,SAAS,+CAE5B0/B,SAAU9jC,IACRojC,iBAAiB,OAAQpjC,EAAM,IAMnCtB,KAAKlI,SAASskC,SAASjlC,EAAOC,GAAI,gBAAiB,CACjD2B,KAAMiH,KAAKwF,KAAKE,SAAS,8CACzB5I,KAAMkD,KAAKwF,KAAKE,SAAS,8CACzBxI,MAAO,SACPgoC,QAAQ,EACRhrC,KAAMirC,QACN/qC,SAAS,EACTgrC,SAAU9jC,IACRojC,iBAAiB,gBAAiBpjC,EAAM,IAM5CtB,KAAKlI,SAASskC,SAASjlC,EAAOC,GAAI,oBAAqB,CACrD2B,KAAMiH,KAAKwF,KAAKE,SAAS,kDACzB5I,KAAMkD,KAAKwF,KAAKE,SAAS,kDACzBxI,MAAO,SACPgoC,QAAQ,EACRhrC,KAAMirC,QACN/qC,SAAS,EACTgrC,SAAU9jC,IACRojC,iBAAiB,oBAAqBpjC,EAAM,IAMhDtB,KAAKlI,SAASskC,SAASjlC,EAAOC,GAAI,uBAAwB,CACxD2B,KAAMiH,KAAKwF,KAAKE,SAAS,qDACzB5I,KAAMkD,KAAKwF,KAAKE,SAAS,qDACzBxI,MAAO,SACPgoC,QAAQ,EACRhrC,KAAMirC,QACN/qC,SAAS,EACTgrC,SAAU9jC,IACRojC,iBAAiB,uBAAwBpjC,EAAM,IAMnDtB,KAAKlI,SAASskC,SAASjlC,EAAOC,GAAI,uBAAwB,CACxD2B,KAAMiH,KAAKwF,KAAKE,SAAS,qDACzB5I,KAAMkD,KAAKwF,KAAKE,SAAS,qDACzBxI,MAAO,SACPgoC,QAAQ,EACRhrC,KAAMirC,QACN/qC,SAAS,EACTgrC,SAAU9jC,IACRojC,iBAAiB,uBAAwBpjC,EAAM,IAMnDtB,KAAKlI,SAASskC,SAASjlC,EAAOC,GAAI,cAAe,CAC/C2B,KAAMiH,KAAKwF,KAAKE,SAAS,4CACzB5I,KAAMkD,KAAKwF,KAAKE,SAAS,4CACzBxI,MAAO,SACPgoC,QAAQ,EACRhrC,KAAMirC,QACN/qC,SAAS,EACTgrC,SAAU9jC,IACRojC,iBAAiB,cAAepjC,EAAM,IAM1CtB,KAAKlI,SAASskC,SAASjlC,EAAOC,GAAI,eAAgB,CAChD2B,KAAMiH,KAAKwF,KAAKE,SAAS,6CACzB5I,KAAMkD,KAAKwF,KAAKE,SAAS,6CACzBxI,MAAO,SACPgoC,QAAQ,EACRhrC,KAAMirC,QACN/qC,SAAS,EACTgrC,SAAU9jC,IACRojC,iBAAiB,eAAgBpjC,EAAM,IAM3CtB,KAAKlI,SAASskC,SAASjlC,EAAOC,GAAI,WAAY,CAC5C2B,KAAMiH,KAAKwF,KAAKE,SAAS,yCACzB5I,KAAMkD,KAAKwF,KAAKE,SAAS,yCACzBxI,MAAO,SACPgoC,QAAQ,EACRhrC,KAAMC,OACNC,QAAS,OACT4pC,QAAS,CACP+B,KAAM/lC,KAAKwF,KAAKE,SAAS,iDACzBsgC,SAAUhmC,KAAKwF,KAAKE,SAAS,qDAC7BugC,KAAMjmC,KAAKwF,KAAKE,SAAS,kDAE3B0/B,SAAU9jC,IACRojC,iBAAiB,WAAYpjC,EAAM,IAMvCtB,KAAKlI,SAASskC,SAASjlC,EAAOC,GAAI,eAAgB,CAChD2B,KAAMiH,KAAKwF,KAAKE,SAAS,6CACzB5I,KAAMkD,KAAKwF,KAAKE,SAAS,6CACzBxI,MAAO,SACPgoC,QAAQ,EACRhrC,KAAMI,OACNF,QAAS,KACTgrC,SAAU9jC,IACR4kC,gBAAgB5kC,EAAM,IAM1B,MAAM6kC,EAAehmC,MAAMC,WAAW,iBAAmB,KAOzD,SAAS8lC,gBAAgB70B,GACvB,MAAMgR,EAAOhZ,SAASC,cAAc,SACpC+Y,EAAKpjB,MAAMuL,YAAY,sBAAuB,GAAG6G,MAClD,CATD60B,gBAAgBC,GAaZhmC,MAAM6F,eAAe,cAAgB7F,MAAM6F,eAAe,aAC5DhG,KAAKlI,SAASskC,SAASjlC,EAAOC,GAAI,YAAa,CAC7C2B,KAAMiH,KAAKwF,KAAKE,SAAS,0CACzB5I,KAAMkD,KAAKwF,KAAKE,SAAS,0CACzBxI,MAAO,SACPgoC,QAAQ,EACRhrC,KAAMC,OACN6pC,QAAS,CACPoC,KAAMpmC,KAAKwF,KAAKE,SAAS,kDACzBjH,UAAWuB,KAAKwF,KAAKE,SAAS,uDAC9B7D,SAAU7B,KAAKwF,KAAKE,SAAS,uDAE/BtL,QAAS,OACTgrC,SAAU9jC,IACRojC,iBAAiB,YAAapjC,EAAM,IAO1CtB,KAAKlI,SAASskC,SAASjlC,EAAOC,GAAI,kBAAmB,CACnD2B,KAAMiH,KAAKwF,KAAKE,SAAS,gDACzB5I,KAAMkD,KAAKwF,KAAKE,SAAS,gDACzBxI,MAAO,SACPgoC,QAAQ,EACRhrC,KAAMirC,QACN/qC,SAAS,EACTgrC,SAAU9jC,IACRojC,iBAAiB,kBAAmBpjC,EAAM,IAM9CtB,KAAKlI,SAASskC,SAASjlC,EAAOC,GAAI,QAAS,CACzC2B,KAAMiH,KAAKwF,KAAKE,SAAS,sCACzB5I,KAAMkD,KAAKwF,KAAKE,SAAS,sCACzBxI,MAAO,SACPgoC,QAAQ,EACRhrC,KAAMirC,QACN/qC,SAAS,EACTgrC,SAAU9jC,IACRojC,iBAAiB,QAASpjC,EAAM,IAMpC+kC,8BAEAzyB,EAAc0yB,iBAAiB5B,kBAE/BtlC,EAAOnB,MAAM,0BAA2B,CAAE8mC,gBAC5C,EAOA,SAASsB,8BACP,IAAK,MAAO1hC,EAAKrD,KAAUgJ,OAAOtB,QAAQjP,GACxCiG,KAAKlI,SAASskC,SAASjlC,EAAOC,GAAIuN,EAAK,CACrCzH,MAAO,SACPgoC,QAAQ,EACRhrC,KAAMoH,EAAMpH,KACZE,QAASkH,EAAMlH,SAGrB,CC5dO,MAAMmsC,uCAAuCjE,sBAClD,WAAA9hC,GACE8d,OACD,CAQD,mBAAA+hB,GACE,IAAK3/B,KAAKgC,MAAO,OAEjB,MAAM0B,EAAQ1D,KAAKgC,MAAM0B,MAAM0F,QAAOiqB,GAAQA,EAAK4H,OAAO6K,UAAUhuC,OAAOiuC,UAC3E,IAAKriC,GAAOwD,OAAQ,OAEpB,MAAM8+B,EAAmBvmC,MAAMC,WAAW,aAC1C,GAAyB,aAArBsmC,EAAiC,OAErC,MAAMC,EAAuC,cAArBD,EAExBp8B,OAAOG,OAAO/J,KAAKkS,aAAajG,QAAQoN,SAAQpiB,IAC9C+I,MAAKkmC,GAAiBxiC,EAAOzM,EAAOgvC,EAAgB,GAEvD,CAWD,GAAAC,CAAiBxiC,EAAOzM,EAAO4J,GAE7B,IAAK5J,GAAOqe,SAASpO,OAAQ,OAE7B,MAAMoO,EAAU,GAChB,IAAK,MAAMisB,KAAkBtqC,EAAMqe,QAAS,CAC1C,MAAM+d,EAAO3vB,EAAM5B,MAAKuxB,GAAQA,EAAKtxB,KAAOw/B,EAAex/B,KAC3D,IAAKsxB,EAAM,SAEX,MAAM8S,EAA0BlvC,EAAMqe,QAAQxT,MAAKhL,GAAUA,EAAOiL,KAAO,aAAaw/B,EAAex/B,OACjGqkC,EAAkBD,GAA2B5E,EAE/C4E,IAAyBtlC,GAAU,GAEvC,MAAMwlC,EAAcrmC,MAAKsmC,GAAuBjT,EAAMkO,EAAgB6E,EAAiBvlC,GAElFA,GACHyU,EAAQlS,KAAKijC,GAGVrmC,KAAKmS,cAAcwK,iBAAiBrT,IAAI+8B,EAAYtkC,KACvD/B,KAAKmS,cAAcwK,iBAAiBvY,IAAIiiC,EAAYtkC,GAAIskC,EAE3D,CAEDrmC,MAAK48B,GAAYtnB,EAASre,EAC3B,CAaD,GAAAqvC,CAAuBjT,EAAMkO,EAAgB6E,EAAiBvlC,GAC5D,MAAM/J,EAAS,EAAYsvC,EAAkB3mC,MAAMG,UAAU2hC,GAmB7D,OAlBAzqC,EAAO8pC,aAAe,YAAYW,EAAeX,cAAc2F,OAAOhF,EAAeX,aAAa4F,QAAQ/uC,MAC1GX,EAAOiL,GAAK,aAAaw/B,EAAex/B,KACxCjL,EAAO2pC,SAAWc,EAAed,SACjC3pC,EAAO6f,SAAW,eAAe4qB,EAAed,WAChD3pC,EAAOuB,KAAOkpC,EAAelpC,KAC7BvB,EAAOwM,IAAMi+B,EAAej+B,IAC5BxM,EAAO2vC,cAAgB,aAAa1qC,EAAgBC,uBAAuBD,EAAgBE,gBAC3FnF,EAAOge,SAAWysB,EAAe1pB,cAAgB0pB,EAAexB,eAEhEjpC,EAAOs7B,QAAU,KACf,IACEiB,EAAKqT,cACN,CAAC,MAAM30B,GAEN,OADArT,OAAOnB,MAAM,kBAAmBwU,IACzB,CACR,GAGIjb,CACR,CAUD,GAAA8lC,CAAYtnB,EAASre,GACnBqe,EAAQ+D,SAAQgtB,IACd,MAAMn5B,EAAQjW,EAAMqe,QAAQ0hB,WAAUlgC,GAAUA,EAAOiL,KAAOskC,EAAYtkC,KAAM,EAChF9K,EAAMqe,QAAQnI,OAAOD,EAAO,EAAGm5B,EAAY,GAE9C,EChHI,MAAMM,cACX,WAAA7mC,GACEE,KAAK4mC,aAAenwC,EAAOC,GAC3BsJ,KAAKsT,SAAW,GAChBtT,KAAK+T,OAAS,IACf,CAMD,gBAAA8yB,GAAqB,CAErB,cAAAC,CAAeC,GACb,OAAO,CACR,CAED,wBAAAC,GAA6B,CAE7B,gBAAApB,CAAiB5B,GAAoB,CAErC,sBAAMiD,GAAqB,CAE3B,cAAAC,GAAmB,CASnB,UAAMt5B,SACE5N,MAAKmnC,KACXnnC,MAAKonC,KACLpnC,MAAKokC,IACN,CAYD,QAAM+C,GACJ,MAAM7zB,QAAiBtT,KAAKinC,oBAAsB,GAElDvsB,MAAM0E,QAAQ,qCAAsC9L,GAEhDA,IACFtT,KAAKsT,SAAWA,EAEnB,CAQD,GAAA8zB,GACE,MAAMC,EAAernC,KAAKknC,kBAAoB,CAAA,EAC9ClnC,KAAK+T,OAAS1S,QAAQC,MAAMgmC,YAAYtvC,EAAWqvC,GAEnD3sB,MAAM0E,QAAQ,mCAAoCpf,KAAK+T,OACxD,CAQD,GAAAqwB,GACE,MAAMC,EAAerkC,KAAKgnC,2BAC1B5C,qBAAqBpkC,KAAMqkC,EAAcrkC,KAAK+T,OAC/C,CAUD,oBAAA0F,CAAqBxH,GACnB,MAAME,EAAgBnS,KAAK6mC,mBAC3B10B,EAAce,cAAgBlT,KAE9B,MAAMsP,YAAEA,EAAW4C,aAAEA,GAAiBD,EAUtC,OATAE,EAAcF,WAAaA,EAC3BE,EAAc7C,YAAcA,EAC5B6C,EAAcD,aAAeA,EAC7BC,EAAc0G,SAAW3G,EAAa2G,SAAS4V,KAAKvc,GACpDC,EAAcgH,aAAejH,EAAaiH,aAAasV,KAAKvc,GAC5DlS,MAAKunC,GAA2Br1B,EAAcC,GAE9CuI,MAAM0E,QAAQ,qCAAsCjN,GAE7CA,CACR,CAUD,GAAAo1B,CAA2Br1B,EAAcC,GACnC1S,MAAM6F,eAAe,cAAgB7F,MAAM6F,eAAe,aAC5D6M,EAAcuvB,yBAAyB,IAAImE,+BAA+B3zB,EAAcC,IAG1FuI,MAAM0E,QAAQ,8CAA+CjN,EAC9D,CAUD,kBAAAuH,CAAmBzH,GACjB,IAAI80B,EAAgBtnC,MAAMC,WAAW,eAEb,SAAlBqnC,GAA4BtnC,MAAM6F,eAAeyhC,KACrDroC,EAAOQ,MAAM6nC,EAAeznC,KAAKwF,KAAKE,SAAS,mCAC/C+hC,EAAgB,OAChBtnC,MAAM0E,WAAW,cAAe4iC,IAIlC,MAAM5oC,EAAc6B,KAAK8mC,eAAeC,IAAkB,IAAIlF,YAO9D,OANA1jC,EAAY8T,WAAaA,EAEzBjS,MAAKwnC,GAAyBrpC,GAE9Buc,MAAM0E,QAAQ,mCAAoCjhB,GAE3CA,CACR,CASD,GAAAqpC,CAAyBrpC,GACvBuc,MAAM0E,QAAQ,4CAA6CjhB,EAC5D,CASD,iBAAOspC,CAAWnE,EAASvhC,GACzB,GAAItC,MAAM6F,eAAevD,GAAK,CAC5B,MAAM2D,EAAQjG,MAAMgG,eAAe1D,GACnCV,QAAQC,MAAMgmC,YAAYhE,EAAS,CAAEvhC,CAACA,GAAK2D,GAC5C,CACF,ECvKI,SAASgiC,cACd,MAAMniC,EAASjG,KAAKkG,QAAQtD,IAAIzL,EAAOC,IACvC6O,EAAOuX,IAAM,CACX8kB,4CACAjD,4BACAjxB,wBACJhP,OAAIA,EACAkkC,8BACAf,wBACAgB,wCACA8D,4BACA9mC,YACAJ,aAGFib,MAAM0E,QAAQ,6BAA8B7Z,EAC9C,CCrBA,IAAI2N,EAqBJrG,eAAe86B,mBAAmBC,GAE3BnoC,MAAMiM,yBAAyBk8B,EAAa9qB,KAAKnR,4BAGjDgwB,sBAGLzoB,EAAgB,IAAI00B,EAAa9qB,IAAI6pB,cAAclwC,EAAOC,UACpDwc,EAActF,OAGpBnO,MAAMwK,qBAGF5I,QAAQC,MAAMwH,eAAexJ,KAAKsG,QAAS,WAC7CvE,QAAQiM,aAAau6B,WAAWC,cAAcl+B,OAAOG,OAAOlT,IAE5DixC,cAAcl+B,OAAOG,OAAOlT,IAG9B6jB,MAAM0E,QAAQ,2BAChB,CAOAvS,eAAek7B,cAEb,MAAMp6B,EAASiuB,YAGTtsB,EAAc,IAAI5B,YAAYC,SAC9B2B,EAAY1B,OAGlB,MAAMo6B,EAAmB,IAAIz2B,iBAAiBjC,EAAa3B,SACrDq6B,EAAiBp6B,OAEvBq6B,mBACAC,mBAEA5oC,KAAKC,eAAiB,IAAIqrB,eAAe1X,EAAe5D,EAAa3B,SAC/DrO,KAAKC,eAAeqO,OAE1B8M,MAAM0E,QAAQ,uBAEd9f,KAAKC,eAAeuZ,OAAO,CAAEtf,KAAM,OAAQnB,KAAM,2BACnD,CAOA,SAAS4vC,mBACH3oC,KAAK0E,KAAKoB,OAAS9F,KAAKkG,QAAQtD,IAAI,iBAAiBmD,SAA0C,IAAhC5F,MAAMC,WAAW,aAClFhB,EAAOC,KAAK,+DAA+D,GAC3Ec,MAAM0E,WAAW,WAAW,GAEhC,CASA,SAAS+jC,mBACPxtB,MAAMupB,GAAG,wBAAwB,IAAM3kC,KAAKC,eAAeiwB,eAC3D,MAAM2Y,EAAQ,CACZ,cAAe,cAAe,qBAAsB,qBACpD,eAAgB,eAAgB,eAAgB,kBAChD,mBAAoB,mBAAoB,aAAc,aACtD,aAAc,cAAe,cAAe,cAAe,eAC3D,cAAe,cAAe,sBAAuB,6BAGvDA,EAAM9uB,SAAQ+uB,GAAQ1tB,MAAMupB,GAAGmE,GAAM,IAAI99B,IAAS+9B,gBAAgB,IAAK/9B,GAAQ89B,MACjF,CASA,SAASC,gBAAgBC,EAAUC,GAC5BC,iBAAiBF,EAAUC,IAChCjpC,KAAKC,eAAeuZ,OAAO,CAAEtf,KAAM,OAAQnB,KAAMkwC,EAAUnpC,KAAMkpC,GACnE,CAUA,SAASE,iBAAiBF,EAAUC,GAClC,IAAKjpC,KAAKC,eAAgB,OAAO,EACjC,OAAQgpC,GACN,IAAK,cACL,IAAK,cACH,OAAOjpC,KAAKC,eAAe67B,yBAAyBkN,EAAS,GAAIA,EAAS,IAC5E,IAAK,qBACL,IAAK,qBACH,OAAOhpC,KAAKC,eAAe47B,kBAAkBmN,EAAS,IAAInU,QAC5D,IAAK,kBACL,IAAK,kBACH,OAAO70B,KAAKC,eAAe47B,kBAAkBmN,EAAS,IAAItmC,OAC5D,IAAK,mBACL,IAAK,mBACH,OAAOymC,mBAAmBH,EAASpU,QAAQtb,UAAU7W,IACvD,IAAK,aACL,IAAK,aACL,IAAK,aACH,OAAOzC,KAAKC,eAAe67B,yBAAyBkN,EAAS,IAAItmC,OACnE,IAAK,cACL,IAAK,cACL,IAAK,cAEH,OADA1C,KAAKC,eAAe0S,WAAWE,cAAc2sB,mBAAmBV,cACzD,EACT,IAAK,cACH,OAAOx0B,OAAO8+B,OAAOJ,EAAS,GAAI,WAAahpC,KAAKC,eAAey7B,mBAAmBsN,EAAS,GAAIA,EAAS,IAC9G,QACE,OAAO,EAEb,CASA,SAASG,mBAAmB1mC,GAC1B,MAAM4mC,EAAoBrpC,KAAKC,eAAe0S,WAAWE,cAAc0sB,wBACvE,QAAK8J,EAAkBzK,mBAAmBn8B,KAC1C4mC,EAAkB5L,kBAAoB,IAAI10B,KACnC,EACT,CAWA,SAASugC,uBAAuBC,EAAMC,GACpC,MAAMC,EAAcF,EAAK,IAAMA,EACzBl/B,EAAUo/B,EAAYngC,cAAckgC,GACtCn/B,GAASA,EAAQoa,iBAAiB,cAAeilB,gBACvD,CAOA,SAASA,kBACH1pC,KAAKC,gBAAgBoK,UACvBrK,KAAKC,eAAeoK,QAAQpL,MAAMutB,OAAS,GAE/C,CA5LApR,MAAMuuB,KAAK,kBAAmB1N,gBAC9B7gB,MAAMupB,GAAG,QAASyD,aAClBhtB,MAAMupB,GAAG,4BAA6B0D,oBACtCjtB,MAAMupB,GAAG,0BAA2B8D,aACpCrtB,MAAMupB,GAAG,gBAAgB,CAACiF,EAAGL,IAASD,uBAAuBC,EAAMxnC,QAAQC,MAAMwH,eAAexJ,KAAKsG,QAAS,UAAY,UAAY,cACtI8U,MAAMupB,GAAG,yBAAyB,CAACiF,EAAGL,IAASD,uBAAuBC,EAAMxnC,QAAQC,MAAMwH,eAAexJ,KAAKsG,QAAS,UAAY,gBAAkB"}