diff --git a/ElvUI/Modules/Bags/Bags.lua b/ElvUI/Modules/Bags/Bags.lua
index 5e0d4d8..f719df5 100644
--- a/ElvUI/Modules/Bags/Bags.lua
+++ b/ElvUI/Modules/Bags/Bags.lua
@@ -1438,6 +1438,24 @@ function B:ContructContainerFrame(name, isBank)
f.vendorGraysButton:SetScript("OnLeave", GameTooltip_Hide)
f.vendorGraysButton:SetScript("OnClick", B.VendorGrayCheck)
+ -- Deconstruct button
+ f.deconstructButton = CreateFrame("Button", nil, f.holderFrame)
+ f.deconstructButton:Size(16 + E.Border)
+ f.deconstructButton:SetTemplate()
+ f.deconstructButton:Point("RIGHT", f.vendorGraysButton, "LEFT", -5, 0)
+ f.deconstructButton:SetNormalTexture("Interface\\ICONS\\INV_Rod_Enchantedcobalt")
+ f.deconstructButton:GetNormalTexture():SetTexCoord(unpack(E.TexCoords))
+ f.deconstructButton:GetNormalTexture():SetInside()
+ f.deconstructButton:SetPushedTexture("Interface\\ICONS\\INV_Rod_Enchantedcobalt")
+ f.deconstructButton:GetPushedTexture():SetTexCoord(unpack(E.TexCoords))
+ f.deconstructButton:GetPushedTexture():SetInside()
+ f.deconstructButton:StyleButton(nil, true)
+ f.deconstructButton.ttText = "Deconstruct Mode"
+ f.deconstructButton.ttText2 = "Allow you to disenchant/mill/prospect/unlock items.\nClick to toggle.\nCurrent state: |cffFF0000Disabled|r"
+ f.deconstructButton:SetScript("OnEnter", B.Tooltip_Show)
+ f.deconstructButton:SetScript("OnLeave", GameTooltip_Hide)
+ -- OnClick handler will be set by Deconstruct module
+
--Search
f.editBox = CreateFrame("EditBox", name.."EditBox", f)
f.editBox:SetFrameLevel(f.editBox:GetFrameLevel() + 2)
diff --git a/ElvUI/Modules/Bags/Deconstruct.lua b/ElvUI/Modules/Bags/Deconstruct.lua
new file mode 100644
index 0000000..10e306b
--- /dev/null
+++ b/ElvUI/Modules/Bags/Deconstruct.lua
@@ -0,0 +1,572 @@
+--[[
+ Deconstruct Module for ElvUI (WoW 3.3.5a / Ascension)
+ Adapted from ElvUI_SLE retail version
+
+ This module provides functionality to disenchant, mill, prospect, and unlock items
+ directly from bags by creating an overlay button when mousing over compatible items.
+]] --
+local E, L, V, P, G = unpack(select(2, ...))
+local B = E:GetModule("Bags")
+
+local D = B:NewModule("Deconstruct", "AceHook-3.0", "AceEvent-3.0")
+
+-- Lua functions
+local _G = _G
+local format, strfind, type, tostring = format, strfind, type, tostring
+local pairs, select, unpack = pairs, select, unpack
+
+-- WoW API
+local GetTradeTargetItemLink = GetTradeTargetItemLink
+local InCombatLockdown = InCombatLockdown
+local GetContainerItemLink = GetContainerItemLink
+local GetSpellInfo = GetSpellInfo
+local GetItemInfo = GetItemInfo
+local GetItemCount = GetItemCount
+local CreateFrame = CreateFrame
+local GameTooltip = GameTooltip
+
+-- Constants (with fallbacks in case they're not loaded yet)
+local LOCKED = LOCKED or "Locked"
+local VIDEO_OPTIONS_ENABLED = VIDEO_OPTIONS_ENABLED or "Enabled"
+local VIDEO_OPTIONS_DISABLED = VIDEO_OPTIONS_DISABLED or "Disabled"
+
+-- Module variables
+D.DeconstructMode = false
+D.ItemTable = {
+ ['DoNotDE'] = {
+ ['49715'] = true, -- Rose helm
+ ['44731'] = true, -- Rose offhand
+ ['21524'] = true, -- Red winter hat
+ ['51525'] = true, -- Green winter hat
+ ['70923'] = true, -- Sweater
+ ['34486'] = true, -- Orgrimmar achievement fish
+ ['11287'] = true, -- Lesser Magic Wand
+ ['11288'] = true -- Greater Magic Wand
+ },
+ ['Cooking'] = {
+ ['46349'] = true -- Chef's Hat
+ },
+ ['Fishing'] = {
+ ['19022'] = true, -- Nat Pagle's Extreme Angler FC-5000
+ ['19970'] = true, -- Arcanite Fishing Pole
+ ['25978'] = true, -- Seth's Graphite Fishing Pole
+ ['44050'] = true, -- Mastercraft Kalu'ak Fishing Pole
+ ['45858'] = true, -- Nat's Lucky Fishing Pole
+ ['45991'] = true, -- Bone Fishing Pole
+ ['45992'] = true -- Jeweled Fishing Pole
+ }
+}
+
+D.Keys = {}
+D.BlacklistDE = {}
+D.BlacklistLOCK = {}
+
+-- Profession spell names
+D.DEname = GetSpellInfo(13262) -- Disenchant
+D.MILLname = GetSpellInfo(51005) -- Milling
+D.PROSPECTname = GetSpellInfo(31252) -- Prospecting
+D.LOCKname = GetSpellInfo(1804) -- Pick Lock
+
+-- Check if player has any relevant professions
+function D:HasRelevantProfession()
+ if D.HasEnchanting then return true end
+ if D.HasInscription then return true end
+ if D.HasJewelcrafting then return true end
+ if D.HasPickLock then return true end
+ return false
+end
+
+-- Check which professions the player has
+function D:UpdateProfessions()
+ D.HasEnchanting = false
+ D.HasInscription = false
+ D.HasJewelcrafting = false
+ D.HasPickLock = false
+
+ if D.DEname and GetSpellInfo(D.DEname) then D.HasEnchanting = true end
+ if D.MILLname and GetSpellInfo(D.MILLname) then D.HasInscription = true end
+ if D.PROSPECTname and GetSpellInfo(D.PROSPECTname) then D.HasJewelcrafting = true end
+ if D.LOCKname and GetSpellInfo(D.LOCKname) then D.HasPickLock = true end
+end
+
+-- Helper function to check if player has a skeleton key
+local function HaveKey() for key in pairs(D.Keys) do if GetItemCount(key) > 0 then return key end end end
+
+-- Build blacklist from settings
+function D:Blacklisting(skill) D['BuildBlacklist' .. skill](self) end
+
+function D:BuildBlacklistDE(...)
+ wipe(D.BlacklistDE)
+ for index = 1, select('#', ...) do
+ local name = select(index, ...)
+ if name and name ~= "" then
+ local itemName = GetItemInfo(name)
+ if itemName then D.BlacklistDE[itemName] = true end
+ end
+ end
+end
+
+function D:BuildBlacklistLOCK(...)
+ wipe(D.BlacklistLOCK)
+ for index = 1, select('#', ...) do
+ local name = select(index, ...)
+ if name and name ~= "" then
+ local itemName = GetItemInfo(name)
+ if itemName then D.BlacklistLOCK[itemName] = true end
+ end
+ end
+end
+
+-- Check if item can be disenchanted
+function D:IsBreakable(itemId, itemName, itemQuality, equipSlot)
+ if not itemId then return false end
+ if type(itemId) == "number" then itemId = tostring(itemId) end
+
+ -- Check blacklists
+ if D.ItemTable['DoNotDE'][itemId] then return false end
+ if D.ItemTable['Cooking'][itemId] then return false end
+ if D.ItemTable['Fishing'][itemId] then return false end
+ if D.BlacklistDE[itemName] then return false end
+
+ return true
+end
+
+-- Check if item is disenchantable
+function D:IsDisenchantable(itemId)
+ if not itemId then return false end
+
+ local itemName, itemLink, itemRarity, itemLevel, itemMinLevel, itemType, itemSubType, itemStackCount, itemEquipLoc = GetItemInfo(itemId)
+ if not itemName then return false end
+
+ -- Quality: 2=Uncommon, 3=Rare, 4=Epic
+ if not itemRarity or itemRarity < 2 or itemRarity > 4 then return false end
+
+ if itemType ~= "Armor" and itemType ~= "Weapon" then return false end
+ if not itemEquipLoc or itemEquipLoc == "" then return false end
+ if not D.HasEnchanting then return false end
+
+ return true
+end
+
+-- Check if item can be prospected
+function D:IsProspectable(itemId)
+ if not itemId or not D.HasJewelcrafting then return false end
+
+ -- Prospectable ores in WotLK (3.3.5a)
+ local prospectableOres = {
+ [2770] = true, -- Copper Ore
+ [2771] = true, -- Tin Ore
+ [2772] = true, -- Iron Ore
+ [3858] = true, -- Mithril Ore
+ [10620] = true, -- Thorium Ore
+ [23424] = true, -- Fel Iron Ore
+ [23425] = true, -- Adamantite Ore
+ [36909] = true, -- Cobalt Ore
+ [36912] = true, -- Saronite Ore
+ [36910] = true -- Titanium Ore
+ }
+
+ return prospectableOres[tonumber(itemId)] or false
+end
+
+-- Check if item can be milled
+function D:IsMillable(itemId)
+ if not itemId or not D.HasInscription then return false end
+
+ -- Millable herbs in WotLK (3.3.5a)
+ local millableHerbs = {
+ [765] = true, -- Silverleaf
+ [2447] = true, -- Peacebloom
+ [2449] = true, -- Earthroot
+ [785] = true, -- Mageroyal
+ [2450] = true, -- Briarthorn
+ [2452] = true, -- Swiftthistle
+ [2453] = true, -- Bruiseweed
+ [3820] = true, -- Stranglekelp
+ [3369] = true, -- Grave Moss
+ [3356] = true, -- Kingsblood
+ [3357] = true, -- Liferoot
+ [3818] = true, -- Fadeleaf
+ [3821] = true, -- Goldthorn
+ [3358] = true, -- Khadgar's Whisker
+ [3819] = true, -- Dragon's Teeth (Wintersbite)
+ [8836] = true, -- Arthas' Tears
+ [8838] = true, -- Sungrass
+ [8839] = true, -- Blindweed
+ [8845] = true, -- Ghost Mushroom
+ [8846] = true, -- Gromsblood
+ [13464] = true, -- Golden Sansam
+ [13463] = true, -- Dreamfoil
+ [13465] = true, -- Mountain Silversage
+ [13466] = true, -- Plaguebloom
+ [13467] = true, -- Icecap
+ [22785] = true, -- Felweed
+ [22786] = true, -- Dreaming Glory
+ [22787] = true, -- Ragveil
+ [22789] = true, -- Terocone
+ [22790] = true, -- Ancient Lichen
+ [22791] = true, -- Netherbloom
+ [22792] = true, -- Nightmare Vine
+ [22793] = true, -- Mana Thistle
+ [36901] = true, -- Goldclover
+ [36903] = true, -- Adder's Tongue
+ [36904] = true, -- Tiger Lily
+ [36905] = true, -- Lichbloom
+ [36906] = true, -- Icethorn
+ [36907] = true, -- Talandra's Rose
+ [37921] = true, -- Deadnettle
+ [39970] = true -- Fire Leaf
+ }
+
+ return millableHerbs[tonumber(itemId)] or false
+end
+
+-- Check if item is currently locked (scan tooltip)
+function D:IsUnlockable(itemLink)
+ if not itemLink then return false end
+
+ -- Scan tooltip for "Locked" text
+ GameTooltip:SetOwner(UIParent, "ANCHOR_NONE")
+ GameTooltip:SetHyperlink(itemLink)
+
+ for i = 2, GameTooltip:NumLines() do
+ local line = _G["GameTooltipTextLeft" .. i]
+ if line then
+ local text = line:GetText()
+ if text and strfind(text, LOCKED) then
+ GameTooltip:Hide()
+ return true
+ end
+ end
+ end
+
+ GameTooltip:Hide()
+ return false
+end
+
+-- Apply the deconstruct overlay to a bag slot
+function D:ApplyDeconstruct(itemLink, itemId, spell, spellType, r, g, b, slot)
+ if not slot then return end
+ if slot == D.DeconstructionReal then return end
+
+ local bag = slot:GetParent():GetID()
+
+ -- Verify the bag and slot exist in ElvUI's bag or bank structure
+ local validBag = (B.BagFrame and B.BagFrame.Bags and B.BagFrame.Bags[bag]) or (B.BankFrame and B.BankFrame.Bags and B.BankFrame.Bags[bag])
+ if not validBag then return end
+
+ D.DeconstructionReal.Bag = bag
+ D.DeconstructionReal.Slot = slot:GetID()
+
+ -- Check if in trade window
+ if GetTradeTargetItemLink and GetTradeTargetItemLink(7) == itemLink then
+ return
+ elseif GetContainerItemLink(bag, slot:GetID()) == itemLink then
+ D.DeconstructionReal.ID = itemId
+ D.DeconstructionReal:SetAttribute('type1', spellType)
+ D.DeconstructionReal:SetAttribute(spellType, spell)
+ D.DeconstructionReal:SetAttribute('target-bag', D.DeconstructionReal.Bag)
+ D.DeconstructionReal:SetAttribute('target-slot', D.DeconstructionReal.Slot)
+ D.DeconstructionReal:SetAllPoints(slot)
+ D.DeconstructionReal:Show()
+
+ -- Apply visual effect (ActionButton_ShowOverlayGlow confirmed on Ascension)
+ ActionButton_ShowOverlayGlow(D.DeconstructionReal)
+ end
+end
+
+-- Get deconstruct mode status text
+function D:GetDeconMode()
+ local text
+ if D.DeconstructMode then
+ text = '|cff00FF00 ' .. VIDEO_OPTIONS_ENABLED .. '|r'
+ else
+ text = '|cffFF0000 ' .. VIDEO_OPTIONS_DISABLED .. '|r'
+ end
+ return text
+end
+
+-- Toggle deconstruct mode (called from button click)
+function D:ToggleMode()
+ D.DeconstructMode = not D.DeconstructMode
+
+ if D.DeconstructButton then
+ local normalTex = D.DeconstructButton:GetNormalTexture()
+ if normalTex then
+ if D.DeconstructMode then
+ normalTex:SetTexture([[Interface\ICONS\INV_Enchant_EssenceCosmicGreater]])
+ ActionButton_ShowOverlayGlow(D.DeconstructButton)
+ else
+ normalTex:SetTexture([[Interface\ICONS\INV_Rod_Enchantedcobalt]])
+ ActionButton_HideOverlayGlow(D.DeconstructButton)
+ end
+ end
+
+ D.DeconstructButton.ttText2 = format("Allow you to disenchant/mill/prospect/unlock items.\nClick to toggle.\nCurrent state: %s.", D:GetDeconMode())
+ if GameTooltip:IsOwned(D.DeconstructButton) then B.Tooltip_Show(D.DeconstructButton) end
+ end
+
+ -- Update both bag and bank slots
+ if B.BagFrame then D:UpdateBagSlots(B.BagFrame, D.DeconstructMode) end
+ if B.BankFrame then D:UpdateBagSlots(B.BankFrame, D.DeconstructMode) end
+end
+
+-- Create the actual deconstruct button overlay
+function D:ConstructRealDecButton()
+ D.DeconstructionReal = CreateFrame('Button', 'ElvUI_DeconReal', E.UIParent, 'SecureActionButtonTemplate')
+ D.DeconstructionReal:SetScript('OnEvent', function(obj, event, ...) obj[event](obj, ...) end)
+ D.DeconstructionReal:RegisterForClicks('AnyUp', 'AnyDown')
+ D.DeconstructionReal:SetFrameStrata('TOOLTIP')
+
+ D.DeconstructionReal.OnLeave = function(frame)
+ if InCombatLockdown() then
+ frame:SetAlpha(0)
+ frame:RegisterEvent('PLAYER_REGEN_ENABLED')
+ else
+ frame:ClearAllPoints()
+ frame:SetAlpha(1)
+ if GameTooltip then GameTooltip:Hide() end
+
+ -- Stop visual effects
+ ActionButton_HideOverlayGlow(frame)
+
+ frame:Hide()
+ end
+ end
+
+ D.DeconstructionReal.SetTip = function(f)
+ GameTooltip:SetOwner(f, 'ANCHOR_LEFT', 0, 4)
+ GameTooltip:ClearLines()
+ GameTooltip:SetBagItem(f.Bag, f.Slot)
+ end
+
+ D.DeconstructionReal:SetScript('OnEnter', D.DeconstructionReal.SetTip)
+ D.DeconstructionReal:SetScript('OnLeave', function() D.DeconstructionReal:OnLeave() end)
+ D.DeconstructionReal:Hide()
+
+ function D.DeconstructionReal:PLAYER_REGEN_ENABLED()
+ self:UnregisterEvent('PLAYER_REGEN_ENABLED')
+ D.DeconstructionReal:OnLeave()
+ end
+end
+
+-- Parse tooltip to determine if item should show deconstruct button
+function D:DeconstructParser()
+ if not D.DeconstructMode then return end
+ if not GameTooltip:IsVisible() then return end
+
+ local owner = GameTooltip:GetOwner()
+ if not owner then return end
+
+ local ownerName = owner.GetName and owner:GetName()
+ if not ownerName then return end
+
+ -- Only process ElvUI bag and bank slots
+ if not (strfind(ownerName, 'ElvUI_ContainerFrameBag') or strfind(ownerName, 'ElvUI_BankContainerFrameBag')) then return end
+
+ -- Get the bag and slot from the owner
+ local bag, slot
+ if owner.GetParent then
+ local parent = owner:GetParent()
+ if parent.GetID then bag = parent:GetID() end
+ end
+ if owner.GetID then slot = owner:GetID() end
+
+ if not bag or not slot then return end
+
+ local itemLink = GetContainerItemLink(bag, slot)
+ if not itemLink then return end
+
+ local itemId = tonumber(itemLink:match("item:(%d+)"))
+ if not itemId then return end
+
+ if InCombatLockdown() then return end
+
+ -- Check what can be done with this item
+ local r, g, b
+
+ -- Check for lockboxes
+ local hasKey = HaveKey()
+ if (D.HasPickLock or hasKey) and D:IsUnlockable(itemLink) then
+ r, g, b = 0, 1, 1
+ if D.HasPickLock then
+ D:ApplyDeconstruct(itemLink, itemId, D.LOCKname, 'spell', r, g, b, owner)
+ elseif hasKey then
+ D:ApplyDeconstruct(itemLink, itemId, hasKey, 'item', r, g, b, owner)
+ end
+ return
+ end
+
+ -- Check for prospectable ores (Jewelcrafting only)
+ if D.HasJewelcrafting and D:IsProspectable(itemId) then
+ r, g, b = 1, 0.5, 0
+ D:ApplyDeconstruct(itemLink, itemId, D.PROSPECTname, 'spell', r, g, b, owner)
+ return
+ end
+
+ -- Check for millable herbs (Inscription only)
+ if D.HasInscription and D:IsMillable(itemId) then
+ r, g, b = 0, 1, 0
+ D:ApplyDeconstruct(itemLink, itemId, D.MILLname, 'spell', r, g, b, owner)
+ return
+ end
+
+ -- Check for disenchantable items (Enchanting only)
+ if D.HasEnchanting and D:IsDisenchantable(itemId) then
+ local itemName, _, itemQuality, _, _, _, _, _, equipSlot = GetItemInfo(itemId)
+ if D:IsBreakable(itemId, itemName, itemQuality, equipSlot) then
+ r, g, b = 0.5, 0, 1
+ D:ApplyDeconstruct(itemLink, itemId, D.DEname, 'spell', r, g, b, owner)
+ return
+ end
+ end
+end
+
+-- Check if an item can be processed (disenchant/mill/prospect/unlock)
+function D:CanProcessItem(itemLink, hasKey)
+ if not itemLink then return false end
+
+ local itemId = tonumber(itemLink:match("item:(%d+)"))
+ if not itemId then return false end
+
+ -- Check lockboxes (Rogues only)
+ if (D.HasPickLock or hasKey) and D:IsUnlockable(itemLink) then return true end
+
+ -- Check prospectable (Jewelcrafting only)
+ if D.HasJewelcrafting and D:IsProspectable(itemId) then return true end
+
+ -- Check millable (Inscription only)
+ if D.HasInscription and D:IsMillable(itemId) then return true end
+
+ -- Check disenchantable (Enchanting only)
+ if D.HasEnchanting and D:IsDisenchantable(itemId) then
+ local itemName, _, itemQuality, _, _, _, _, _, equipSlot = GetItemInfo(itemId)
+ if D:IsBreakable(itemId, itemName, itemQuality, equipSlot) then return true end
+ end
+
+ return false
+end
+
+-- Update all bag/bank slots to dim non-processable items
+function D:UpdateBagSlots(frame, isActive)
+ if not frame or not frame.Bags then return end
+
+ local hasKey = HaveKey()
+ for _, bagID in ipairs(frame.BagIDs) do
+ if frame.Bags[bagID] then
+ for slotID = 1, GetContainerNumSlots(bagID) do
+ local slot = frame.Bags[bagID][slotID]
+ if slot then
+ if isActive then
+ -- Dim items that can't be processed
+ local itemLink = GetContainerItemLink(bagID, slotID)
+ if itemLink and D:CanProcessItem(itemLink, hasKey) then
+ slot:SetAlpha(1)
+ else
+ slot:SetAlpha(0.3)
+ end
+ else
+ -- Restore normal alpha
+ slot:SetAlpha(1)
+ end
+ end
+ end
+ end
+ end
+end
+
+-- Helper function to setup button and hooks (called once when bags are first opened)
+local function SetupDeconstructButton()
+ if D.DeconstructButton then return end
+
+ -- Update professions first
+ D:UpdateProfessions()
+
+ -- Only show button if player has relevant professions
+ if not D:HasRelevantProfession() then return end
+
+ if not B.BagFrame or not B.BagFrame.deconstructButton then return end
+
+ -- Store button reference
+ D.DeconstructButton = B.BagFrame.deconstructButton
+ D.DeconstructButton:SetScript("OnClick", function() D:ToggleMode() end)
+
+ -- Only create the real deconstruct button and hooks once
+ if not D.DeconstructionReal then
+ D:ConstructRealDecButton()
+
+ -- Hook GameTooltip to detect when mousing over items
+ GameTooltip:HookScript('OnShow', function() D:DeconstructParser() end)
+ GameTooltip:HookScript('OnUpdate', function() D:DeconstructParser() end)
+ end
+
+ -- Hide deconstruct mode when bags close
+ B.BagFrame:HookScript('OnHide', function()
+ D.DeconstructMode = false
+ if D.DeconstructButton then
+ local normalTex = D.DeconstructButton:GetNormalTexture()
+ if normalTex then normalTex:SetTexture([[Interface\ICONS\INV_Rod_Enchantedcobalt]]) end
+ ActionButton_HideOverlayGlow(D.DeconstructButton)
+ end
+ if B.BagFrame then D:UpdateBagSlots(B.BagFrame, false) end
+ if B.BankFrame then D:UpdateBagSlots(B.BankFrame, false) end
+ if D.DeconstructionReal then D.DeconstructionReal:OnLeave() end
+ end)
+end
+
+-- Initialize the module
+function D:Initialize()
+ if not E.private.bags.enable then return end
+
+ -- Hook into Layout to setup button for bags and reapply dimming
+ hooksecurefunc(B, "Layout", function(_, isBank)
+ if not isBank then if B.BagFrame and not D.DeconstructButton then E:Delay(0.1, function() SetupDeconstructButton() end) end end
+
+ -- Reapply dimming after layout (layout resets slot alpha)
+ if D.DeconstructMode then
+ E:Delay(0.05, function()
+ if B.BagFrame then D:UpdateBagSlots(B.BagFrame, true) end
+ if B.BankFrame then D:UpdateBagSlots(B.BankFrame, true) end
+ end)
+ end
+ end)
+
+ -- Build blacklists
+ D:Blacklisting('DE')
+ D:Blacklisting('LOCK')
+
+ -- Register events
+ D:RegisterEvent('BAG_UPDATE')
+ D:RegisterEvent('SKILL_LINES_CHANGED')
+
+ -- If bag frame already exists, setup button now
+ if B.BagFrame and not D.DeconstructButton then E:Delay(0.1, function() SetupDeconstructButton() end) end
+end
+
+-- Handle SKILL_LINES_CHANGED event
+function D:SKILL_LINES_CHANGED()
+ D:UpdateProfessions()
+
+ -- Show/hide button based on professions
+ local hasProf = D:HasRelevantProfession()
+
+ if D.DeconstructButton then
+ if hasProf then
+ D.DeconstructButton:Show()
+ else
+ D.DeconstructButton:Hide()
+ D.DeconstructMode = false
+ end
+ end
+end
+
+-- Handle BAG_UPDATE event
+function D:BAG_UPDATE()
+ if D.DeconstructMode then
+ if B.BagFrame then D:UpdateBagSlots(B.BagFrame, true) end
+ if B.BankFrame then D:UpdateBagSlots(B.BankFrame, true) end
+ end
+end
+
+-- Wait for ElvUI to fully load before initializing
+hooksecurefunc(B, "Initialize", function() D:Initialize() end)
diff --git a/ElvUI/Modules/Bags/Load_Bags.xml b/ElvUI/Modules/Bags/Load_Bags.xml
index 3213cc4..2b03112 100644
--- a/ElvUI/Modules/Bags/Load_Bags.xml
+++ b/ElvUI/Modules/Bags/Load_Bags.xml
@@ -2,4 +2,5 @@
+
\ No newline at end of file