From a4cd49dbfd1a8361b170c72ae93e216d1bfa5272 Mon Sep 17 00:00:00 2001
From: Meow <30401521+me0wg4ming@users.noreply.github.com>
Date: Wed, 31 Dec 2025 12:20:50 +0100
Subject: [PATCH 01/40] performance updates
performance updates
From 6eca163abd6b90256229834abb14134e947f3944 Mon Sep 17 00:00:00 2001
From: Meow <30401521+me0wg4ming@users.noreply.github.com>
Date: Wed, 31 Dec 2025 12:21:44 +0100
Subject: [PATCH 02/40] performance updates
performance updates
---
modules/actionbar.lua | 91 +-
modules/actionbar_nodebug.lua | 1771 +++++++++++++++++++++++++++++++++
modules/bgscore.lua | 60 ++
modules/chat.lua | 2 +
modules/energytick.lua | 22 +-
modules/nameplates.lua | 3 +
modules/skin.lua | 3 +
modules/tooltip.lua | 4 +
8 files changed, 1938 insertions(+), 18 deletions(-)
create mode 100644 modules/actionbar_nodebug.lua
create mode 100644 modules/bgscore.lua
diff --git a/modules/actionbar.lua b/modules/actionbar.lua
index eabebc55..df1eae1a 100644
--- a/modules/actionbar.lua
+++ b/modules/actionbar.lua
@@ -912,24 +912,40 @@ pfUI:RegisterModule("actionbar", "vanilla:tbc", function ()
end
local cat, stealth
- local function IsCatStealth()
+ local inCatForm = nil -- cached from buff scan
+ local prowlActive = nil -- tracks if prowl is active
+
+ -- Full scan for cat form and prowl (only on login/reload)
+ local function FullScan()
if class ~= "DRUID" then return nil end
- cat, stealth = nil, nil
-
+
+ local foundCat, foundStealth = nil, nil
+
for i = 0, 31 do
local texture = GetPlayerBuffTexture(i)
if not texture then break end
- -- catform icon detected
if strfind(texture, "Ability_Druid_CatForm") then
- if stealth then return true end
- cat = true
+ foundCat = true
end
- -- stealth icon detected
if strfind(texture, "Ability_Ambush") then
- if cat then return true end
- stealth = true
+ foundStealth = true
+ end
+ end
+
+ inCatForm = foundCat
+ prowlActive = foundCat and foundStealth
+ return prowlActive
+ end
+
+ -- Quick scan only for prowl (when we know we're in cat form)
+ local function HasProwlBuff()
+ for i = 0, 31 do
+ local texture = GetPlayerBuffTexture(i)
+ if not texture then break end
+ if strfind(texture, "Ability_Ambush") then
+ return true
end
end
return nil
@@ -956,7 +972,59 @@ pfUI:RegisterModule("actionbar", "vanilla:tbc", function ()
end
-- setup page switch frame
+ local prowling = nil
local pageswitch = CreateFrame("Frame", "pfActionBarPageSwitch", UIParent)
+ pageswitch:RegisterEvent("PLAYER_AURAS_CHANGED")
+ pageswitch:RegisterEvent("PLAYER_ENTERING_WORLD")
+ pageswitch:RegisterEvent("UNIT_CASTEVENT")
+ pageswitch:SetScript("OnEvent", function()
+ if class ~= "DRUID" then return end
+
+ -- UNIT_CASTEVENT: detect Cat Form and Prowl cast instantly
+ -- Cat Form: 768 | Prowl: 5215 (R1), 6783 (R2), 9913 (R3)
+ if event == "UNIT_CASTEVENT" then
+ local guid, target, cEvent, spellId = arg1, arg2, arg3, arg4
+ local _, playerGuid = UnitExists("player")
+ if guid == playerGuid and cEvent == "CAST" then
+ if spellId == 5215 or spellId == 6783 or spellId == 9913 then
+ inCatForm = true
+ prowlActive = true
+ prowling = true
+ elseif spellId == 768 then
+ inCatForm = true
+ end
+ end
+ return
+ end
+
+ -- PLAYER_AURAS_CHANGED: smart scanning
+ if event == "PLAYER_AURAS_CHANGED" then
+ if prowlActive then
+ -- We were prowling, check if still prowling
+ if HasProwlBuff() then
+ prowling = true
+ else
+ -- Prowl ended
+ prowlActive = nil
+ prowling = nil
+ -- Also check if still in cat form
+ inCatForm = nil
+ for i = 0, 31 do
+ local texture = GetPlayerBuffTexture(i)
+ if not texture then break end
+ if strfind(texture, "Ability_Druid_CatForm") then
+ inCatForm = true
+ break
+ end
+ end
+ end
+ elseif not inCatForm then
+ -- Not in cat form, do a full scan (might have just shifted)
+ prowling = FullScan()
+ end
+ -- If inCatForm but not prowlActive, no scan needed (wait for UNIT_CASTEVENT)
+ end
+ end)
pageswitch:SetScript("OnUpdate", function()
-- switch actionbar page depending on meta key that is pressed
if C.bars.pagemastershift == "1" and IsShiftKeyDown() then
@@ -974,10 +1042,9 @@ pfUI:RegisterModule("actionbar", "vanilla:tbc", function ()
-- switch actionbar page if druid stealth is detected
if C.bars.druidstealth == "1" then
- local stealth = IsCatStealth()
- if stealth and _G.CURRENT_ACTIONBAR_PAGE == 1 then
+ if prowling and _G.CURRENT_ACTIONBAR_PAGE == 1 then
SwitchBar(prowl)
- elseif not stealth and _G.CURRENT_ACTIONBAR_PAGE == 8 then
+ elseif not prowling and _G.CURRENT_ACTIONBAR_PAGE == 8 then
SwitchBar(default)
end
end
diff --git a/modules/actionbar_nodebug.lua b/modules/actionbar_nodebug.lua
new file mode 100644
index 00000000..ca9a91ba
--- /dev/null
+++ b/modules/actionbar_nodebug.lua
@@ -0,0 +1,1771 @@
+pfUI:RegisterModule("actionbar", "vanilla:tbc", function ()
+ local _, class = UnitClass("player")
+ local color = RAID_CLASS_COLORS[class]
+ local cr, cg, cb = color.r , color.g, color.b
+ local er, eg, eb, ea = GetStringColor(pfUI_config.appearance.border.color)
+
+ local backdrop_highlight = { edgeFile = pfUI.media["img:glow"], edgeSize = 8 }
+ local showgrid = 0
+ local showgrid_pet = 0
+ local rawborder, border = GetBorderSize("actionbars")
+ local bpad = rawborder > 1 and border - GetPerfectPixel() or GetPerfectPixel()
+
+ local eventcache = { } -- contains a list of events that shall be processed later -> [event] = true
+ local updatecache = { } -- contains a list of buttons slots that shall be refreshed later -> [slot] = true
+ local buttoncache = { } -- contains a list of all buttons ever created -> [slot] = frame
+
+ local petvisibility = "[pet] show; hide"
+
+ -- try to assume based on the current mouse positions if a button drag
+ -- should happen even if action-on-key-down is used. By that replace the
+ -- cast events by reverting the active buttons to the old mouse-up state.
+ local drag_await
+ local drag_active
+ local function AssumeButtonDrag()
+ -- skip during combat
+ if InCombatLockdown and InCombatLockdown() then return end
+
+ -- skip if keydown press is not enabled
+ if C.bars.keydown ~= "1" then return end
+
+ -- skip if always shift-drag is not enabled
+ if C.bars.shiftdrag ~= "1" then return end
+
+ if drag_await and not drag_active and IsShiftKeyDown() then
+ drag_active = true
+ -- set all buttons to regular on release clicks
+ for id, button in pairs(buttoncache) do
+ button:RegisterForClicks("LeftButtonUp", "RightButtonUp")
+ end
+ elseif drag_active and not IsShiftKeyDown() then
+ drag_active = nil
+ -- set all buttons back to their defaults
+ for id, button in pairs(buttoncache) do
+ button:RegisterForClicks("LeftButtonDown", "RightButtonDown")
+ end
+ end
+ end
+
+ -- hide blizzard bars
+ local function kill(f, killshow)
+ if f.Show and killshow then f.Show = function() return end end
+ if f.UnregisterAllEvents then f:UnregisterAllEvents() end
+ if f.Hide then f:Hide() end
+ end
+
+ -- also abbreviate mouse buttons
+ local OrigGetBindingText = GetBindingText
+ local function GetBindingText(msg, mod, abbrev)
+ local txt = OrigGetBindingText(msg, mod, abbrev)
+ if abbrev then
+ txt = string.gsub(txt, _G[string.format("%s%s", mod, "BUTTON3")], "MB3")
+ txt = string.gsub(txt, _G[string.format("%s%s", mod, "BUTTON4")], "MB4")
+ txt = string.gsub(txt, _G[string.format("%s%s", mod, "BUTTON5")], "MB5")
+ txt = string.gsub(txt, _G[string.format("%s%s", mod, "MOUSEWHEELDOWN")], "MWD")
+ txt = string.gsub(txt, _G[string.format("%s%s", mod, "MOUSEWHEELUP")], "MWU")
+ end
+ return txt
+ end
+
+ kill(MainMenuBar)
+
+ local blizzard_elements = { MultiBarBottomLeft,
+ MultiBarBottomRight, MultiBarLeft, MultiBarRight }
+ for _, f in pairs(blizzard_elements) do
+ kill(f, true)
+ end
+
+ -- enable all possible actionbar pages
+ SetActionBarToggles(0, 0, 0, 0)
+ _G.SHOW_MULTI_ACTIONBAR_1 = nil
+ _G.SHOW_MULTI_ACTIONBAR_2 = nil
+ _G.SHOW_MULTI_ACTIONBAR_3 = nil
+ _G.SHOW_MULTI_ACTIONBAR_4 = nil
+
+ -- events that provide special updater functions
+ local special_events = {
+ ["ACTIONBAR_UPDATE_COOLDOWN"] = true,
+ ["ACTIONBAR_UPDATE_USABLE"] = true,
+ ["ACTIONBAR_UPDATE_STATE"] = true,
+ }
+
+ -- events that are shared across all buttons
+ local global_events = {
+ -- slot/button updates
+ ["PLAYER_ENTERING_WORLD"] = true,
+ ["ACTIONBAR_SLOT_CHANGED"] = true,
+ ["UPDATE_BINDINGS"] = true,
+ ["ACTIONBAR_PAGE_CHANGED"] = true,
+ ["UPDATE_BONUS_ACTIONBAR"] = true,
+ ["CRAFT_SHOW"] = true,
+ ["CRAFT_CLOSE"] = true,
+ ["TRADE_SKILL_SHOW"] = true,
+ ["TRADE_SKILL_CLOSE"] = true,
+ ["PLAYER_ENTER_COMBAT"] = true,
+ ["PLAYER_LEAVE_COMBAT"] = true,
+ -- cooldown updates
+ ["UNIT_INVENTORY_CHANGED"] = true,
+ -- auto repeat action
+ ["START_AUTOREPEAT_SPELL"] = true,
+ ["STOP_AUTOREPEAT_SPELL"] = true,
+ }
+
+ -- events that are used for the aura/shapeshift bar
+ local aura_events = {
+ ["UPDATE_SHAPESHIFT_FORMS"] = true,
+ ["PLAYER_AURAS_CHANGED"] = true,
+ }
+
+ -- events that are used for the pet bar
+ local pet_events = {
+ ["PLAYER_CONTROL_LOST"] = true,
+ ["PLAYER_CONTROL_GAINED"] = true,
+ ["PLAYER_FARSIGHT_FOCUS_CHANGED"] = true,
+ ["UNIT_PET"] = true,
+ ["PET_BAR_UPDATE"] = true,
+ ["PET_BAR_UPDATE_COOLDOWN"] = true,
+ }
+
+ local buttontypes = {
+ -- blizzard keybinds
+ [3] = "MULTIACTIONBAR3BUTTON",
+ [4] = "MULTIACTIONBAR4BUTTON",
+ [5] = "MULTIACTIONBAR2BUTTON",
+ [6] = "MULTIACTIONBAR1BUTTON",
+ [11] = "SHAPESHIFTBUTTON",
+ [12] = "BONUSACTIONBUTTON",
+ -- additional keybinds
+ [2] = "PFPAGING",
+ [7] = "PFSTANCEONE",
+ [8] = "PFSTANCETWO",
+ [9] = "PFSTANCETHREE",
+ [10] = "PFSTANCEFOUR",
+ }
+
+ local blizzbarmapping = {
+ ["MultiBarRight"] = 3,
+ ["MultiBarLeft"] = 4,
+ ["MultiBarBottomRight"] = 5,
+ ["MultiBarBottomLeft"] = 6,
+ ["ShapeShiftBar"] = 11,
+ ["BonusActionBar"] = 12,
+ }
+
+ local barnames = {
+ [1] = "Main",
+ [2] = "Paging",
+ [3] = "Right",
+ [4] = "Vertical",
+ [5] = "Left",
+ [6] = "Top",
+ [7] = "StanceBar1",
+ [8] = "StanceBar2",
+ [9] = "StanceBar3",
+ [10] = "StanceBar4",
+ [11] = "Stances",
+ [12] = "Pet",
+ }
+
+ local button_animations = {
+ ["none"] = function()
+ this.active = nil
+ this:Hide()
+ end,
+ ["zoomfade"] = function()
+ if this.active == 0 then
+ -- init animation
+ this:SetWidth(this.parent:GetWidth())
+ this:SetHeight(this.parent:GetHeight())
+ this:SetScale(this.parent:GetScale())
+ this.tex:SetTexture(this.parent.icon:GetTexture())
+ this.tex:SetVertexColor(this.parent.icon:GetVertexColor())
+ this:SetAlpha(1)
+ this.active = 1
+ return
+ elseif this.active == 1 then
+ -- run animation
+ local fade = 30/GetFramerate()*0.05
+ this:SetAlpha(this:GetAlpha() - fade)
+ this:SetScale(this:GetScale() + fade)
+ if this:GetAlpha() > 0 then return end
+ end
+
+ -- stop animation
+ this.active = nil
+ this:Hide()
+ end,
+ ["shrinkreturn"] = function()
+ if this.active == 0 then
+ -- init animation
+ this:SetWidth(this.parent:GetWidth())
+ this:SetHeight(this.parent:GetHeight())
+ this:SetScale(this.parent:GetScale())
+ this.tex:SetTexture(this.parent.icon:GetTexture())
+ this.tex:SetVertexColor(this.parent.icon:GetVertexColor())
+ this:SetAlpha(1)
+ this.parent.icon:Hide()
+ this.active = 1
+ this.time = 0
+ return
+ elseif this.active == 1 then
+ -- run animation
+ this.time = this.time + 30/GetFramerate()*0.1
+ local fade = 1 -math.exp(-this.time)*math.sin(this.time*math.pi)
+ this:SetAlpha(fade)
+ this:SetScale(fade)
+ if this.time < 1 then return end
+ end
+
+ -- stop animation
+ this.active = nil
+ this:Hide()
+ this.parent.icon:Show()
+ end,
+ ["elasticzoom"] = function()
+ if this.active == 0 then
+ -- init animation
+ this:SetWidth(this.parent:GetWidth())
+ this:SetHeight(this.parent:GetHeight())
+ this:SetScale(this.parent:GetScale())
+ this.tex:SetTexture(this.parent.icon:GetTexture())
+ this.tex:SetVertexColor(this.parent.icon:GetVertexColor())
+ this:SetAlpha(1)
+ this.parent.icon:Hide()
+ this.active = 1
+ this.time = 0
+ return
+ elseif this.active == 1 then
+ -- run animation
+ this.time = this.time + 30/GetFramerate()*0.03
+ local fade = 1 -math.exp(-this.time*6)*math.sin(this.time*4*math.pi)
+ this:SetAlpha(fade)
+ this:SetScale(fade)
+ if this.time < 1 then return end
+ end
+
+ -- stop animation
+ this.active = nil
+ this:Hide()
+ this.parent.icon:Show()
+ end,
+ ["wobblezoom"] = function()
+ if this.active == 0 then
+ -- init animation
+ this:SetWidth(this.parent:GetWidth())
+ this:SetHeight(this.parent:GetHeight())
+ this:SetScale(this.parent:GetScale())
+ this.tex:SetTexture(this.parent.icon:GetTexture())
+ this.tex:SetVertexColor(this.parent.icon:GetVertexColor())
+ this:SetAlpha(1)
+ this.parent.icon:Hide()
+ this.active = 1
+ this.time = 0
+ return
+ elseif this.active == 1 then
+ -- run animation
+ this.time = this.time + 30/GetFramerate()*0.02
+ local fade = 1 -math.exp(-this.time*6)*math.sin(this.time*10*math.pi)
+ this:SetAlpha(fade)
+ this:SetScale(fade)
+ if this.time < 1 then return end
+ end
+
+ -- stop animation
+ this.active = nil
+ this:Hide()
+ this.parent.icon:Show()
+ end,
+ }
+
+ local function GetActiveBar()
+ if CURRENT_ACTIONBAR_PAGE == 1 and GetBonusBarOffset() ~= 0 then
+ return NUM_ACTIONBAR_PAGES + GetBonusBarOffset()
+ else
+ return CURRENT_ACTIONBAR_PAGE
+ end
+ end
+
+ local function ButtonDrag(self)
+ -- skip during combat
+ if InCombatLockdown and InCombatLockdown() then return end
+
+ local self = self or this
+
+ if _G.LOCK_ACTIONBAR == "1" and not (pfUI_config.bars.shiftdrag == "1" and IsShiftKeyDown()) then return end
+
+ if self.bar == 12 then
+ PickupPetAction(self.id)
+ else
+ PickupAction(self.id)
+ end
+ end
+
+ local function ButtonDragStop(self)
+ -- skip during combat
+ if InCombatLockdown and InCombatLockdown() then return end
+
+ local self = self or this
+
+ if MacroFrame_SaveMacro then
+ MacroFrame_SaveMacro()
+ end
+
+ if self.bar == 12 then
+ PickupPetAction(self.id)
+ else
+ PlaceAction(self.id)
+ end
+ end
+
+ local mouse
+ local function ButtonAnimate(self)
+ local self = self or this
+ mouse = arg1 and not keystate
+
+ -- trigger action animation
+ if ( pfUI_config.bars.keydown == "1" and keystate == "down" ) or (pfUI_config.bars.keydown == "0" and keystate == "up" ) or self.bar == 11 or mouse then
+ if C.bars.animmode == "keypress" and ( self:GetAlpha() > .1 or C.bars.animalways == "1" ) then
+ self.animation.active = 0
+ self.animation:Show()
+ end
+ end
+
+ -- handle button highlight
+ if keystate == "down" then
+ self.highlight:Show()
+ elseif not MouseIsOver(self) then
+ self.highlight:Hide()
+ end
+ end
+
+ local function ButtonClick(self)
+ local self = self or this
+
+ local grid = self.bar == 12 and showgrid_pet or showgrid
+ local mouse = arg1 and not keystate
+ local keystate = keystate
+ local slfcast = C.bars.altself == "1" and IsAltKeyDown() and true or self.slfcast
+ slfcast = C.bars.rightself == "1" and arg1 and arg1 == "RightButton" and true or slfcast
+ self.slfcast = nil
+
+ if ( pfUI_config.bars.keydown == "1" and keystate == "down" and not drag_active ) or (pfUI_config.bars.keydown == "0" and keystate == "up" or drag_active ) or self.bar == 11 or mouse then
+ if self.bar == 11 then
+ CastShapeshiftForm(self.id)
+ elseif grid == 1 then
+ if self.bar == 12 then
+ PickupPetAction(self.id)
+ else
+ PickupAction(self.id)
+ end
+ elseif self.bar == 12 then
+ if arg1 == "LeftButton" then
+ if IsPetAttackActive(self.id) then
+ PetStopAttack()
+ else
+ CastPetAction(self.id)
+ end
+ else
+ TogglePetAutocast(self.id)
+ end
+ else
+ if MacroFrame_SaveMacro then
+ MacroFrame_SaveMacro()
+ end
+
+ UseAction(self.id, nil, slfcast)
+ end
+ end
+ end
+
+ local function ButtonMacroScan(self)
+ if self.bar > 10 then return end
+ if not self.scanmacro then return end
+ if pfUI.bars.skip_macro then return end
+
+ local macro = GetActionText(self.id)
+ self.spellslot = nil
+ self.booktype = nil
+ if macro then
+ local slot = GetMacroIndexByName(macro)
+ local name, _, body = GetMacroInfo(slot)
+
+ if name and body then
+ local match
+
+ for line in gfind(body, "[^%\n]+") do
+ _, _, match = string.find(line, '^#showtooltip (.+)')
+
+ -- skip any further manual macro scanning on
+ -- gameclients with native macro spell detection
+ if pfUI.client > 11200 and match then
+ self.spellslot = nil
+ self.booktype = nil
+ return
+ end
+
+ -- allow the user to disable the scan
+ if match and strfind(match, "disable") then
+ return
+ end
+
+ if not match then
+ -- add support to specify custom tooltips via:
+ -- /run --showtooltip SPELLNAME
+ _, _, match = string.find(line, '%-%-showtooltip (.+)')
+ end
+
+ if not match then
+ _, _, match = string.find(line, '^/cast (.+)')
+ end
+
+ if not match then
+ _, _, match = string.find(line, '^/pfcast (.+)')
+ end
+
+ if not match then
+ _, _, match = string.find(line, '^/pfmouse (.+)')
+ end
+
+ if not match then
+ _, _, match = string.find(line, 'CastSpellByName%(%"(.+)%"%)')
+ end
+
+ if match then
+ local _, _, spell, rank = string.find(match, '(.+)%((.+)%)')
+ spell = spell or match
+ self.spellslot, self.booktype = libspell.GetSpellIndex(spell, rank)
+
+ if self.spellslot and self.spellslot > 0 then return end
+ end
+ end
+ end
+ end
+ end
+
+ local function ButtonEnter(self)
+ local self = self or this
+
+ -- indicate that dragging could get enabled
+ drag_await = true
+
+ GameTooltip:ClearLines()
+ GameTooltip_SetDefaultAnchor(GameTooltip, self)
+
+ if self.bar == 11 then
+ GameTooltip:SetShapeshift(self.id)
+ elseif self.bar == 12 then
+ local name, _, _, token = GetPetActionInfo(self.id)
+ if token then
+ GameTooltip:AddLine(_G[name])
+ GameTooltip:Show()
+ else
+ GameTooltip:SetPetAction(self.id)
+ end
+ elseif self.spellslot and self.booktype then
+ GameTooltip:SetSpell(self.spellslot, self.booktype)
+ else
+ GameTooltip:SetAction(self.id)
+ end
+
+ self.highlight:Show()
+ end
+
+ local function ButtonLeave(self)
+ local self = self or this
+
+ -- no longer wait for a drag event
+ drag_await = nil
+
+ self.highlight:Hide()
+ GameTooltip:Hide()
+ end
+
+ local start, duration, enable, castable, autocast, token
+ local grid, sid, id, bar, active, texture, _
+ local function ButtonSlotUpdate(self)
+ if not self then return end
+ local self = self or this
+ sid = self.id -- 1 to 120
+
+ -- reset shared variables
+ castable, autocast, token = nil, nil, nil
+
+ -- set the own ID for compatibility to some vanilla addons
+ if pfUI.client <= 11200 then self:SetID(self.id) end
+
+ grid = self.bar == 12 and showgrid_pet or showgrid
+
+ if self.bar == 11 then
+ -- stance button
+ bar = self.bar
+ id = sid
+ texture, _, active = GetShapeshiftFormInfo(id)
+ elseif self.bar == 12 then
+ -- pet button
+ bar = self.bar
+ id = sid
+ _, _, texture, token, active, castable, autocast = GetPetActionInfo(id)
+ texture = token and _G[texture] or texture
+ else
+ active = IsCurrentAction(sid) or IsAutoRepeatAction(sid)
+ texture = GetActionTexture(sid)
+ bar = GetActiveBar()
+ id = self.bar == 1 and self.slot or sid-((self.bar)-1)*12
+ end
+
+ -- overwrite with spell macro texture where possible
+ if self.spellslot and self.booktype then
+ texture = GetSpellTexture(self.spellslot, self.booktype)
+ end
+
+ if not self.showempty and self.backdrop and not texture and grid == 0 then
+ self.backdrop:Hide()
+ self.hide = true
+ else
+ self.backdrop:Show()
+ self.hide = nil
+ end
+
+ -- active border
+ if active then
+ if C.bars.animmode == "statechange" and not self.active:IsShown() then
+ self.animation.active = 0
+ self.animation:Show()
+ end
+
+ self.backdrop:SetBackdropBorderColor(cr,cg,cb,1)
+ self.active:Show()
+ else
+ self.backdrop:SetBackdropBorderColor(er,eg,eb,ea)
+ self.active:Hide()
+ end
+
+ if self.bar ~= 11 and self.bar ~= 12 then
+ -- update consumables
+ if IsConsumableAction(sid) then
+ self.count:SetText(GetActionCount(sid))
+ elseif IsReagentAction and IsReagentAction(sid) then
+ self.count:SetText(GetReagentCount(sid))
+ else
+ self.count:SetText(nil)
+ end
+
+ -- equipped item
+ if IsEquippedAction(sid) and C.bars.showequipped == "1" then
+ self.equipped:Show()
+ else
+ self.equipped:Hide()
+ end
+
+ -- update macro text
+ if C.bars["bar"..self.bar] and C.bars["bar"..self.bar].showmacro == "1" then
+ self.macro:SetText(GetActionText(sid))
+ else
+ self.macro:SetText("")
+ end
+ end
+
+ -- icon
+ if texture ~= self.texture then
+ self.icon:SetTexture(texture)
+ self.texture = texture
+ end
+
+ -- handle pet bar quirks
+ if self.bar == 12 then
+ -- desaturate disabled petbar
+ self.icon:SetDesaturated(not GetPetActionsUsable())
+
+ -- display autocast
+ if autocast then
+ self.autocast:Show()
+ self.autocast:SetAlpha(self:GetAlpha() * 0.10)
+ else
+ self.autocast:Hide()
+ end
+
+ if castable and C.bars.showcastable == "1" then
+ self.autocastable:Show()
+ else
+ self.autocastable:Hide()
+ end
+ end
+
+ -- keybinds
+ if not self.hide and self.bar == 1 and self.bar ~= 11 and self.bar ~= 12 then
+ self.keybind:SetText(GetBindingText(GetBindingKey("ACTIONBUTTON"..id), "KEY_", 1))
+ elseif not self.hide and buttontypes[self.bar] then
+ self.keybind:SetText(GetBindingText(GetBindingKey(buttontypes[self.bar]..id), "KEY_", 1))
+ else
+ self.keybind:SetText("")
+ end
+ end
+
+ local sid, usable, oom, _
+ local function ButtonUsableUpdate(self)
+ local self = self or this
+ sid = self.id -- 1 to 120
+
+ if self.bar == 11 then
+ _, _, _, usable = GetShapeshiftFormInfo(sid)
+ elseif self.bar == 12 then
+ usable = true
+ else
+ usable, oom = IsUsableAction(sid)
+ end
+
+ -- update usable [out-of-range = 1, oom = 2, not-usable = 3, default = 0]
+ if self.outofrange and C.bars.glowrange == "1" then
+ if self.vertexstate ~= 1 then
+ self.icon:SetVertexColor(self.rangeColor[1], self.rangeColor[2], self.rangeColor[3], self.rangeColor[4])
+ self.vertexstate = 1
+ end
+ elseif oom and C.bars.showoom == "1" then
+ if self.vertexstate ~= 2 then
+ self.icon:SetVertexColor(self.oomColor[1], self.oomColor[2], self.oomColor[3], self.oomColor[4])
+ self.vertexstate = 2
+ end
+ elseif not usable and C.bars.showna == "1" then
+ if self.vertexstate ~= 3 then
+ self.icon:SetVertexColor(self.naColor[1], self.naColor[2], self.naColor[3], self.naColor[4])
+ self.vertexstate = 3
+ end
+ else
+ if self.vertexstate ~= 0 then
+ self.icon:SetVertexColor(1, 1, 1, 1)
+ self.vertexstate = 0
+ end
+ end
+ end
+
+ local function ButtonRangeUpdate(self)
+ local self = self or this
+
+ -- update range display
+ if C.bars.glowrange == "1" and self.bar ~= 11 and self.bar ~= 12 and HasAction(self.id) and ActionHasRange(self.id) and IsActionInRange(self.id) == 0 then
+ if not self.outofrange then
+ self.outofrange = true
+ ButtonUsableUpdate(self)
+ end
+ elseif self.outofrange then
+ self.outofrange = nil
+ ButtonUsableUpdate(self)
+ end
+ end
+
+ local start, duration, enable
+ local function ButtonCooldownUpdate(button)
+ if not button then return end
+
+ if button.bar == 11 then
+ start, duration, enable = GetShapeshiftFormCooldown(button.id)
+ elseif button.bar == 12 then
+ start, duration, enable = GetPetActionCooldown(button.id)
+ elseif button.spellslot and button.booktype then
+ start, duration = GetSpellCooldown(button.spellslot, button.booktype)
+ enable = 1
+ else
+ start, duration, enable = GetActionCooldown(button.id)
+ end
+
+ CooldownFrame_SetTimer(button.cd, start, duration, enable)
+ end
+
+ local _, active
+ local function ButtonIsActiveUpdate(button)
+ if not button then return end
+
+ if button.bar == 11 then
+ _, _, active, _ = GetShapeshiftFormInfo(button.id)
+ elseif button.bar == 12 then
+ _, _, _, _, active, _, _ = GetPetActionInfo(button.id)
+ else
+ active = IsCurrentAction(button.id) or IsAutoRepeatAction(button.id)
+ end
+
+ -- active border
+ if active then
+ if not button.border_active then
+ button.backdrop:SetBackdropBorderColor(cr,cg,cb,1)
+ button.border_active = true
+ end
+
+ button.active:Show()
+ else
+ if button.border_active then
+ button.backdrop:SetBackdropBorderColor(er,eg,eb,ea)
+ button.border_active = nil
+ end
+
+ button.active:Hide()
+ end
+ end
+
+
+ local function ButtonFullUpdate(button)
+ if not button then return end
+
+ ButtonMacroScan(button)
+ ButtonSlotUpdate(button)
+ ButtonRangeUpdate(button)
+ ButtonUsableUpdate(button)
+ ButtonCooldownUpdate(button)
+ ButtonIsActiveUpdate(button)
+ end
+
+ local function BarsEvent(self)
+ local self = self or this
+
+ -- refresh only specific slots
+ if event == "ACTIONBAR_SLOT_CHANGED" and arg1 and arg1 ~= 0 then
+ updatecache[arg1] = true
+ return
+ end
+
+ -- run special refresh functions on next update
+ if special_events[event] then
+ eventcache[event] = true
+ return
+ end
+
+ -- handle aura events
+ if aura_events[event] then
+ for j=1,12 do
+ if self[11] and self[11][j] then
+ updatecache[self[11][j].slot] = true
+ end
+ end
+ return
+ end
+
+ -- handle pet events
+ if pet_events[event] then
+ for j=1,12 do
+ if self[12] and self[12][j] then
+ updatecache[self[12][j].slot] = true
+ end
+ end
+ return
+ end
+
+ -- handle global events
+ for id in pairs(buttoncache) do
+ updatecache[id] = true
+ end
+ end
+
+ local self, button, unlock
+ local function BarsUpdate(self)
+ self = self or this
+
+ -- update buttons whenever a button drag is assumed
+ AssumeButtonDrag()
+
+ if pfUI.unlock then
+ -- update all bars when entering unlock
+ if pfUI.unlock:IsShown() ~= unlock then
+ pfUI.bars:UpdateConfig()
+ unlock = pfUI.unlock:IsShown()
+ end
+ end
+
+ -- run cached usable usable actions
+ if eventcache["ACTIONBAR_UPDATE_USABLE"] then
+ eventcache["ACTIONBAR_UPDATE_USABLE"] = nil
+ for id, button in pairs(buttoncache) do
+ ButtonUsableUpdate(button)
+ end
+ end
+
+ -- run cached cooldown events
+ if eventcache["ACTIONBAR_UPDATE_COOLDOWN"] then
+ eventcache["ACTIONBAR_UPDATE_COOLDOWN"] = nil
+ for id, button in pairs(buttoncache) do
+ ButtonCooldownUpdate(button)
+ end
+ end
+
+ -- run cached action state events
+ if eventcache["ACTIONBAR_UPDATE_STATE"] then
+ eventcache["ACTIONBAR_UPDATE_STATE"] = nil
+ for id, button in pairs(buttoncache) do
+ ButtonIsActiveUpdate(button)
+ end
+ end
+
+ for id in pairs(updatecache) do
+ -- run updates based on slot
+ pfUI.bars.ButtonFullUpdate(buttoncache[id])
+
+ -- run updates on paging actionbar if required
+ for i=1,12 do
+ if pfUI.bars[1][i].id == id then
+ pfUI.bars.ButtonFullUpdate(pfUI.bars[1][i])
+ end
+ end
+
+ -- clear update cache
+ updatecache[id] = nil
+ end
+
+ if ( this.tick or .2) > GetTime() then return else this.tick = GetTime() + .2 end
+
+ for id, button in pairs(buttoncache) do
+ if button:IsShown() then ButtonRangeUpdate(button) end
+ end
+ end
+
+ -- create the main event and update handler for pfUI actionbars
+ local bars = CreateFrame("Frame", "pfActionBar", UIParent)
+ for event in pairs(special_events) do bars:RegisterEvent(event) end
+ for event in pairs(global_events) do bars:RegisterEvent(event) end
+ for event in pairs(aura_events) do bars:RegisterEvent(event) end
+ for event in pairs(pet_events) do bars:RegisterEvent(event) end
+
+ -- refresh actionbar buttons on event
+ bars:SetScript("OnEvent", BarsEvent)
+
+ -- update actionbar buttons
+ bars:SetScript("OnUpdate", BarsUpdate)
+
+ -- enable bar paging via secure functions
+ local function ButtonSwitch(self, att, value)
+ if att == "state-parent" then
+ local action = SecureButton_GetModifiedAttribute(self, "action", SecureStateChild_GetEffectiveButton(self)) or self.id
+ if self.id == action then return end
+ updatecache[self.slot] = true
+ self.id = action
+ end
+ end
+
+ local function EnablePaging(bar)
+ if pfUI.client <= 11200 then
+ if not bar.pager then
+ bar.pager = CreateFrame("Frame")
+ bar.pager:RegisterEvent("PLAYER_ENTERING_WORLD")
+ bar.pager:RegisterEvent("UPDATE_BONUS_ACTIONBAR")
+ bar.pager:RegisterEvent("ACTIONBAR_PAGE_CHANGED")
+ bar.pager:SetScript("OnEvent", function()
+ for i=1, 10 do -- reload pageable bars
+ local pageable = C.bars["bar"..i] and C.bars["bar"..i].pageable == "1" and true or nil
+ _G.VIEWABLE_ACTION_BAR_PAGES[i] = pageable
+ end
+
+ local active = GetActiveBar()
+ for i=1,12 do
+ local id = i + (active-1)*12
+ bar[i].id = id
+ updatecache[i] = true
+ end
+ end)
+ end
+ else
+ -- append paging enabled bars to the filter list
+ for i=1,12 do bar[i]:SetScript("OnAttributeChanged", ButtonSwitch) end
+
+ -- fill all possible page states
+ local page, pages = nil, {}
+ while not pages[6] do
+ for i=1, 6 do
+ page = i == 1 and 1 or C.bars["bar"..i] and C.bars["bar"..i].pageable == "1" and i
+ if page then table.insert(pages, page) end
+ end
+ end
+
+ bar:SetAttribute("statemap-page", "$input")
+ bar:SetAttribute("state", (bar:GetAttribute("state-page") or 1))
+
+ -- prio posses bar
+ bar.filter = "[bonusbar: 5] 11;"
+
+ -- set bar 8 for druid stealth if enabled
+ local prowl = class == "DRUID" and C.bars["druidstealth"] == "1" and "8" or "7"
+
+ -- write default pages
+ for state, page in pairs(pages) do
+ if page ~= 1 then -- skip page 1 as it is supposed to stay dynamic for stances
+ bar.filter = string.format("%s[actionbar: %s] %s; ", bar.filter, state, page)
+ end
+ end
+
+ -- write page driver conditions
+ bar.filter = string.format("%s[bonusbar:1,nostealth] 7; [bonusbar:1,stealth] %s; [bonusbar:2] 10; [bonusbar:3] 9; [bonusbar:4] 10; 1", bar.filter, prowl)
+
+ -- prepend pagemaster states if enabled
+ if C.bars.pagemaster == "1" then
+ for mod, page in pairs({ ["shift"] = "6", ["ctrl"] = "5", ["alt"] = "3" }) do
+ bar.filter = string.format("[modifier:%s] %s;", mod, page) .. bar.filter
+ end
+ end
+
+ -- enable page driver conditions
+ RegisterStateDriver(bar, "page", bar.filter)
+ SecureStateHeader_Refresh(bar)
+ end
+ end
+
+ local function SwitchBar(bar)
+ if _G.CURRENT_ACTIONBAR_PAGE ~= bar then
+ _G.CURRENT_ACTIONBAR_PAGE = bar
+ ChangeActionBarPage(bar)
+ end
+ end
+
+ local cat, stealth
+ local inCatForm = nil -- cached from buff scan
+ local prowlActive = nil -- tracks if prowl is active
+
+ -- Full scan for cat form and prowl (only on login/reload)
+ local function FullScan()
+ if class ~= "DRUID" then return nil end
+
+ local foundCat, foundStealth = nil, nil
+
+ for i = 0, 31 do
+ local texture = GetPlayerBuffTexture(i)
+ if not texture then break end
+
+ if strfind(texture, "Ability_Druid_CatForm") then
+ foundCat = true
+ end
+
+ if strfind(texture, "Ability_Ambush") then
+ foundStealth = true
+ end
+ end
+
+ inCatForm = foundCat
+ prowlActive = foundCat and foundStealth
+ return prowlActive
+ end
+
+ -- Quick scan only for prowl (when we know we're in cat form)
+ local function HasProwlBuff()
+ for i = 0, 31 do
+ local texture = GetPlayerBuffTexture(i)
+ if not texture then break end
+ if strfind(texture, "Ability_Ambush") then
+ return true
+ end
+ end
+ return nil
+ end
+
+ -- pagemaster / meta page switch
+ if pfUI.expansion == "vanilla" then
+ local prowl, shift, ctrl, alt, default = 8, 6, 5, 3, 1
+
+ -- set temporary pagemaster bindings keybinds
+ if C.bars.pagemaster == "1" then
+ local modifier = { "ALT", "SHIFT", "CTRL" }
+ local buttons = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "-", "+", "=", "´" }
+ local current = CURRENT_ACTIONBAR_PAGE
+ bars.pagemaster = bars.pagemaster or CreateFrame("Frame", "pfPageMaster", UIParent)
+ bars.pagemaster:RegisterEvent("PLAYER_ENTERING_WORLD")
+ bars.pagemaster:SetScript("OnEvent", function()
+ for _,mod in pairs(modifier) do
+ for _,but in pairs(buttons) do
+ SetBinding(mod.."-"..but)
+ end
+ end
+ end)
+ end
+
+ -- setup page switch frame
+ local prowling = nil
+ local pageswitch = CreateFrame("Frame", "pfActionBarPageSwitch", UIParent)
+ pageswitch:RegisterEvent("PLAYER_AURAS_CHANGED")
+ pageswitch:RegisterEvent("PLAYER_ENTERING_WORLD")
+ pageswitch:RegisterEvent("UNIT_CASTEVENT")
+ pageswitch:SetScript("OnEvent", function()
+ if class ~= "DRUID" then return end
+
+ -- On login/reload: full scan
+ if event == "PLAYER_ENTERING_WORLD" then
+ prowling = FullScan()
+ return
+ end
+
+ -- UNIT_CASTEVENT: detect Prowl cast instantly
+ -- Prowl Spell IDs: 5215 (Rank 1), 6783 (Rank 2), 9913 (Rank 3)
+ if event == "UNIT_CASTEVENT" then
+ local guid, target, cEvent, spellId = arg1, arg2, arg3, arg4
+ local _, playerGuid = UnitExists("player")
+ if guid == playerGuid and cEvent == "CAST" then
+ if spellId == 5215 or spellId == 6783 or spellId == 9913 then
+ -- Prowl cast detected
+ inCatForm = true
+ prowlActive = true
+ prowling = true
+ elseif spellId == 768 then
+ -- Cat Form cast (Spell ID 768)
+ inCatForm = true
+ end
+ end
+ return
+ end
+
+ -- PLAYER_AURAS_CHANGED: smart scanning
+ if event == "PLAYER_AURAS_CHANGED" then
+ if prowlActive then
+ -- We were prowling, check if still prowling
+ if HasProwlBuff() then
+ prowling = true
+ else
+ -- Prowl ended
+ prowlActive = nil
+ prowling = nil
+ -- Also check if still in cat form
+ inCatForm = nil
+ for i = 0, 31 do
+ local texture = GetPlayerBuffTexture(i)
+ if not texture then break end
+ if strfind(texture, "Ability_Druid_CatForm") then
+ inCatForm = true
+ break
+ end
+ end
+ end
+ elseif not inCatForm then
+ -- Not in cat form, do a full scan (might have just shifted)
+ prowling = FullScan()
+ end
+ -- If inCatForm but not prowlActive, no scan needed (wait for UNIT_CASTEVENT)
+ end
+ end)
+ pageswitch:SetScript("OnUpdate", function()
+ -- switch actionbar page depending on meta key that is pressed
+ if C.bars.pagemastershift == "1" and IsShiftKeyDown() then
+ SwitchBar(shift)
+ return
+ elseif C.bars.pagemasterctrl == "1" and IsControlKeyDown() then
+ SwitchBar(ctrl)
+ return
+ elseif C.bars.pagemasteralt == "1" and IsAltKeyDown() then
+ SwitchBar(alt)
+ return
+ elseif C.bars.pagemasteralt == "1" or C.bars.pagemasterctrl == "1" or C.bars.pagemastershift == "1" then
+ SwitchBar(default)
+ end
+
+ -- switch actionbar page if druid stealth is detected
+ if C.bars.druidstealth == "1" then
+ if prowling and _G.CURRENT_ACTIONBAR_PAGE == 1 then
+ SwitchBar(prowl)
+ elseif not prowling and _G.CURRENT_ACTIONBAR_PAGE == 8 then
+ SwitchBar(default)
+ end
+ end
+ end)
+ end
+
+ local function CreateActionButton(parent, bar, button)
+ -- load config
+ local size = C.bars["bar"..bar].icon_size
+ local font = pfUI.media[C.bars.font]
+ local font_offset = tonumber(C.bars.font_offset)
+
+ local macro_size = tonumber(C.bars.macro_size)
+ local macro_color = { strsplit(",", C.bars.macro_color) }
+
+ local count_size = tonumber(C.bars.count_size)
+ local count_color = { strsplit(",", C.bars.count_color) }
+
+ local bind_size = tonumber(C.bars.bind_size)
+ local bind_color = { strsplit(",", C.bars.bind_color) }
+
+ local cd_size = tonumber(C.bars.cd_size)
+
+ local showempty = C.bars["bar"..bar].showempty
+ local showmacro = C.bars["bar"..bar].showmacro
+ local showkybind = C.bars["bar"..bar].showkeybind
+ local showcount = C.bars["bar"..bar].showcount
+
+ -- sanitize font sizes
+ if macro_size == 0 then macro_size = 1 end
+ if count_size == 0 then macro_size = 1 end
+ if bind_size == 0 then macro_size = 1 end
+ if cd_size == 0 then cd_size = nil end
+
+ local button_name = "pfActionBar" .. barnames[bar] .. "Button" .. button
+
+ local id = (bar-1)*12+button
+ local exists = _G[button_name] and true or nil
+ local f = _G[button_name] or CreateFrame("Button", button_name, parent, ACTIONBAR_SECURE_TEMPLATE_BUTTON)
+
+ -- no button available, create a new one
+ if not exists then
+ -- prepare the button for vanilla
+ if not f.HookScript then
+ f.HookScript = HookScript
+ f:SetScript("OnClick", ButtonClick)
+ end
+
+ if bar ~= 11 then
+ f:RegisterForDrag("LeftButton", "RightButton")
+ f:SetScript("OnDragStart", ButtonDrag)
+ f:SetScript("OnReceiveDrag", ButtonDragStop)
+ end
+
+ -- add mouseovers
+ f:SetScript("OnEnter", ButtonEnter)
+ f:SetScript("OnLeave", ButtonLeave)
+
+ -- add click animation handler
+ f:HookScript("OnClick", ButtonAnimate)
+ f.id = id
+
+ -- set a static slot
+ f.slot = id
+
+ -- cooldown
+ f.cd = CreateFrame(COOLDOWN_FRAME_TYPE, f:GetName() .. "Cooldown", f, "CooldownFrameTemplate")
+ f.cd.pfCooldownStyleAnimation = 1
+ f.cd.pfCooldownType = "NOGCD"
+ f.cd.pfCooldownSize = cd_size
+
+ -- icon
+ f.icon = f:CreateTexture(button_name .. "Icon", "BACKGROUND")
+ f.icon:SetTexCoord(.08, .92, .08, .92)
+ f.icon:SetAllPoints()
+
+ -- animation
+ f.animation = CreateFrame("Frame", button_name .. "Animation", f)
+ f.animation.parent = f
+ f.animation:SetPoint("CENTER", 0, 0)
+ f.animation:Hide()
+ f.animation.tex = f.animation:CreateTexture(button_name .. "AnimationTexture", "BACKGROUND")
+ f.animation.tex:SetTexCoord(.08, .92, .08, .92)
+ f.animation.tex:SetAllPoints()
+
+ if bar ~= 11 and bar ~= 12 then
+ -- equipped item
+ f.equipped = f:CreateTexture(nil, "BORDER")
+ f.equipped:SetAllPoints()
+ f.equipped:Hide()
+ elseif bar == 12 then
+ f.autocast = CreateFrame("Model", nil, f)
+ f.autocast:SetAllPoints()
+ f.autocast:SetModel("Interface\\Buttons\\UI-AutoCastButton.mdx")
+ f.autocast:SetSequence(0)
+ f.autocast:SetSequenceTime(0, 0)
+ f.autocast:Hide()
+
+ f.autocastable = f:CreateTexture(nil, "BORDER")
+ f.autocastable:SetAllPoints()
+ f.autocastable:SetTexture("Interface\\Buttons\\UI-AutoCastableOverlay")
+ f.autocastable:SetTexCoord(.25, .75, .25, .75)
+ end
+
+ -- macro
+ f.macro = f:CreateFontString(button_name .. "Name", "LOW", "GameFontNormal")
+
+ -- keybind
+ f.keybind = f:CreateFontString(nil, "LOW", "GameFontNormal")
+
+ -- itemcount
+ f.count = f:CreateFontString(button_name .. "Count", "LOW", "GameFontNormal")
+
+ -- highlight
+ f.highlight = CreateFrame("Frame", nil, f)
+ f.highlight:SetBackdrop(backdrop_highlight)
+ f.highlight:SetBackdropBorderColor(1,1,1,.8)
+ f.highlight:SetAllPoints()
+ f.highlight:Hide()
+
+ -- active
+ f.active = CreateFrame("Frame", nil, f)
+ f.active:SetBackdrop(backdrop_highlight)
+ f.active:SetBackdropBorderColor(1,1,.5,1)
+ f.active:SetAllPoints()
+ f.active:Hide()
+
+ -- add to buttoncache
+ buttoncache[id] = f
+ end
+
+ -- set required attributes for regular tbc buttons
+ if pfUI.client > 11200 then
+ if bar == 11 then
+ f:SetAttribute("type", "spell")
+ f:SetAttribute('spell', select(2, GetShapeshiftFormInfo(button)))
+ elseif bar == 12 then
+ f:SetAttribute("type1", "pet")
+ f:SetAttribute("action1", button)
+ f:SetAttribute("type2", "macro")
+ f:SetAttribute("macrotext2", "/click PetActionButton".. button .. " RightButton")
+ else
+ bars[bar]:SetAttribute("addchild", f)
+ f:SetAttribute("type", "action")
+ f:SetAttribute("action", id)
+ f:SetAttribute("checkselfcast", true)
+ f:SetAttribute("useparent-unit", true)
+ f:SetAttribute("useparent-statebutton", true)
+
+ for state = 0, 11 do -- add custom states
+ local action = ((state == 0 and bar or state)-1)*12+button
+ f:SetAttribute(string.format("*type-S%d", state), "action")
+ f:SetAttribute(string.format("*type-S%dRight", state), "action")
+ f:SetAttribute(string.format("*action-S%d", state), action)
+ f:SetAttribute(string.format("*action-S%dRight", state), action)
+ if C.bars.rightself == "1" then
+ f:SetAttribute(string.format("*unit-S%dRight", state), "player")
+ else
+ f:SetAttribute(string.format("*unit-S%dRight", state), nil)
+ end
+ end
+ end
+ end
+
+ -- set keydown option
+ if C.bars.keydown == "1" then
+ f:RegisterForClicks("LeftButtonDown", "RightButtonDown")
+ else
+ f:RegisterForClicks("LeftButtonUp", "RightButtonUp")
+ end
+
+ -- set animation
+ f.animation:SetScript("OnUpdate", button_animations[C.bars.animation])
+
+ -- pet autocast
+ if bar == 12 then
+ f.autocast:SetScale(C.bars["bar"..bar].icon_size / 25)
+ f.autocast:SetAlpha(.10)
+ end
+
+ -- macro options
+ if showmacro == "1" then f.macro:Show() else f.macro:Hide() end
+ SetAllPointsOffset(f.macro, f, font_offset, -font_offset)
+ f.macro:SetFont(font, macro_size, "OUTLINE")
+ f.macro:SetTextColor(unpack(macro_color))
+ f.macro:SetJustifyH("LEFT")
+ f.macro:SetJustifyV("BOTTOM")
+
+ -- keybind options
+ if showkybind == "1" then f.keybind:Show() else f.keybind:Hide() end
+ SetAllPointsOffset(f.keybind, f, font_offset, -font_offset)
+ f.keybind:SetFont(font, bind_size, "OUTLINE")
+ f.keybind:SetTextColor(unpack(bind_color))
+ f.keybind:SetJustifyH("RIGHT")
+ f.keybind:SetJustifyV("TOP")
+ f.keybind:SetNonSpaceWrap(false)
+
+ -- item count options
+ if showcount == "1" then f.count:Show() else f.count:Hide() end
+ SetAllPointsOffset(f.count, f, font_offset, -font_offset)
+ f.count:SetFont(font, count_size, "OUTLINE")
+ f.count:SetTextColor(unpack(count_color))
+ f.count:SetJustifyH("RIGHT")
+ f.count:SetJustifyV("BOTTOM")
+
+ -- macro spell scan
+ if C.bars.macroscan == "0" then
+ f.scanmacro, f.spellslot, f.booktype = nil, nil, nil
+ else
+ f.scanmacro = true
+ end
+
+ -- range glow color
+ f.rangeColor = { strsplit(",", C.bars.rangecolor) }
+
+ -- out of mana color
+ f.oomColor = { strsplit(",", C.bars.oomcolor) }
+
+ -- not usable color
+ f.naColor = { strsplit(",", C.bars.nacolor) }
+
+ -- equipped color
+ if f.equipped then
+ f.equipped:SetTexture(strsplit(",", C.bars.eqcolor))
+ end
+
+ -- general appearance
+ f.showempty = showempty == "1" and true or nil
+ f:SetHeight(size)
+ f:SetWidth(size)
+ CreateBackdrop(f, border)
+
+ return f
+ end
+
+ local function CreateActionBar(i)
+ -- load config
+ local buttonbasename = "pfActionBar" .. barnames[i] .. "Button"
+ local enable = C.bars["bar"..i].enable
+ local size = C.bars["bar"..i].icon_size
+ local spacing = C.bars["bar"..i].spacing
+ local background = C.bars["bar"..i].background
+ local formfactor = C.bars["bar"..i].formfactor
+ local autohide = C.bars["bar"..i].autohide
+ local hide_time = C.bars["bar"..i].hide_time
+ local hide_combat = C.bars["bar"..i].hide_combat == "1" and true or nil
+
+ local buttons = tonumber(C.bars["bar"..i].buttons) or 12
+ if i == 11 and bars[i] then -- shapeshift buttons
+ buttons = GetNumShapeshiftForms()
+ elseif i == 12 and bars[i] then -- pet buttons
+ buttons = NUM_PET_ACTION_SLOTS
+ elseif i == 12 or i == 11 then
+ -- Fallback to 10 buttons on shapeshift and petbar during initialization.
+ -- This lets us load bars that aren't yet available for your class or level.
+ buttons = 10
+ end
+
+ -- don't process empty bars
+ if buttons == 0 then
+ bars[i]:Hide()
+ return
+ end
+
+ -- the stored layout is invalid, temporary fallback
+ if not pfGridmath[buttons][BarLayoutFormfactor(formfactor)] then
+ formfactor = BarLayoutOptions(buttons)[1]
+ end
+
+ local font = pfUI.font_unit
+ local font_size = C.global.font_unit_size
+
+ local realsize = size+border*2
+
+ -- create frame
+ local init = not bars[i]
+ bars[i] = bars[i] or CreateFrame("Frame", "pfActionBar" .. barnames[i], UIParent, ACTIONBAR_SECURE_TEMPLATE_BAR)
+ bars[i]:SetID(i)
+
+ -- autohide
+ if autohide == "1" then
+ EnableAutohide(bars[i], tonumber(hide_time), hide_combat)
+ else
+ DisableAutohide(bars[i])
+ end
+
+ -- apply visible settings
+ if enable == "1" then
+ -- handle pet bar
+ if i == 12 then
+ if pfUI.client > 11200 then
+ if InCombatLockdown and InCombatLockdown() then
+ -- don't process those events during combat
+ else
+ -- set state driver for pet bars
+ bars[i]:SetAttribute("unit", "pet")
+ local visibility = pfUI.unlock and pfUI.unlock:IsShown() and "show" or petvisibility
+ if bars[i].visibility ~= visibility then
+ RegisterStateDriver(bars[i], 'visibility', visibility)
+ bars[i].visibility = visibility
+ end
+ end
+ else
+ -- only show when pet actions exists
+ if PetHasActionBar() or pfUI.unlock and pfUI.unlock:IsShown() then
+ bars[i]:Show()
+ else
+ bars[i]:Hide()
+ end
+
+ -- show/hide petbar on petbar updates
+ if init then
+ bars[i]:RegisterEvent("PET_BAR_UPDATE")
+ bars[i]:SetScript("OnEvent", function()
+ -- hide obsolete buttons
+ for i=1, NUM_PET_ACTION_SLOTS do
+ if not PetHasActionBar() and bars[12][i] then
+ bars[12][i]:Hide()
+ end
+ end
+ -- refresh layout
+ CreateActionBar(12)
+ end)
+ end
+ end
+
+ -- handle shapeshift bar
+ elseif i == 11 then
+ -- only show when shapeshifts exist
+ if GetNumShapeshiftForms() > 0 then
+ bars[i]:Show()
+ else
+ bars[i]:Hide()
+ end
+
+ -- update shapeshift bar when amount of spells changes
+ if init then
+ bars[i]:RegisterEvent("PLAYER_ENTERING_WORLD")
+ bars[i]:RegisterEvent("UPDATE_BONUS_ACTIONBAR")
+ bars[i]:RegisterEvent("UPDATE_SHAPESHIFT_FORMS")
+ bars[i]:SetScript("OnEvent", function()
+ local count = GetNumShapeshiftForms()
+ if count ~= this.lastCount then
+ this.lastCount = count
+
+ -- hide obsolete buttons
+ for i=1, NUM_SHAPESHIFT_SLOTS do
+ if i > GetNumShapeshiftForms() and bars[11][i] then
+ bars[11][i]:Hide()
+ end
+ end
+
+ -- create new buttons and refresh layout
+ CreateActionBar(11)
+ end
+ end)
+ end
+
+ -- regular bars
+ else
+ bars[i]:Show()
+ end
+
+ elseif enable == "0" then
+ bars[i]:UnregisterAllEvents()
+ bars[i]:Hide()
+ end
+
+ -- create action buttons
+ local maxbuttons = (i == 11 or i == 12) and 10 or 12
+ for j=1,maxbuttons do
+ bars[i][j] = CreateActionButton(bars[i], i, j)
+ bars[i][j].bar = i
+
+ BarButtonAnchor(bars[i][j], buttonbasename, j, buttons, formfactor, size, border, spacing)
+ bars[i][j]:ClearAllPoints()
+ bars[i][j]:SetPoint(unpack(bars[i][j]._anchor))
+ bars[i][j]:Show()
+
+ if i > 10 then
+ bars[i][j].id = j
+ end
+
+ -- refresh button
+ updatecache[bars[i][j].slot] = true
+ end
+
+ for j=buttons+1,12 do
+ if bars[i][j] then
+ bars[i][j]:Hide()
+ end
+ end
+
+ -- add up to 0-11 button parent states to each bar
+ if i <= 10 and pfUI.client > 11200 then
+ bars[i]:SetAttribute("statebutton", "0:S0;1:S1;2:S2;3:S3;4:S4;5:S5;6:S6;7:S7;8:S8;9:S9;10:S10;11:S11;")
+ bars[i]:SetAttribute("statebutton2", "0:S0Right;1:S1Right;2:S2Right;3:S3Right;4:S4Right;5:S5Right;6:S6Right;7:S7Right;8:S8Right;9:S9Right;10:S10Right;11:S11Right;")
+ end
+
+ -- enable paging for the first actionbar
+ if i == 1 then
+ EnablePaging(bars[i])
+ end
+
+ -- adjust actionbar size
+ BarLayoutSize(bars[i], buttons, formfactor, size, border, spacing)
+ bars[i]:SetWidth(bars[i]._size[1])
+ bars[i]:SetHeight(bars[i]._size[2])
+ bars[i]:ClearAllPoints()
+ if i == 1 then -- main
+ bars[i]:SetPoint("BOTTOM", 0, 2*border)
+ elseif i == 3 then -- left
+ bars[i]:SetPoint("BOTTOMLEFT", bars[1], "BOTTOMRIGHT", 3*border, 0)
+ elseif i == 4 then -- vertical
+ bars[i]:SetPoint("RIGHT", -2*border, 0)
+ elseif i == 5 then -- right
+ bars[i]:SetPoint("BOTTOMRIGHT", bars[1], "BOTTOMLEFT", -3*border, 0)
+ elseif i == 6 then -- top
+ bars[i]:SetPoint("BOTTOM", bars[1], "TOP", 0, -spacing)
+ elseif i == 11 then -- stances
+ bars[i]:SetPoint("BOTTOM", bars[6], "TOP", 0, 3*border)
+ elseif i == 12 then -- pet
+ bars[i]:SetPoint("BOTTOM", bars[6], "TOP", 0, 3*border)
+
+ -- make stance bar dodge by default
+ bars[i]:SetScript("OnShow", function()
+ if bars[11] and bars[11]:IsShown() then
+ bars[11]:ClearAllPoints()
+ bars[11]:SetPoint("BOTTOM", bars[12], "TOP", 0, 3*border)
+ UpdateMovable(bars[11], true)
+ end
+ end)
+
+ -- restore old stance bar position
+ bars[i]:SetScript("OnHide", function()
+ if bars[11] and bars[11]:IsShown() then
+ bars[11]:ClearAllPoints()
+ bars[11]:SetPoint("BOTTOM", bars[6], "TOP", 0, 3*border)
+ UpdateMovable(bars[11], true)
+ end
+ end)
+ else -- others
+ bars[i]:SetPoint("TOP", 0, -i*50)
+ end
+
+ UpdateMovable(bars[i])
+
+ -- apply backdrop settings
+ if background == "1" then
+ CreateBackdrop(bars[i], border)
+ CreateBackdropShadow(bars[i])
+ bars[i].backdrop:Show()
+ elseif bars[i].backdrop then
+ bars[i].backdrop:Hide()
+ end
+
+ -- share backdrop of main and top actionbar
+ if bars[6] and bars[1] then
+ bars[6].OnMove = bars[6].OnMove or function()
+ bars[1].mergedBackdrop = bars[1].mergedBackdrop or CreateFrame("Frame", nil, UIParent)
+ bars[1].mergedBackdrop:SetPoint("TOPLEFT", bars[6], "TOPLEFT", 0, 0)
+ bars[1].mergedBackdrop:SetPoint("BOTTOMRIGHT", bars[1], "BOTTOMRIGHT", 0, 0)
+ CreateBackdrop(bars[1].mergedBackdrop)
+
+ local _, anchor, _ = bars[6]:GetPoint()
+ if anchor == bars[1] and C.bars.bar1.enable == "1"
+ and C.bars.bar1.enable == "1" and C.bars.bar6.enable == "1"
+ and C.bars.bar1.background == "1" and C.bars.bar6.background == "1"
+ and C.bars.bar1.autohide == "0" and C.bars.bar6.autohide == "0"
+ and C.bars.bar1.icon_size == C.bars.bar6.icon_size
+ and C.bars.bar1.spacing == C.bars.bar6.spacing
+ and C.bars.bar1.formfactor == C.bars.bar6.formfactor
+ and C.bars.bar1.buttons == C.bars.bar6.buttons
+ then
+ bars[1].mergedBackdrop:Show()
+
+ if C.bars.bar1.background == "1" and bars[1].backdrop then
+ bars[1].backdrop:Hide()
+ end
+
+ if C.bars.bar6.background == "1" and bars[6].backdrop then
+ bars[6].backdrop:Hide()
+ end
+ else
+ bars[1].mergedBackdrop:Hide()
+
+ if C.bars.bar1.background == "1" and bars[1].backdrop then
+ bars[1].backdrop:Show()
+ end
+
+ if C.bars.bar6.background == "1" and bars[6].backdrop then
+ bars[6].backdrop:Show()
+ end
+ end
+ end
+ bars[6].OnMove()
+ end
+ end
+
+ -- create actionbars
+ pfUI.bars = bars
+ pfUI.bars.update = updatecache
+ pfUI.bars.buttons = buttoncache
+ pfUI.bars.ButtonFullUpdate = ButtonFullUpdate
+ pfUI.bars.ButtonEnter = ButtonEnter
+ pfUI.bars.ButtonLeave = ButtonLeave
+
+ pfUI.bars.UpdateGrid = function(self, state, typ)
+ if not typ then
+ showgrid = state
+
+ for id in pairs(buttoncache) do
+ updatecache[id] = true
+ end
+ elseif typ == "PET" then
+ showgrid_pet = state
+ for slot=133,142 do
+ updatecache[slot] = true
+ end
+ end
+ end
+
+ pfUI.bars.UpdateConfig = function(self)
+ for i=1,12 do
+ CreateActionBar(i)
+ end
+ end
+
+ pfUI.bars:UpdateConfig()
+
+ -- Localize custom keybinds for additional actionbars (see Bindings.xml)
+ local names = {
+ ["PAGING"] = T["Paging Actionbar"],
+ ["STANCEONE"] = T["Stance Bar 1"],
+ ["STANCETWO"] = T["Stance Bar 2"],
+ ["STANCETHREE"] = T["Stance Bar 3"],
+ ["STANCEFOUR"] = T["Stance Bar 4"],
+ }
+
+ for name, loc in pairs(names) do
+ _G["BINDING_HEADER_PFBAR"..name] = T["Action Bar"] .. " " .. loc
+ for i=1,12 do
+ _G["BINDING_NAME_PF" .. name .. i] = loc .. " " .. T["Button"] .. " " .. i
+ end
+ end
+
+ -- Map Keybinds to button clicks
+ function _G.pfActionButton(slot, slfcast, opt)
+ if ChatFrameEditBox:IsShown() then return end
+
+ local bar, button = 1, slot
+
+ -- determine the proper bar and button
+ if opt and blizzbarmapping[opt] then
+ bar = blizzbarmapping[opt]
+ elseif slot > 12 then
+ bar, button = ceil(slot/12), mod(slot, 12)
+ button = button == 0 and 12 or button
+ end
+
+ local frame = bars[bar][button]
+ if frame then
+ frame.slfcast = slfcast
+ frame:Click()
+ end
+ end
+
+ -- Set keybinds to all actionbuttons
+ if pfUI.client <= 11200 then
+ -- In order to be able to reuse already defined keybinds, we need to remap
+ -- existing button functions to pfUI. We need to get rid of the blizzard calls
+ -- to avoid having them call texture changes and errors due to missing buttons
+ _G.ActionButtonDown = pfActionButton
+ _G.ActionButtonUp = pfActionButton
+ _G.BonusActionButtonDown = function(slot) pfActionButton(slot, nil, "BonusActionBar") end
+ _G.BonusActionButtonUp = function(slot) pfActionButton(slot, nil, "BonusActionBar") end
+ _G.MultiActionButtonDown = function(bar, slot, slf) pfActionButton(slot, slf, bar) end
+ _G.MultiActionButtonUp = function(bar, slot, slf) pfActionButton(slot, slf, bar) end
+ _G.ShapeshiftBar_ChangeForm = function(slot) pfActionButton(slot, nil, "ShapeShiftBar") end
+ else
+ local bindwraps = {
+ ["ACTIONBUTTON%d"] = 1,
+ ["SHAPESHIFTBUTTON%d"] = 11, -- ShapeShiftBar
+ ["BONUSACTIONBUTTON%d"] = 12, -- BonusActionBar
+ ["MULTIACTIONBAR1BUTTON%d"] = 6, -- MultiBarBottomLeft
+ ["MULTIACTIONBAR2BUTTON%d"] = 5, -- MultiBarBottomRight
+ ["MULTIACTIONBAR3BUTTON%d"] = 3, -- MultiBarRight
+ ["MULTIACTIONBAR4BUTTON%d"] = 4, -- MultiBarLeft
+ ["PFPAGING%d"] = 2,
+ ["PFSTANCEONE%d"] = 7,
+ ["PFSTANCETWO%d"] = 8,
+ ["PFSTANCETHREE%d"] = 9,
+ ["PFSTANCEFOUR%d"] = 10,
+ }
+
+ -- rebind all existing bindings to our own buttons
+ local keybinder = CreateFrame("Frame")
+ keybinder:RegisterEvent("UPDATE_BINDINGS")
+ keybinder:SetScript("OnEvent", function()
+ for name, bar in pairs(bindwraps) do
+ for i=1,12 do
+ local key = GetBindingKey(format(name, i))
+ local button = bars[bar][i]
+ if key and button then
+ SetOverrideBindingClick(button, false, key, button:GetName(), 'LeftButton')
+ end
+ end
+ end
+ end)
+ end
+
+ -- handle drag-drop grid
+ local grid = CreateFrame("Frame")
+ grid:RegisterEvent("ACTIONBAR_SHOWGRID")
+ grid:RegisterEvent("ACTIONBAR_HIDEGRID")
+ grid:RegisterEvent("PET_BAR_SHOWGRID")
+ grid:RegisterEvent("PET_BAR_HIDEGRID")
+
+ grid:SetScript("OnEvent", function()
+ if event == "ACTIONBAR_SHOWGRID" then
+ pfUI.bars:UpdateGrid(1)
+ elseif event == "ACTIONBAR_HIDEGRID" then
+ pfUI.bars:UpdateGrid(0)
+ elseif event == "PET_BAR_SHOWGRID" then
+ pfUI.bars:UpdateGrid(1, "PET")
+ elseif event == "PET_BAR_HIDEGRID" then
+ pfUI.bars:UpdateGrid(0, "PET")
+ end
+ end)
+
+ -- reagent counter
+ if C.bars.reagents == "1" then
+ local reagent_slots = { }
+ local reagent_counts = { }
+ local reagent_capture = SPELL_REAGENTS.."(.+)"
+ local scanner = libtipscan:GetScanner("actionbar")
+
+ local UpdateSlot = function(slot)
+ local texture = GetActionTexture(slot)
+
+ -- update buttons that previously had an reagent
+ if reagent_slots[slot] and not HasAction(slot) then
+ reagent_slots[slot] = nil
+ updatecache[slot] = true
+ end
+
+ -- search for reagent requirements
+ if HasAction(slot) then
+ scanner:SetAction(slot)
+ local _, reagents = scanner:Find(reagent_capture)
+
+ -- remove reagent counts if existing
+ reagents = reagents and string.gsub(reagents, " %((.+)%)", "")
+
+ -- update on reagent requirement changes
+ if reagents and reagent_slots[slot] ~= reagents then
+ reagent_counts[reagents] = reagent_counts[reagents] or 0
+ reagent_slots[slot] = reagents
+ updatecache[slot] = true
+ end
+ end
+ end
+
+ local reagentcounter = CreateFrame("Frame", "pfReagentCounter", UIParent)
+ reagentcounter:RegisterEvent("PLAYER_ENTERING_WORLD")
+ reagentcounter:RegisterEvent("ACTIONBAR_SLOT_CHANGED")
+ reagentcounter:RegisterEvent("BAG_UPDATE")
+ reagentcounter:SetScript("OnEvent", function()
+ if event == "BAG_UPDATE" then
+ this.event = true
+ else
+ this.scan = 1
+ end
+ end)
+
+ -- limit events to one per second and smoothen action scanning
+ reagentcounter:SetScript("OnUpdate", function()
+ -- scan one action slot per frame
+ if this.scan and this.scan <= 120 then
+ UpdateSlot(this.scan)
+ this.scan = this.scan + 1
+ end
+
+ -- trigger reagent count updates after action scans
+ if this.scan and this.scan >= 120 then
+ this.event = true
+ this.scan = nil
+ end
+
+ -- queue events to fire only once per second
+ if not this.event then return end
+ if ( this.tick or 1) > GetTime() then return else this.tick = GetTime() + 1 end
+
+ -- scan for all reagent item counts
+ for item in pairs(reagent_counts) do
+ reagent_counts[item] = GetItemCount(item)
+ end
+
+ -- update all actionbar buttons
+ for slot in pairs(reagent_slots) do
+ updatecache[slot] = true
+ end
+
+ -- remove event trigger
+ this.event = nil
+ end)
+
+ function IsReagentAction(slot)
+ return reagent_slots[slot] and true or nil
+ end
+
+ function GetReagentCount(slot)
+ return reagent_counts[reagent_slots[slot]]
+ end
+ end
+end)
diff --git a/modules/bgscore.lua b/modules/bgscore.lua
new file mode 100644
index 00000000..932f3918
--- /dev/null
+++ b/modules/bgscore.lua
@@ -0,0 +1,60 @@
+pfUI:RegisterModule("bgscore", "vanilla:tbc", function ()
+ local bgframe = WorldStateAlwaysUpFrame
+ if not bgframe then
+ bgframe = CreateFrame("Frame", "WorldStateAlwaysUpFrame", UIParent)
+ bgframe:SetWidth(200)
+ bgframe:SetHeight(25)
+ bgframe:SetPoint("TOP", UIParent, "TOP", 0, -100)
+ end
+
+ local mover = CreateFrame("Frame", "pfUIBGScoreMover", UIParent)
+ mover:SetWidth(220)
+ mover:SetHeight(30)
+ mover:SetPoint("TOP", UIParent, "TOP", 0, -100)
+ mover:SetFrameStrata("DIALOG")
+ mover:SetMovable(true)
+ mover:EnableMouse(true)
+ mover:RegisterForDrag("LeftButton")
+ mover:SetScript("OnDragStart", function() mover:StartMoving() end)
+ mover:SetScript("OnDragStop", function()
+ mover:StopMovingOrSizing()
+ local x = mover:GetLeft()
+ local y = mover:GetTop()
+ pfUI_config = pfUI_config or {}
+ pfUI_config.positions = pfUI_config.positions or {}
+ pfUI_config.positions["WorldStateAlwaysUpFrame"] = { x = x, y = y }
+ bgframe:ClearAllPoints()
+ bgframe:SetPoint("TOPLEFT", UIParent, "BOTTOMLEFT", x, y)
+ DEFAULT_CHAT_FRAME:AddMessage("|cff33ffccBG Score Frame|r position saved.")
+ end)
+ mover:Hide()
+
+ pfUI.api.CreateBackdrop(mover, nil, nil, .8)
+
+ -- Title label
+ local title = mover:CreateFontString(nil, "OVERLAY")
+ title:SetFont("Fonts\\FRIZQT__.TTF", 14, "OUTLINE")
+ title:SetText("Battleground Frames")
+ title:SetPoint("TOP", mover, "TOP", 0, -2)
+
+ -- BG score preview text
+ local bgscore = mover:CreateFontString(nil, "OVERLAY")
+ bgscore:SetFont("Fonts\\FRIZQT__.TTF", 10, "OUTLINE")
+ bgscore:SetText("|cff3399ffAlliance: 123|r | |cffff4444Horde: 456|r")
+ bgscore:SetPoint("BOTTOM", mover, "BOTTOM", 0, 2)
+
+ mover.label = "BG Score"
+ pfUI.unlock.frames = pfUI.unlock.frames or {}
+ table.insert(pfUI.unlock.frames, mover)
+
+ local pos = pfUI_config and pfUI_config.positions and pfUI_config.positions["WorldStateAlwaysUpFrame"]
+ if pos then
+ bgframe:SetPoint("TOPLEFT", UIParent, "BOTTOMLEFT", pos.x, pos.y)
+ mover:SetPoint("TOPLEFT", UIParent, "BOTTOMLEFT", pos.x, pos.y)
+ end
+
+ local origShow = pfUI.unlock.Show
+ local origHide = pfUI.unlock.Hide
+ pfUI.unlock.Show = function(self) origShow(self); mover:Show() end
+ pfUI.unlock.Hide = function(self) origHide(self); mover:Hide(); bgframe:Show() end
+end)
diff --git a/modules/chat.lua b/modules/chat.lua
index ad09a24d..884d027a 100644
--- a/modules/chat.lua
+++ b/modules/chat.lua
@@ -455,6 +455,8 @@ pfUI:RegisterModule("chat", "vanilla:tbc", function ()
if C.chat.global.tabmouse == "1" then
pfUI.chat.mouseovertab = CreateFrame("Frame")
pfUI.chat.mouseovertab:SetScript("OnUpdate", function()
+ -- throttle to 0.1s
+ if ( this.tick or .1) > GetTime() then return else this.tick = GetTime() + .1 end
if pfUI.chat.hideLock then return end
diff --git a/modules/energytick.lua b/modules/energytick.lua
index 8e966afc..d3c8e24d 100644
--- a/modules/energytick.lua
+++ b/modules/energytick.lua
@@ -7,6 +7,9 @@ pfUI:RegisterModule("energytick", "vanilla:tbc", function ()
energytick:RegisterEvent("UNIT_DISPLAYPOWER")
energytick:RegisterEvent("UNIT_ENERGY")
energytick:RegisterEvent("UNIT_MANA")
+ energytick:RegisterEvent("CHAT_MSG_SPELL_SELF_BUFF")
+ energytick:RegisterEvent("CHAT_MSG_SPELL_PERIODIC_SELF_BUFFS")
+
energytick:SetScript("OnEvent", function()
if UnitPowerType("player") == 0 and C.unitframes.player.manatick == "1" then
this.mode = "MANA"
@@ -18,6 +21,14 @@ pfUI:RegisterModule("energytick", "vanilla:tbc", function ()
this:Hide()
end
+ -- Filter nur eigene Energy-Gewinne von Talents/Buffs
+ if event == "CHAT_MSG_SPELL_SELF_BUFF" or event == "CHAT_MSG_SPELL_PERIODIC_SELF_BUFFS" then
+ if string.find(arg1, "You gain") and string.find(arg1, "Energy from") then
+ this.ignoreNextGain = true
+ end
+ return
+ end
+
if event == "PLAYER_ENTERING_WORLD" then
this.lastMana = UnitMana("player")
end
@@ -38,7 +49,10 @@ pfUI:RegisterModule("energytick", "vanilla:tbc", function ()
this.badtick = diff
end
elseif this.mode == "ENERGY" and diff > 0 then
- this.target = 2
+ if not this.ignoreNextGain then
+ this.target = 2
+ end
+ this.ignoreNextGain = false
end
this.lastMana = this.currentMana
end
@@ -69,14 +83,10 @@ pfUI:RegisterModule("energytick", "vanilla:tbc", function ()
energytick.spark:SetWidth(C.unitframes.player.pheight + 5)
energytick.spark:SetBlendMode('ADD')
- -- update spark size on player frame changes
local hookUpdateConfig = pfUI.uf.player.UpdateConfig
function pfUI.uf.player.UpdateConfig()
- -- update spark sizes
energytick.spark:SetHeight(C.unitframes.player.pheight + 15)
energytick.spark:SetWidth(C.unitframes.player.pheight + 5)
-
- -- run default unitframe update function
hookUpdateConfig(pfUI.uf.player)
end
-end)
+end)
\ No newline at end of file
diff --git a/modules/nameplates.lua b/modules/nameplates.lua
index d751ec9d..c181418a 100644
--- a/modules/nameplates.lua
+++ b/modules/nameplates.lua
@@ -321,6 +321,9 @@ pfUI:RegisterModule("nameplates", "vanilla:tbc", function ()
end)
nameplates:SetScript("OnUpdate", function()
+ -- throttle to 10 updates per second instead of every frame
+ if (this.tick or 0.1) > GetTime() then return else this.tick = GetTime() + 0.1 end
+
-- propagate events to all nameplates
if this.eventcache then
this.eventcache = nil
diff --git a/modules/skin.lua b/modules/skin.lua
index dbf64c1a..7c890016 100644
--- a/modules/skin.lua
+++ b/modules/skin.lua
@@ -2,6 +2,9 @@ pfUI:RegisterModule("skin", "vanilla:tbc", function ()
-- align UIParent panels
pfUI.panelalign = CreateFrame("Frame", "pfUIParentPanelAlign", UIParent)
pfUI.panelalign:SetScript("OnUpdate", function()
+ -- throttle to 5 updates per second instead of every frame
+ if (this.tick or 0.2) > GetTime() then return else this.tick = GetTime() + 0.2 end
+
local left = UIParent.left
local center = UIParent.center
local rbpos, ropos
diff --git a/modules/tooltip.lua b/modules/tooltip.lua
index f45159ed..03c51040 100644
--- a/modules/tooltip.lua
+++ b/modules/tooltip.lua
@@ -33,6 +33,10 @@ pfUI:RegisterModule("tooltip", "vanilla:tbc", function ()
tooltip.cursor:SetWidth(tonumber(C.tooltip.cursoroffset) * 2)
tooltip.cursor:SetHeight(tonumber(C.tooltip.cursoroffset) * 2)
tooltip.cursor:SetScript("OnUpdate", function()
+ -- throttle to 0.1s - cursor following doesn't need to be every frame
+ if (this.tick or 0) > GetTime() then return end
+ this.tick = GetTime() + 0.1
+
local scale = UIParent:GetScale()
local x, y = GetCursorPosition()
this:SetPoint("CENTER", UIParent, "BOTTOMLEFT", x/scale, y/scale)
From 2fe5603e6e655b17d42a0206225078fb9a61a5bb Mon Sep 17 00:00:00 2001
From: Meow <30401521+me0wg4ming@users.noreply.github.com>
Date: Wed, 31 Dec 2025 12:22:09 +0100
Subject: [PATCH 03/40] performance updates
performance updates
---
libs/libpredict.lua | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/libs/libpredict.lua b/libs/libpredict.lua
index 448876c8..77701f0b 100644
--- a/libs/libpredict.lua
+++ b/libs/libpredict.lua
@@ -96,6 +96,10 @@ libpredict:SetScript("OnEvent", function()
end)
libpredict:SetScript("OnUpdate", function()
+ -- throttle cleanup to 0.1s - no need to check every frame
+ if (this.tick or 0) > GetTime() then return end
+ this.tick = GetTime() + 0.1
+
-- update on timeout events
for timestamp, targets in pairs(events) do
if GetTime() >= timestamp then
From b8c8214feac175531536f24e0170ff6efca8d2cf Mon Sep 17 00:00:00 2001
From: Meow <30401521+me0wg4ming@users.noreply.github.com>
Date: Wed, 31 Dec 2025 12:28:10 +0100
Subject: [PATCH 04/40] Update README.md
---
README.md | 122 +-----------------------------------------------------
1 file changed, 1 insertion(+), 121 deletions(-)
diff --git a/README.md b/README.md
index 6e556887..0c9fbe83 100644
--- a/README.md
+++ b/README.md
@@ -1,121 +1 @@
-# pfUI
-
-An AddOn for World of Warcraft: Vanilla (1.12.1) and The Burning Crusade (2.4.3), which aims to be a full replacement for the original interface. The design is inspired by several screenshots I've seen from TukUI, ElvUI and others. This addon delivers modern features and a minimalistic style that's easy to use right from the start. It is entirely written from scratch without any inclusion of third-party addons or libraries.
-
-This is **not** an addon-pack like [ShaguUI](http://shagu.org/ShaguUI/), however, there is support for external addons like MobHealth3, DPSMate and others, but they will never be shipped within the package.
-
-**Please do not re-upload or distribute outdated versions of this project. However, you are more than welcome to fork or link to the official github page.**
-
-## Screenshots
-
-
-
-
-
-
-## Installation (Vanilla)
-1. Download **[Latest Version](https://github.com/shagu/pfUI/archive/master.zip)**
-2. Unpack the Zip file
-3. Rename the folder "pfUI-master" to "pfUI"
-4. Copy "pfUI" into Wow-Directory\Interface\AddOns
-5. Restart Wow
-
-## Installation (The Burning Crusade)
-1. Download **[Latest Version](https://github.com/shagu/pfUI/archive/master.zip)**
-2. Unpack the Zip file
-3. Rename the folder "pfUI-master" to "pfUI-tbc"
-4. Copy "pfUI-tbc" into Wow-Directory\Interface\AddOns
-5. Restart Wow
-
-## Commands
-
- /pfui Open the configuration GUI
- /share Open the configuration import/export dialog
- /gm Open the ticket Dialog
- /rl Reload the whole UI
- /farm Toggles the Farm-Mode
- /pfcast Same as /cast but for mouseover units
- /focus Creates a Focus-Frame for the current target
- /castfocus Same as /cast but for focus frame
- /clearfocus Clears the Focus-Frame
- /swapfocus Toggle Focus and Target-Frame
- /pftest Toggle pfUI Unitframe Test Mode
- /abp Addon Button Panel
-
-## Languages
-pfUI supports and contains language specific code for the following gameclients.
-* English (enUS)
-* Korean (koKR)
-* French (frFR)
-* German (deDE)
-* Chinese (zhCN)
-* Spanish (esES)
-* Russian (ruRU)
-
-## Recommended Addons
-* [pfQuest](https://shagu.org/pfQuest) A simple database and quest helper
-* [WIM](http://addons.us.to/addon/wim), [WIM (continued)](https://github.com/shirsig/WIM) Give whispers an instant messenger feel
-
-## Plugins
-* [pfUI-eliteoverlay](https://shagu.org/pfUI-eliteoverlay) Add elite dragons to unitframes
-* [pfUI-fonts](https://shagu.org/pfUI-fonts) Additional fonts for pfUI
-* [pfUI-CustomMedia](https://github.com/mrrosh/pfUI-CustomMedia) Additional textures for pfUI
-* [pfUI-Gryphons](https://github.com/mrrosh/pfUI-Gryphons) Add back the gryphons to your actionbars
-
-## FAQ
-**What does "pfUI" stand for?**
-The term "*pfui!*" is german and simply stands for "*pooh!*", because I'm not a
-big fan of creating configuration UI's, especially not via the Wow-API
-(you might have noticed that in ShaguUI).
-
-**How can I donate?**
-You can donate via [GitHub](https://github.com/sponsors/shagu) or [Ko-fi](https://ko-fi.com/shagu)
-
-**How do I report a Bug?**
-Please provide as much information as possible in the [Bugtracker](https://github.com/shagu/pfUI/issues).
-If there is an error message, provide the full content of it. Just telling that "there is an error" won't help any of us.
-Please consider adding additional information such as: since when did you got the error,
-does it still happen using a clean configuration, what other addons are loaded and which version you're running.
-When playing with a non-english client, the language might be relevant too. If possible, explain how people can reproduce the issue.
-
-**How can I contribute?**
-Report errors and issues in the [Bugtracker](https://github.com/shagu/pfUI/issues).
-Please make sure to have the latest version installed and check for conflicting addons beforehand.
-
-**I have bad performance, what can I do?**
-There's only one known performance issue: that is while using "Frame Shadows". Make sure to disable those
-in the pfUI settings (Settings -> Appearance -> Enable Frame Shadows). If you still have a low performance,
-it's most likely a combination with another addon. Disable all AddOns but pfUI and then enable one-by-one,
-till the performance problem occurs again. Make sure to report the identified AddOn and what you did to reproduce
-via the [Bugtracker](https://github.com/shagu/pfUI/issues).
-
-**Where is the happiness indicator for pets?**
-The pet happiness is shown as the color of your pet's frame. Depending on your skin, this can either be the text or the background color of your pet's healthbar:
-
-- Green = Happy
-- Yellow = Content
-- Red = Unhappy
-
-Since version 4.0.7 there is also an additional icon that can be enabled from the pet unit frame options.
-
-**Can I use Clique with pfUI?**
-This addon already includes support for clickcasting. If you still want to make use of clique, all pfUI's unitframes are already compatible to Clique-TBC. For Vanilla, a pfUI compatible version can be found [Here](https://github.com/shagu/Clique/archive/master.zip). If you want to keep your current version of Clique, you'll have to apply this [Patch](https://github.com/shagu/Clique/commit/a5ee56c3f803afbdda07bae9cd330e0d4a75d75a).
-
-**Where is the Experience Bar?**
-The experience bar shows up on mouseover and whenever you gain experience, next to left chatframe by default. There's also an option to make it stay visible all the time.
-
-**How do I show the Damage- and Threatmeter Dock?**
-If you enabled the "dock"-feature for your external (third-party) meters such as DPSMate or KTM, then you'll be able to toggle between them and the Right Chat by clicking on the ">" symbol on the bottom-right panel.
-
-**Why is my chat always resetting to only 3 lines of text?**
-This happens if "Simple Chat" is enabled in blizzards interface settings (Advanced Options).
-Paste the following command into your chat to disable that option: `/run SIMPLE_CHAT="0"; pfUI.chat.SetupPositions(); ReloadUI()`
-
-**How can I enable mouseover cast?**
-On Vanilla, create a macro with "/pfcast SPELLNAME". If you also want to see the cooldown, You might want to add "/run if nil then CastSpellByName("SPELLNAME") end" on top of the macro. For The Burning Crusade, just use the regular mouseover macros.
-
-**Will there be pfUI for Activision's "Classic" remakes?**
-No, it would require an entire rewrite of the AddOn since the game is now a different one. The AddOn-API has evolved during the last 15 years and the new "Classic" versions are based on a current retail gameclient. I don't plan to play any of those new versions, so I won't be porting any of my addons to it.
-
-**Everything from scratch?! Are you insane?**
-Most probably, yes.
+pfUI performance updates, use on own risk.
From 6be7731d3e1438fa3e9975ca05a63fed847b247c Mon Sep 17 00:00:00 2001
From: Meow <30401521+me0wg4ming@users.noreply.github.com>
Date: Wed, 31 Dec 2025 12:39:25 +0100
Subject: [PATCH 05/40] performance update
performance update
From 6c86d83352a1a2b01545f67fe4360f2bb7aae38f Mon Sep 17 00:00:00 2001
From: Meow <30401521+me0wg4ming@users.noreply.github.com>
Date: Wed, 31 Dec 2025 12:46:04 +0100
Subject: [PATCH 06/40] performance update
performance update
---
api/unitframes.lua | 151 +++++++++++++++++++++++++++++++++++++--------
1 file changed, 125 insertions(+), 26 deletions(-)
diff --git a/api/unitframes.lua b/api/unitframes.lua
index 9c1b9465..36e8eaed 100644
--- a/api/unitframes.lua
+++ b/api/unitframes.lua
@@ -14,6 +14,79 @@ end)
pfUI.uf.frames = {}
pfUI.uf.delayed = {}
+-- =====================================================
+-- ZENTRALER EVENT-HANDLER für Raid/Party Performance
+-- =====================================================
+pfUI.uf.unitmap = {} -- Maps "raid1" -> frame, "party2" -> frame, etc.
+
+pfUI.uf.RebuildUnitmap = function()
+ -- Clear old mappings
+ for k in pairs(pfUI.uf.unitmap) do
+ pfUI.uf.unitmap[k] = nil
+ end
+
+ -- Rebuild raid mappings
+ if pfUI.uf.raid then
+ for i = 1, 40 do
+ local frame = pfUI.uf.raid[i]
+ if frame and frame.id and frame.id ~= 0 then
+ pfUI.uf.unitmap["raid" .. frame.id] = frame
+ end
+ end
+ end
+
+ -- Rebuild party mappings
+ for i = 1, 4 do
+ local frame = _G["pfGroup" .. i]
+ if frame and frame.label == "party" then
+ pfUI.uf.unitmap["party" .. frame.id] = frame
+ end
+ end
+end
+
+pfUI.uf.eventframe = CreateFrame("Frame")
+pfUI.uf.eventframe:RegisterEvent("UNIT_HEALTH")
+pfUI.uf.eventframe:RegisterEvent("UNIT_MAXHEALTH")
+pfUI.uf.eventframe:RegisterEvent("UNIT_MANA")
+pfUI.uf.eventframe:RegisterEvent("UNIT_MAXMANA")
+pfUI.uf.eventframe:RegisterEvent("UNIT_RAGE")
+pfUI.uf.eventframe:RegisterEvent("UNIT_MAXRAGE")
+pfUI.uf.eventframe:RegisterEvent("UNIT_ENERGY")
+pfUI.uf.eventframe:RegisterEvent("UNIT_MAXENERGY")
+pfUI.uf.eventframe:RegisterEvent("UNIT_AURA")
+pfUI.uf.eventframe:RegisterEvent("UNIT_PORTRAIT_UPDATE")
+pfUI.uf.eventframe:RegisterEvent("UNIT_MODEL_CHANGED")
+pfUI.uf.eventframe:RegisterEvent("UNIT_DISPLAYPOWER")
+pfUI.uf.eventframe:RegisterEvent("UNIT_FACTION")
+pfUI.uf.eventframe:RegisterEvent("RAID_ROSTER_UPDATE")
+pfUI.uf.eventframe:RegisterEvent("PARTY_MEMBERS_CHANGED")
+
+pfUI.uf.eventframe:SetScript("OnEvent", function()
+ -- Unitmap neu aufbauen bei Roster-Änderungen
+ if event == "RAID_ROSTER_UPDATE" or event == "PARTY_MEMBERS_CHANGED" then
+ pfUI.uf.RebuildUnitmap()
+ return
+ end
+
+ if not arg1 then return end
+
+ -- Direkt den richtigen Frame finden
+ local frame = pfUI.uf.unitmap[arg1]
+ if not frame then return end
+
+ -- Event verarbeiten (gleiche Logik wie vorher)
+ if event == "UNIT_PORTRAIT_UPDATE" or event == "UNIT_MODEL_CHANGED" then
+ frame.update_portrait = true
+ elseif event == "UNIT_AURA" then
+ frame.update_aura = true
+ elseif event == "UNIT_FACTION" then
+ frame.update_pvp = true
+ else
+ frame.update_full = true
+ end
+end)
+-- =====================================================
+
-- slash command to toggle unitframe test mode
_G.SLASH_PFTEST1, _G.SLASH_PFTEST2 = "/pftest", "/pfuftest"
_G.SlashCmdList.PFTEST = function()
@@ -51,6 +124,9 @@ local function BuffOnUpdate()
end
local function TargetBuffOnUpdate()
+ -- throttle to 0.1s
+ if ( this.tick or .1) > GetTime() then return else this.tick = GetTime() + .1 end
+
local name, rank, icon, count, duration, timeleft = _G.UnitBuff("target", this.id)
if duration and timeleft then
CooldownFrame_SetTimer(this.cd, GetTime() + timeleft - duration, duration, 1)
@@ -921,6 +997,13 @@ function pfUI.uf.OnUpdate()
-- update combat feedback
if this.feedbackText then CombatFeedback_OnUpdate(arg1) end
+ -- Throttle for raid/party frames: only process updates every 0.1s
+ -- This reduces OnUpdate calls from 5760/sec (40 frames * 144fps) to ~400/sec
+ if this.label == "raid" or this.label == "party" then
+ if (this.tick or 0) > GetTime() then return end
+ this.tick = GetTime() + 0.1
+ end
+
-- process indicator update events
if this.update_indicators then
pfUI.uf:RefreshIndicators(this)
@@ -1164,33 +1247,49 @@ end
function pfUI.uf:EnableEvents()
local f = self
+ local unitstr = f.label .. f.id
- f:RegisterEvent("PLAYER_ENTERING_WORLD")
- f:RegisterEvent("UNIT_DISPLAYPOWER")
- f:RegisterEvent("UNIT_HEALTH")
- f:RegisterEvent("UNIT_MAXHEALTH")
- f:RegisterEvent("UNIT_MANA")
- f:RegisterEvent("UNIT_MAXMANA")
- f:RegisterEvent("UNIT_RAGE")
- f:RegisterEvent("UNIT_MAXRAGE")
- f:RegisterEvent("UNIT_ENERGY")
- f:RegisterEvent("UNIT_MAXENERGY")
- f:RegisterEvent("UNIT_FOCUS")
- f:RegisterEvent("UNIT_PORTRAIT_UPDATE")
- f:RegisterEvent("UNIT_MODEL_CHANGED")
- f:RegisterEvent("UNIT_FACTION")
- f:RegisterEvent("UNIT_AURA") -- frame=buff, frame=debuff
- f:RegisterEvent("PLAYER_AURAS_CHANGED") -- label=player && frame=buff
- f:RegisterEvent("UNIT_INVENTORY_CHANGED") -- label=player && frame=buff
- f:RegisterEvent("PARTY_MEMBERS_CHANGED") -- label=party, frame=leaderIcon
- f:RegisterEvent("PARTY_LEADER_CHANGED") -- frame=leaderIcon
- f:RegisterEvent("RAID_ROSTER_UPDATE") -- label=raidIcon
- f:RegisterEvent("PLAYER_UPDATE_RESTING") -- label=restIcon
- f:RegisterEvent("PLAYER_TARGET_CHANGED") -- label=target
- f:RegisterEvent("PARTY_LOOT_METHOD_CHANGED") -- frame=lootIcon
- f:RegisterEvent("RAID_TARGET_UPDATE") -- frame=raidIcon
- f:RegisterEvent("UNIT_PET")
- f:RegisterEvent("UNIT_HAPPINESS")
+ -- Raid/Party Frames: Registriere im zentralen Handler statt selbst
+ if f.label == "raid" or f.label == "party" then
+ -- Nur nicht-UNIT_* Events selbst registrieren
+ f:RegisterEvent("PLAYER_ENTERING_WORLD")
+ f:RegisterEvent("PARTY_MEMBERS_CHANGED")
+ f:RegisterEvent("PARTY_LEADER_CHANGED")
+ f:RegisterEvent("RAID_ROSTER_UPDATE")
+ f:RegisterEvent("PARTY_LOOT_METHOD_CHANGED")
+ f:RegisterEvent("RAID_TARGET_UPDATE")
+
+ -- Unitmap aktualisieren
+ pfUI.uf.RebuildUnitmap()
+ else
+ -- Alle anderen Frames: Normale Event-Registrierung
+ f:RegisterEvent("PLAYER_ENTERING_WORLD")
+ f:RegisterEvent("UNIT_DISPLAYPOWER")
+ f:RegisterEvent("UNIT_HEALTH")
+ f:RegisterEvent("UNIT_MAXHEALTH")
+ f:RegisterEvent("UNIT_MANA")
+ f:RegisterEvent("UNIT_MAXMANA")
+ f:RegisterEvent("UNIT_RAGE")
+ f:RegisterEvent("UNIT_MAXRAGE")
+ f:RegisterEvent("UNIT_ENERGY")
+ f:RegisterEvent("UNIT_MAXENERGY")
+ f:RegisterEvent("UNIT_FOCUS")
+ f:RegisterEvent("UNIT_PORTRAIT_UPDATE")
+ f:RegisterEvent("UNIT_MODEL_CHANGED")
+ f:RegisterEvent("UNIT_FACTION")
+ f:RegisterEvent("UNIT_AURA")
+ f:RegisterEvent("PLAYER_AURAS_CHANGED")
+ f:RegisterEvent("UNIT_INVENTORY_CHANGED")
+ f:RegisterEvent("PARTY_MEMBERS_CHANGED")
+ f:RegisterEvent("PARTY_LEADER_CHANGED")
+ f:RegisterEvent("RAID_ROSTER_UPDATE")
+ f:RegisterEvent("PLAYER_UPDATE_RESTING")
+ f:RegisterEvent("PLAYER_TARGET_CHANGED")
+ f:RegisterEvent("PARTY_LOOT_METHOD_CHANGED")
+ f:RegisterEvent("RAID_TARGET_UPDATE")
+ f:RegisterEvent("UNIT_PET")
+ f:RegisterEvent("UNIT_HAPPINESS")
+ end
f:RegisterForClicks('LeftButtonUp', 'RightButtonUp',
'MiddleButtonUp', 'Button4Up', 'Button5Up')
From 96c005239db189255682e9d6abaa5ef349441db2 Mon Sep 17 00:00:00 2001
From: Meow <30401521+me0wg4ming@users.noreply.github.com>
Date: Sat, 3 Jan 2026 12:33:07 +0100
Subject: [PATCH 07/40] performance update
---
modules/actionbar.lua | 93 +----
modules/actionbar_nodebug.lua | 35 +-
modules/addonbuttons.lua | 2 +-
modules/addons.lua | 2 +-
modules/afkcam.lua | 2 +-
modules/autovendor.lua | 2 +-
modules/bags.lua | 6 +-
modules/bgscore.lua | 2 +-
modules/bubbles.lua | 2 +-
modules/buff.lua | 2 +-
modules/buffwatch.lua | 2 +-
modules/castbar.lua | 21 +-
modules/chat.lua | 26 +-
modules/chatcopy.lua | 2 +-
modules/combopoints.lua | 2 +-
modules/cooldown.lua | 15 +-
modules/easteregg.lua | 2 +-
modules/energytick.lua | 2 +-
modules/farmmode.lua | 2 +-
modules/feigndeath.lua | 2 +-
modules/firstrun.lua | 2 +-
modules/focus.lua | 2 +-
modules/group.lua | 2 +-
modules/gryphons.lua | 2 +-
modules/gui.lua | 64 +--
modules/hoverbind.lua | 2 +-
modules/infight.lua | 2 +-
modules/loot.lua | 2 +-
modules/map.lua | 2 +-
modules/mapreveal.lua | 2 +-
modules/minimap.lua | 4 +-
modules/mirrortimers.lua | 2 +-
modules/nameplates.lua | 3 +-
modules/nampower.lua | 743 +++++++++++++++++++++++++++++++++
modules/panel.lua | 2 +-
modules/pet.lua | 2 +-
modules/pettarget.lua | 2 +-
modules/pixelperfect.lua | 2 +-
modules/player.lua | 2 +-
modules/questitem.lua | 6 +-
modules/raid.lua | 7 +-
modules/roll.lua | 2 +-
modules/screenshot.lua | 2 +-
modules/sellvalue.lua | 2 +-
modules/share.lua | 2 +-
modules/skin.lua | 2 +-
modules/socialmod.lua | 2 +-
modules/superwow.lua | 379 +++++++++++++++--
modules/target.lua | 2 +-
modules/targettarget.lua | 2 +-
modules/targettargettarget.lua | 2 +-
modules/thirdparty.lua | 14 +-
modules/tooltip.lua | 2 +-
modules/totems.lua | 5 +-
modules/uf_tukui.lua | 2 +-
modules/unitxp.lua | 234 +++++++++++
modules/unlock.lua | 2 +-
modules/unusable.lua | 2 +-
modules/updatenotify.lua | 2 +-
modules/xpbar.lua | 2 +-
60 files changed, 1485 insertions(+), 258 deletions(-)
create mode 100644 modules/nampower.lua
create mode 100644 modules/unitxp.lua
diff --git a/modules/actionbar.lua b/modules/actionbar.lua
index df1eae1a..10e542dc 100644
--- a/modules/actionbar.lua
+++ b/modules/actionbar.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("actionbar", "vanilla:tbc", function ()
+pfUI:RegisterModule("actionbar", "vanilla", function ()
local _, class = UnitClass("player")
local color = RAID_CLASS_COLORS[class]
local cr, cg, cb = color.r , color.g, color.b
@@ -395,14 +395,6 @@ pfUI:RegisterModule("actionbar", "vanilla:tbc", function ()
for line in gfind(body, "[^%\n]+") do
_, _, match = string.find(line, '^#showtooltip (.+)')
- -- skip any further manual macro scanning on
- -- gameclients with native macro spell detection
- if pfUI.client > 11200 and match then
- self.spellslot = nil
- self.booktype = nil
- return
- end
-
-- allow the user to disable the scan
if match and strfind(match, "disable") then
return
@@ -1176,39 +1168,6 @@ pfUI:RegisterModule("actionbar", "vanilla:tbc", function ()
buttoncache[id] = f
end
- -- set required attributes for regular tbc buttons
- if pfUI.client > 11200 then
- if bar == 11 then
- f:SetAttribute("type", "spell")
- f:SetAttribute('spell', select(2, GetShapeshiftFormInfo(button)))
- elseif bar == 12 then
- f:SetAttribute("type1", "pet")
- f:SetAttribute("action1", button)
- f:SetAttribute("type2", "macro")
- f:SetAttribute("macrotext2", "/click PetActionButton".. button .. " RightButton")
- else
- bars[bar]:SetAttribute("addchild", f)
- f:SetAttribute("type", "action")
- f:SetAttribute("action", id)
- f:SetAttribute("checkselfcast", true)
- f:SetAttribute("useparent-unit", true)
- f:SetAttribute("useparent-statebutton", true)
-
- for state = 0, 11 do -- add custom states
- local action = ((state == 0 and bar or state)-1)*12+button
- f:SetAttribute(string.format("*type-S%d", state), "action")
- f:SetAttribute(string.format("*type-S%dRight", state), "action")
- f:SetAttribute(string.format("*action-S%d", state), action)
- f:SetAttribute(string.format("*action-S%dRight", state), action)
- if C.bars.rightself == "1" then
- f:SetAttribute(string.format("*unit-S%dRight", state), "player")
- else
- f:SetAttribute(string.format("*unit-S%dRight", state), nil)
- end
- end
- end
- end
-
-- set keydown option
if C.bars.keydown == "1" then
f:RegisterForClicks("LeftButtonDown", "RightButtonDown")
@@ -1335,40 +1294,26 @@ pfUI:RegisterModule("actionbar", "vanilla:tbc", function ()
if enable == "1" then
-- handle pet bar
if i == 12 then
- if pfUI.client > 11200 then
- if InCombatLockdown and InCombatLockdown() then
- -- don't process those events during combat
- else
- -- set state driver for pet bars
- bars[i]:SetAttribute("unit", "pet")
- local visibility = pfUI.unlock and pfUI.unlock:IsShown() and "show" or petvisibility
- if bars[i].visibility ~= visibility then
- RegisterStateDriver(bars[i], 'visibility', visibility)
- bars[i].visibility = visibility
- end
- end
+ -- only show when pet actions exists
+ if PetHasActionBar() or pfUI.unlock and pfUI.unlock:IsShown() then
+ bars[i]:Show()
else
- -- only show when pet actions exists
- if PetHasActionBar() or pfUI.unlock and pfUI.unlock:IsShown() then
- bars[i]:Show()
- else
- bars[i]:Hide()
- end
+ bars[i]:Hide()
+ end
- -- show/hide petbar on petbar updates
- if init then
- bars[i]:RegisterEvent("PET_BAR_UPDATE")
- bars[i]:SetScript("OnEvent", function()
- -- hide obsolete buttons
- for i=1, NUM_PET_ACTION_SLOTS do
- if not PetHasActionBar() and bars[12][i] then
- bars[12][i]:Hide()
- end
- end
- -- refresh layout
- CreateActionBar(12)
- end)
- end
+ -- show/hide petbar on petbar updates
+ if init then
+ bars[i]:RegisterEvent("PET_BAR_UPDATE")
+ bars[i]:SetScript("OnEvent", function()
+ -- hide obsolete buttons
+ for i=1, NUM_PET_ACTION_SLOTS do
+ if not PetHasActionBar() and bars[12][i] then
+ bars[12][i]:Hide()
+ end
+ end
+ -- refresh layout
+ CreateActionBar(12)
+ end)
end
-- handle shapeshift bar
diff --git a/modules/actionbar_nodebug.lua b/modules/actionbar_nodebug.lua
index ca9a91ba..9edd0469 100644
--- a/modules/actionbar_nodebug.lua
+++ b/modules/actionbar_nodebug.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("actionbar", "vanilla:tbc", function ()
+pfUI:RegisterModule("actionbar", "vanilla", function ()
local _, class = UnitClass("player")
local color = RAID_CLASS_COLORS[class]
local cr, cg, cb = color.r , color.g, color.b
@@ -1184,39 +1184,6 @@ pfUI:RegisterModule("actionbar", "vanilla:tbc", function ()
buttoncache[id] = f
end
- -- set required attributes for regular tbc buttons
- if pfUI.client > 11200 then
- if bar == 11 then
- f:SetAttribute("type", "spell")
- f:SetAttribute('spell', select(2, GetShapeshiftFormInfo(button)))
- elseif bar == 12 then
- f:SetAttribute("type1", "pet")
- f:SetAttribute("action1", button)
- f:SetAttribute("type2", "macro")
- f:SetAttribute("macrotext2", "/click PetActionButton".. button .. " RightButton")
- else
- bars[bar]:SetAttribute("addchild", f)
- f:SetAttribute("type", "action")
- f:SetAttribute("action", id)
- f:SetAttribute("checkselfcast", true)
- f:SetAttribute("useparent-unit", true)
- f:SetAttribute("useparent-statebutton", true)
-
- for state = 0, 11 do -- add custom states
- local action = ((state == 0 and bar or state)-1)*12+button
- f:SetAttribute(string.format("*type-S%d", state), "action")
- f:SetAttribute(string.format("*type-S%dRight", state), "action")
- f:SetAttribute(string.format("*action-S%d", state), action)
- f:SetAttribute(string.format("*action-S%dRight", state), action)
- if C.bars.rightself == "1" then
- f:SetAttribute(string.format("*unit-S%dRight", state), "player")
- else
- f:SetAttribute(string.format("*unit-S%dRight", state), nil)
- end
- end
- end
- end
-
-- set keydown option
if C.bars.keydown == "1" then
f:RegisterForClicks("LeftButtonDown", "RightButtonDown")
diff --git a/modules/addonbuttons.lua b/modules/addonbuttons.lua
index c083163f..319ebf3d 100644
--- a/modules/addonbuttons.lua
+++ b/modules/addonbuttons.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("addonbuttons", "vanilla:tbc", function ()
+pfUI:RegisterModule("addonbuttons", "vanilla", function ()
if not pfUI.minimap then return end
if C.abuttons.enable == "0" then return end
diff --git a/modules/addons.lua b/modules/addons.lua
index 220035c8..da35d396 100644
--- a/modules/addons.lua
+++ b/modules/addons.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("addons", "vanilla:tbc", function ()
+pfUI:RegisterModule("addons", "vanilla", function ()
local rawborder, border = GetBorderSize()
-- add main menu button
diff --git a/modules/afkcam.lua b/modules/afkcam.lua
index a9d55d0d..504ad036 100644
--- a/modules/afkcam.lua
+++ b/modules/afkcam.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("afkcam", "vanilla:tbc", function ()
+pfUI:RegisterModule("afkcam", "vanilla", function ()
local MARKED_AFK_CAPTURE = SanitizePattern(MARKED_AFK_MESSAGE)
local social_chats = {
"CHAT_MSG_SAY",
diff --git a/modules/autovendor.lua b/modules/autovendor.lua
index 57c259ab..5dc88369 100644
--- a/modules/autovendor.lua
+++ b/modules/autovendor.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("autovendor", "vanilla:tbc", function ()
+pfUI:RegisterModule("autovendor", "vanilla", function ()
local rawborder, border = GetBorderSize()
local bpad = rawborder > 1 and border - GetPerfectPixel() or GetPerfectPixel()
local processed = {}
diff --git a/modules/bags.lua b/modules/bags.lua
index d343d98a..49d5a084 100644
--- a/modules/bags.lua
+++ b/modules/bags.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("bags", "vanilla:tbc", function ()
+pfUI:RegisterModule("bags", "vanilla", function ()
local rawborder, default_border = GetBorderSize("bags")
local knownInventorySpellTextures = {
@@ -573,8 +573,8 @@ pfUI:RegisterModule("bags", "vanilla:tbc", function ()
SlotLeave()
end)
- -- On TBC, the OnEvent function of the template scans for framenames,
- -- and obviously doesn't know the pf-Names. Therefore, triggering
+ -- The OnEvent function of the template scans for framenames,
+ -- and doesn't know the pf-Names. Therefore, triggering
-- the update function on each frame manually
if frame == pfUI.bag.left and BankFrameItemButton_Update then
local SlotUpdate = frame.bagslots.slots[slot].frame:GetScript("OnUpdate")
diff --git a/modules/bgscore.lua b/modules/bgscore.lua
index 932f3918..693c6560 100644
--- a/modules/bgscore.lua
+++ b/modules/bgscore.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("bgscore", "vanilla:tbc", function ()
+pfUI:RegisterModule("bgscore", "vanilla", function ()
local bgframe = WorldStateAlwaysUpFrame
if not bgframe then
bgframe = CreateFrame("Frame", "WorldStateAlwaysUpFrame", UIParent)
diff --git a/modules/bubbles.lua b/modules/bubbles.lua
index 61f9e991..16f4dba6 100644
--- a/modules/bubbles.lua
+++ b/modules/bubbles.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("bubbles", "vanilla:tbc", function ()
+pfUI:RegisterModule("bubbles", "vanilla", function ()
local alpha = tonumber(C.chat.bubbles.alpha)
diff --git a/modules/buff.lua b/modules/buff.lua
index f7114416..7dfbabf6 100644
--- a/modules/buff.lua
+++ b/modules/buff.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("buff", "vanilla:tbc", function ()
+pfUI:RegisterModule("buff", "vanilla", function ()
-- Hide Blizz
BuffFrame:Hide()
BuffFrame:UnregisterAllEvents()
diff --git a/modules/buffwatch.lua b/modules/buffwatch.lua
index e9109b2a..f9c7a154 100644
--- a/modules/buffwatch.lua
+++ b/modules/buffwatch.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("buffwatch", "vanilla:tbc", function ()
+pfUI:RegisterModule("buffwatch", "vanilla", function ()
local rawborder, border = GetBorderSize("panels")
local scanner = libtipscan:GetScanner("buffwatch")
diff --git a/modules/castbar.lua b/modules/castbar.lua
index bb2b071e..b8ad0df7 100644
--- a/modules/castbar.lua
+++ b/modules/castbar.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("castbar", "vanilla:tbc", function ()
+pfUI:RegisterModule("castbar", "vanilla", function ()
local font = C.castbar.use_unitfonts == "1" and pfUI.font_unit or pfUI.font_default
local font_size = C.castbar.use_unitfonts == "1" and C.global.font_unit_size or C.global.font_size
local rawborder, default_border = GetBorderSize("unitframes")
@@ -86,11 +86,20 @@ pfUI:RegisterModule("castbar", "vanilla:tbc", function ()
local query = this.unitstr ~= "" and this.unitstr or this.unitname
if not query then return end
- -- transform all non player unitstrings to unit guids
- if superwow_active and this.unitstr and not UnitIsUnit(this.unitstr, 'player') then
+ -- transform unitstrings to unit guids when SuperWoW is active
+ -- SuperWoW stores cast data by GUID for all units INCLUDING player
+ -- BUT: For player casts, we need to use libcast data because it handles pushback correctly
+ local useLibcastForPlayer = this.unitstr == "player"
+
+ if superwow_active and this.unitstr and not useLibcastForPlayer then
local _, guid = UnitExists(this.unitstr)
query = guid or query
end
+
+ -- For player: use player name to query libcast.db directly
+ if useLibcastForPlayer then
+ query = UnitName("player")
+ end
local cast, nameSubtext, text, texture, startTime, endTime, isTradeSkill = UnitCastingInfo(query)
if not cast then
@@ -149,10 +158,10 @@ pfUI:RegisterModule("castbar", "vanilla:tbc", function ()
if this.showtimer then
if this.delay and this.delay > 0 then
- local delay = "|cffffaaaa" .. (channel and "-" or "+") .. round(this.delay,1) .. " |r "
- this.bar.right:SetText(delay .. string.format("%.1f",cur) .. " / " .. round(max,1))
+ local delay = "|cffffaaaa" .. (channel and "-" or "+") .. round(this.delay,2) .. " |r "
+ this.bar.right:SetText(delay .. string.format("%.2f",cur) .. " / " .. round(max,2))
else
- this.bar.right:SetText(string.format("%.1f",cur) .. " / " .. round(max,1))
+ this.bar.right:SetText(string.format("%.2f",cur) .. " / " .. round(max,2))
end
end
diff --git a/modules/chat.lua b/modules/chat.lua
index 884d027a..6268bd4f 100644
--- a/modules/chat.lua
+++ b/modules/chat.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("chat", "vanilla:tbc", function ()
+pfUI:RegisterModule("chat", "vanilla", function ()
local panelfont = C.panel.use_unitfonts == "1" and pfUI.font_unit or pfUI.font_default
local panelfont_size = C.panel.use_unitfonts == "1" and C.global.font_unit_size or C.global.font_size
local rawborder, default_border = GetBorderSize("chat")
@@ -727,6 +727,12 @@ pfUI:RegisterModule("chat", "vanilla:tbc", function ()
end
end)
+ local function GetPlayerLevel(name)
+ if not pfUI_playerDB then return nil end
+ if not pfUI_playerDB[name] then return nil end
+ return pfUI_playerDB[name].level
+ end
+
local function ScanWhoName(name)
-- abort if another query is ongoing
if who_query.pending then return end
@@ -747,8 +753,7 @@ pfUI:RegisterModule("chat", "vanilla:tbc", function ()
end
-- Remove prat CLINKs
- text = gsub(text, "{CLINK:(%x+):([%d-]-:[%d-]-:[%d-]-:[%d-]-:[%d-]-:[%d-]-:[%d-]-:[%d-]-):([^}]-)}", "|c%1|Hitem:%2|h[%3]|h|r") -- tbc
- text = gsub(text, "{CLINK:(%x+):([%d-]-:[%d-]-:[%d-]-:[%d-]-):([^}]-)}", "|c%1|Hitem:%2|h[%3]|h|r") -- vanilla
+ text = gsub(text, "{CLINK:(%x+):([%d-]-:[%d-]-:[%d-]-:[%d-]-):([^}]-)}", "|c%1|Hitem:%2|h[%3]|h|r")
-- Remove chatter CLINKs
text = gsub(text, "{CLINK:item:(%x+):([%d-]-:[%d-]-:[%d-]-:[%d-]-:[%d-]-:[%d-]-:[%d-]-:[%d-]-):([^}]-)}", "|c%1|Hitem:%2|h[%3]|h|r")
@@ -785,6 +790,21 @@ pfUI:RegisterModule("chat", "vanilla:tbc", function ()
end
end
+ -- display player levels if available
+ if C.chat.text.playerlevel == "1" then
+ for name in gfind(text, "|Hplayer:(.-)|h") do
+ local real, _ = strsplit(":", name)
+ local level = GetPlayerLevel(real)
+
+ if level then
+ local levelcolor = rgbhex(GetDifficultyColor(level))
+ -- Add level after the player name, before the closing bracket
+ text = string.gsub(text, "(|Hplayer:" .. name .. "|h.-|h|r)" .. right,
+ "%1 " .. levelcolor .. level .. "|r" .. right)
+ end
+ end
+ end
+
-- reduce channel name to number
if C.chat.text.channelnumonly == "1" then
local channel = string.gsub(text, ".*%[(.-)%]%s+(.*|Hplayer).+", "%1")
diff --git a/modules/chatcopy.lua b/modules/chatcopy.lua
index 11da75e0..c67b2a01 100644
--- a/modules/chatcopy.lua
+++ b/modules/chatcopy.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("chatcopy", "vanilla:tbc", function ()
+pfUI:RegisterModule("chatcopy", "vanilla", function ()
local limit = 100
local f = CreateFrame("Frame")
f:RegisterEvent("PLAYER_ENTERING_WORLD")
diff --git a/modules/combopoints.lua b/modules/combopoints.lua
index f874974e..839f50d7 100644
--- a/modules/combopoints.lua
+++ b/modules/combopoints.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("combopoints", "vanilla:tbc", function ()
+pfUI:RegisterModule("combopoints", "vanilla", function ()
local rawborder, border = GetBorderSize()
-- Hide Blizzard combo point frame and unregister all events to prevent it from popping up again
diff --git a/modules/cooldown.lua b/modules/cooldown.lua
index 0a293940..9561cf83 100644
--- a/modules/cooldown.lua
+++ b/modules/cooldown.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("cooldown", "vanilla:tbc", function ()
+pfUI:RegisterModule("cooldown", "vanilla", function ()
-- cache values
local lowcolor = {strsplit(",", C.appearance.cd.lowcolor)}
local normalcolor = {strsplit(",", C.appearance.cd.normalcolor)}
@@ -134,14 +134,7 @@ pfUI:RegisterModule("cooldown", "vanilla:tbc", function ()
end
end
- if pfUI.expansion == "vanilla" then
- -- vanilla does not have a cooldown frame type, so we hook the
- -- regular SetTimer function that each one is calling.
- hooksecurefunc("CooldownFrame_SetTimer", SetCooldown)
- else
- -- tbc and later expansion have a cooldown frametype, so we can
- -- hook directly into the frame creation and add our function there.
- local methods = getmetatable(CreateFrame('Cooldown', nil, nil, 'CooldownFrameTemplate')).__index
- hooksecurefunc(methods, 'SetCooldown', SetCooldown)
- end
+ -- vanilla does not have a cooldown frame type, so we hook the
+ -- regular SetTimer function that each one is calling.
+ hooksecurefunc("CooldownFrame_SetTimer", SetCooldown)
end)
diff --git a/modules/easteregg.lua b/modules/easteregg.lua
index 35a76c6d..9c5a7512 100644
--- a/modules/easteregg.lua
+++ b/modules/easteregg.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("easteregg", "vanilla:tbc", function ()
+pfUI:RegisterModule("easteregg", "vanilla", function ()
-- merry x-mas!
if date("%m%d") == "1224" or date("%m%d") == "1225" then
local title = (UnitFactionGroup("player") == "Horde") and PVP_RANK_18_0 or PVP_RANK_18_1
diff --git a/modules/energytick.lua b/modules/energytick.lua
index d3c8e24d..cfcffb71 100644
--- a/modules/energytick.lua
+++ b/modules/energytick.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("energytick", "vanilla:tbc", function ()
+pfUI:RegisterModule("energytick", "vanilla", function ()
if not pfUI.uf or not pfUI.uf.player then return end
local energytick = CreateFrame("Frame", nil, pfUI.uf.player.power.bar)
diff --git a/modules/farmmode.lua b/modules/farmmode.lua
index 19478884..0a1e3bad 100644
--- a/modules/farmmode.lua
+++ b/modules/farmmode.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("farmmode", "vanilla:tbc", function ()
+pfUI:RegisterModule("farmmode", "vanilla", function ()
local function ToggleFarmMode()
if pfUI.farmmap:IsShown() then
pfUI.farmmap:Hide()
diff --git a/modules/feigndeath.lua b/modules/feigndeath.lua
index ba4e5fcd..01a5e41f 100644
--- a/modules/feigndeath.lua
+++ b/modules/feigndeath.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("feigndeath", "vanilla:tbc", function ()
+pfUI:RegisterModule("feigndeath", "vanilla", function ()
local cache = { }
local scanner = libtipscan:GetScanner("feigndeath")
local healthbar = scanner:GetChildren()
diff --git a/modules/firstrun.lua b/modules/firstrun.lua
index f27bd7f2..582cbe45 100644
--- a/modules/firstrun.lua
+++ b/modules/firstrun.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("firstrun", "vanilla:tbc", function ()
+pfUI:RegisterModule("firstrun", "vanilla", function ()
pfUI.firstrun = CreateFrame("Frame", "pfFirstRunWizard", UIParent)
pfUI.firstrun.steps = {}
diff --git a/modules/focus.lua b/modules/focus.lua
index a2e24582..16f4124a 100644
--- a/modules/focus.lua
+++ b/modules/focus.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("focus", "vanilla:tbc", function ()
+pfUI:RegisterModule("focus", "vanilla", function ()
-- do not go further on disabled UFs
if C.unitframes.disable == "1" then return end
diff --git a/modules/group.lua b/modules/group.lua
index 5aa0aaa2..81684f70 100644
--- a/modules/group.lua
+++ b/modules/group.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("group", "vanilla:tbc", function ()
+pfUI:RegisterModule("group", "vanilla", function ()
-- do not go further on disabled UFs
if C.unitframes.disable == "1" then return end
diff --git a/modules/gryphons.lua b/modules/gryphons.lua
index 96eba04e..287ae5b8 100644
--- a/modules/gryphons.lua
+++ b/modules/gryphons.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("gryphons", "vanilla:tbc", function ()
+pfUI:RegisterModule("gryphons", "vanilla", function ()
pfUI.gryphons = {
frames = {
left = CreateFrame("Frame"),
diff --git a/modules/gui.lua b/modules/gui.lua
index 2827caa8..64785efe 100644
--- a/modules/gui.lua
+++ b/modules/gui.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("gui", "vanilla:tbc", function ()
+pfUI:RegisterModule("gui", "vanilla", function ()
local Reload, U, CreateConfig, CreateTabFrame, CreateArea, CreateGUIEntry, EntryUpdate
-- "searchDB" gets populated when CreateConfig is called. The table holds
@@ -1657,6 +1657,19 @@ pfUI:RegisterModule("gui", "vanilla:tbc", function ()
CreateConfig(nil, T["Show Druid Mana Bar"], C.unitframes, "druidmanabar", "checkbox", nil, nil, nil, nil, "vanilla" )
CreateConfig(nil, T["Druid Mana Bar Height"], C.unitframes, "druidmanaheight", nil, nil, nil, nil, nil, "vanilla" )
CreateConfig(nil, T["Druid Mana Bar Text"], C.unitframes, "druidmanatext", "checkbox", nil, nil, nil, nil, "vanilla" )
+ CreateConfig(nil, T["Track Group on Minimap"], C.unitframes, "track_group", "checkbox", nil, nil, nil, nil, "vanilla" )
+
+ CreateConfig(nil, T["Nampower Settings"], nil, nil, "header")
+ CreateConfig(nil, T["Show Spell Queue Indicator"], C.unitframes, "spellqueue", "checkbox", nil, nil, nil, nil, "vanilla" )
+ CreateConfig(nil, T["Spell Queue Icon Size"], C.unitframes, "spellqueuesize", nil, nil, nil, nil, nil, "vanilla" )
+ CreateConfig(nil, T["Show Reactive Spell Indicator"], C.unitframes, "reactive_indicator", "checkbox", nil, nil, nil, nil, "vanilla" )
+ CreateConfig(nil, T["Reactive Indicator Size"], C.unitframes, "reactive_size", nil, nil, nil, nil, nil, "vanilla" )
+ CreateConfig(nil, T["Enhanced Buff Tracking"], C.unitframes, "nampower_buffs", "checkbox", nil, nil, nil, nil, "vanilla" )
+
+ CreateConfig(nil, T["UnitXP Settings"], nil, nil, "header")
+ CreateConfig(nil, T["Show Line of Sight Indicator"], C.unitframes, "los_indicator", "checkbox", nil, nil, nil, nil, "vanilla" )
+ CreateConfig(nil, T["Show Behind Indicator"], C.unitframes, "behind_indicator", "checkbox", nil, nil, nil, nil, "vanilla" )
+ CreateConfig(nil, T["Enable OS Notifications"], C.unitframes, "unitxp_notify", "checkbox", nil, nil, nil, nil, "vanilla" )
end)
-- Shared Unit- and Groupframes
@@ -2263,6 +2276,7 @@ pfUI:RegisterModule("gui", "vanilla:tbc", function ()
CreateConfig(nil, T["Generate Playerlinks"], C.chat.text, "playerlinks", "checkbox")
CreateConfig(nil, T["Enable URL Detection"], C.chat.text, "detecturl", "checkbox")
CreateConfig(nil, T["Enable Class Colors"], C.chat.text, "classcolor", "checkbox")
+ CreateConfig(nil, T["Enable Player Levels"], C.chat.text, "playerlevel", "checkbox")
CreateConfig(nil, T["Who Search Unknown Classes (|cffffaaaaExperimental|r)"], C.chat.text, "whosearchunknown", "checkbox")
CreateConfig(nil, T["Colorize Unknown Classes"], C.chat.text, "tintunknown", "checkbox")
CreateConfig(nil, T["Unknown Class Color"], C.chat.text, "unknowncolor", "color")
@@ -2388,36 +2402,26 @@ pfUI:RegisterModule("gui", "vanilla:tbc", function ()
CreateConfig(nil, "ShaguDPS (" .. T["Dock"] .. ")", C.thirdparty.shagudps, "dock", "checkbox")
CreateConfig(nil, "DPSMate (" .. T["Skin"] .. ")", C.thirdparty.dpsmate, "skin", "checkbox")
CreateConfig(nil, "DPSMate (" .. T["Dock"] .. ")", C.thirdparty.dpsmate, "dock", "checkbox")
- CreateConfig(nil, "Recount (" .. T["Skin"] .. ")", C.thirdparty.recount, "skin", "checkbox", nil, nil, nil, nil, "tbc")
- CreateConfig(nil, "Recount (" .. T["Dock"] .. ")", C.thirdparty.recount, "dock", "checkbox", nil, nil, nil, nil, "tbc")
- CreateConfig(nil, "Omen (" .. T["Skin"] .. ")", C.thirdparty.omen, "skin", "checkbox", nil, nil, nil, nil, "tbc")
- CreateConfig(nil, "Omen (" .. T["Dock"] .. ")", C.thirdparty.omen, "dock", "checkbox", nil, nil, nil, nil, "tbc")
- CreateConfig(nil, "SWStats (" .. T["Skin"] .. ")", C.thirdparty.swstats, "skin", "checkbox", nil, nil, nil, nil, "vanilla")
- CreateConfig(nil, "SWStats (" .. T["Dock"] .. ")", C.thirdparty.swstats, "dock", "checkbox", nil, nil, nil, nil, "vanilla")
- CreateConfig(nil, "KLH Threat Meter (" .. T["Skin"] .. ")", C.thirdparty.ktm, "skin", "checkbox", nil, nil, nil, nil, "vanilla")
- CreateConfig(nil, "KLH Threat Meter (" .. T["Dock"] .. ")", C.thirdparty.ktm, "dock", "checkbox", nil, nil, nil, nil, "vanilla")
- CreateConfig(nil, "TW Threatmeter (" .. T["Skin"] .. ")", C.thirdparty.twt, "skin", "checkbox", nil, nil, nil, nil, "vanilla")
- CreateConfig(nil, "TW Threatmeter (" .. T["Dock"] .. ")", C.thirdparty.twt, "dock", "checkbox", nil, nil, nil, nil, "vanilla")
- CreateConfig(nil, "WIM", C.thirdparty.wim, "enable", "checkbox", nil, nil, nil, nil, "vanilla")
- CreateConfig(nil, "HealComm", C.thirdparty.healcomm, "enable", "checkbox", nil, nil, nil, nil, "vanilla")
- CreateConfig(nil, "SortBags", C.thirdparty.sortbags, "enable", "checkbox", nil, nil, nil, nil, "vanilla")
- CreateConfig(nil, "Bag_Sort", C.thirdparty.bag_sort, "enable", "checkbox", nil, nil, nil, nil, "tbc")
+ CreateConfig(nil, "SWStats (" .. T["Skin"] .. ")", C.thirdparty.swstats, "skin", "checkbox")
+ CreateConfig(nil, "SWStats (" .. T["Dock"] .. ")", C.thirdparty.swstats, "dock", "checkbox")
+ CreateConfig(nil, "KLH Threat Meter (" .. T["Skin"] .. ")", C.thirdparty.ktm, "skin", "checkbox")
+ CreateConfig(nil, "KLH Threat Meter (" .. T["Dock"] .. ")", C.thirdparty.ktm, "dock", "checkbox")
+ CreateConfig(nil, "TW Threatmeter (" .. T["Skin"] .. ")", C.thirdparty.twt, "skin", "checkbox")
+ CreateConfig(nil, "TW Threatmeter (" .. T["Dock"] .. ")", C.thirdparty.twt, "dock", "checkbox")
+ CreateConfig(nil, "WIM", C.thirdparty.wim, "enable", "checkbox")
+ CreateConfig(nil, "HealComm", C.thirdparty.healcomm, "enable", "checkbox")
+ CreateConfig(nil, "SortBags", C.thirdparty.sortbags, "enable", "checkbox")
CreateConfig(nil, "MrPlow", C.thirdparty.mrplow, "enable", "checkbox")
- CreateConfig(nil, "BetterCharacterStats", C.thirdparty.bcs, "enable", "checkbox", nil, nil, nil, nil, "vanilla")
- CreateConfig(nil, "Crafty", C.thirdparty.crafty, "enable", "checkbox", nil, nil, nil, nil, "vanilla")
- CreateConfig(nil, "CleverMacro", C.thirdparty.clevermacro, "enable", "checkbox", nil, nil, nil, nil, "vanilla")
- CreateConfig(nil, "AckisRecipeList", C.thirdparty.ackis, "enable", "checkbox", nil, nil, nil, nil, "tbc")
- CreateConfig(nil, "SheepWatch", C.thirdparty.sheepwatch, "enable", "checkbox", nil, nil, nil, nil, "tbc")
- CreateConfig(nil, "TotemTimers", C.thirdparty.totemtimers, "enable", "checkbox", nil, nil, nil, nil, "tbc")
- CreateConfig(nil, "DruidBar", C.thirdparty.druidbar, "enable", "checkbox", nil, nil, nil, nil, "tbc")
- CreateConfig(nil, "BCEPGP", C.thirdparty.bcepgp, "enable", "checkbox", nil, nil, nil, nil, "tbc")
- CreateConfig(nil, "FlightMap", C.thirdparty.flightmap, "enable", "checkbox", nil, nil, nil, nil, "vanilla")
- CreateConfig(nil, "TheoryCraft", C.thirdparty.theorycraft, "enable", "checkbox", nil, nil, nil, nil, "vanilla")
- CreateConfig(nil, "SuperMacro", C.thirdparty.supermacro, "enable", "checkbox", nil, nil, nil, nil, "vanilla")
- CreateConfig(nil, "AtlasLoot", C.thirdparty.atlasloot, "enable", "checkbox", nil, nil, nil, nil, "vanilla")
- CreateConfig(nil, "MyRolePlay", C.thirdparty.myroleplay, "enable", "checkbox", nil, nil, nil, nil, "vanilla")
- CreateConfig(nil, "DruidManaBar", C.thirdparty.druidmana, "enable", "checkbox", nil, nil, nil, nil, "vanilla")
- CreateConfig(nil, "NoteIt", C.thirdparty.noteit, "enable", "checkbox", nil, nil, nil, nil, "vanilla")
+ CreateConfig(nil, "BetterCharacterStats", C.thirdparty.bcs, "enable", "checkbox")
+ CreateConfig(nil, "Crafty", C.thirdparty.crafty, "enable", "checkbox")
+ CreateConfig(nil, "CleverMacro", C.thirdparty.clevermacro, "enable", "checkbox")
+ CreateConfig(nil, "FlightMap", C.thirdparty.flightmap, "enable", "checkbox")
+ CreateConfig(nil, "TheoryCraft", C.thirdparty.theorycraft, "enable", "checkbox")
+ CreateConfig(nil, "SuperMacro", C.thirdparty.supermacro, "enable", "checkbox")
+ CreateConfig(nil, "AtlasLoot", C.thirdparty.atlasloot, "enable", "checkbox")
+ CreateConfig(nil, "MyRolePlay", C.thirdparty.myroleplay, "enable", "checkbox")
+ CreateConfig(nil, "DruidManaBar", C.thirdparty.druidmana, "enable", "checkbox")
+ CreateConfig(nil, "NoteIt", C.thirdparty.noteit, "enable", "checkbox")
end)
CreateGUIEntry(T["Components"], T["Modules"], function()
diff --git a/modules/hoverbind.lua b/modules/hoverbind.lua
index 00f4a162..a838a5c2 100644
--- a/modules/hoverbind.lua
+++ b/modules/hoverbind.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("hoverbind", "vanilla:tbc", function ()
+pfUI:RegisterModule("hoverbind", "vanilla", function ()
local keymap = {
-- buttons to binding association
["pfActionBarMainButton"] = "ACTIONBUTTON",
diff --git a/modules/infight.lua b/modules/infight.lua
index 95531a8e..b48b4e88 100644
--- a/modules/infight.lua
+++ b/modules/infight.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("infight", "vanilla:tbc", function ()
+pfUI:RegisterModule("infight", "vanilla", function ()
local function OnUpdate()
if not this.infight and not this.aggro and not this.health then return end
if ( this.tick or 1) > GetTime() then return else this.tick = GetTime() + .1 end
diff --git a/modules/loot.lua b/modules/loot.lua
index a2284398..bfa2ab1a 100644
--- a/modules/loot.lua
+++ b/modules/loot.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("loot", "vanilla:tbc", function ()
+pfUI:RegisterModule("loot", "vanilla", function ()
local rawborder, border = GetBorderSize()
pfUI.loot = CreateFrame("Frame", "pfLootFrame", UIParent)
diff --git a/modules/map.lua b/modules/map.lua
index 806f1e17..247e1150 100644
--- a/modules/map.lua
+++ b/modules/map.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("map", "vanilla:tbc", function ()
+pfUI:RegisterModule("map", "vanilla", function ()
table.insert(UISpecialFrames, "WorldMapFrame")
local function UpdateTooltipScale()
diff --git a/modules/mapreveal.lua b/modules/mapreveal.lua
index 594b0ff3..c8120a6c 100644
--- a/modules/mapreveal.lua
+++ b/modules/mapreveal.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("mapreveal", "vanilla:tbc", function ()
+pfUI:RegisterModule("mapreveal", "vanilla", function ()
-- do not load if other map addon is loaded
if Cartographer then return end
if METAMAP_TITLE then return end
diff --git a/modules/minimap.lua b/modules/minimap.lua
index 53bc3374..3ea5f343 100644
--- a/modules/minimap.lua
+++ b/modules/minimap.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("minimap", "vanilla:tbc", function ()
+pfUI:RegisterModule("minimap", "vanilla", function ()
local rawborder, border = GetBorderSize()
local size = tonumber(C.appearance.minimap.size) or 140
@@ -39,7 +39,7 @@ pfUI:RegisterModule("minimap", "vanilla:tbc", function ()
Minimap:SetWidth(size)
Minimap:SetHeight(size)
- -- vanilla+tbc: do the best to detect the minimap arrow
+ -- do the best to detect the minimap arrow
local arrowscale = tonumber(C.appearance.minimap.arrowscale)
local minimaparrow = ({Minimap:GetChildren()})[9]
for k, v in pairs({Minimap:GetChildren()}) do
diff --git a/modules/mirrortimers.lua b/modules/mirrortimers.lua
index 6b08f395..311e6683 100644
--- a/modules/mirrortimers.lua
+++ b/modules/mirrortimers.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("mirrortimers", "vanilla:tbc", function ()
+pfUI:RegisterModule("mirrortimers", "vanilla", function ()
local font = pfUI.font_default
local fontsize = tonumber(C.global.font_size)
local height = fontsize * 1.3
diff --git a/modules/nameplates.lua b/modules/nameplates.lua
index c181418a..ce25a161 100644
--- a/modules/nameplates.lua
+++ b/modules/nameplates.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("nameplates", "vanilla:tbc", function ()
+pfUI:RegisterModule("nameplates", "vanilla", function ()
-- disable original castbars
pcall(SetCVar, "ShowVKeyCastbar", 0)
@@ -1115,7 +1115,6 @@ pfUI:RegisterModule("nameplates", "vanilla:tbc", function ()
if pfUI.client <= 11200 then
-- handle vanilla only settings
- -- due to the secured lua api, those settings can't be applied to TBC and later.
local hookOnConfigChange = nameplates.OnConfigChange
nameplates.OnConfigChange = function(self)
hookOnConfigChange(self)
diff --git a/modules/nampower.lua b/modules/nampower.lua
new file mode 100644
index 00000000..8e71ecc5
--- /dev/null
+++ b/modules/nampower.lua
@@ -0,0 +1,743 @@
+-- Nampower integration module
+-- Provides spell queue indicator and enhanced cast information
+-- Requires Nampower DLL: https://gitea.com/avitasia/nampower
+
+pfUI:RegisterModule("nampower", "vanilla", function ()
+ -- Only load if Nampower is available
+ if not GetNampowerVersion then return end
+
+ local rawborder, border = GetBorderSize()
+
+ -- Spell Queue Indicator
+ -- Shows the currently queued spell icon near the castbar
+ if C.unitframes.spellqueue == "1" then
+ local size = tonumber(C.unitframes.spellqueuesize) or 32
+
+ pfUI.spellqueue = CreateFrame("Frame", "pfSpellQueue", UIParent)
+ pfUI.spellqueue:SetFrameStrata("HIGH")
+ pfUI.spellqueue:SetWidth(size)
+ pfUI.spellqueue:SetHeight(size)
+ pfUI.spellqueue:Hide()
+
+ -- Position near player castbar if available
+ if pfUI.castbar and pfUI.castbar.player then
+ pfUI.spellqueue:SetPoint("LEFT", pfUI.castbar.player, "RIGHT", border*3, 0)
+ else
+ pfUI.spellqueue:SetPoint("CENTER", UIParent, "CENTER", 100, -100)
+ end
+
+ pfUI.spellqueue.icon = pfUI.spellqueue:CreateTexture("OVERLAY")
+ pfUI.spellqueue.icon:SetAllPoints(pfUI.spellqueue)
+ pfUI.spellqueue.icon:SetTexCoord(.08, .92, .08, .92)
+
+ UpdateMovable(pfUI.spellqueue)
+ CreateBackdrop(pfUI.spellqueue)
+ CreateBackdropShadow(pfUI.spellqueue)
+
+ -- Event codes from Nampower
+ local ON_SWING_QUEUED = 0
+ local ON_SWING_QUEUE_POPPED = 1
+ local NORMAL_QUEUED = 2
+ local NORMAL_QUEUE_POPPED = 3
+ local NON_GCD_QUEUED = 4
+ local NON_GCD_QUEUE_POPPED = 5
+
+ local queue = CreateFrame("Frame")
+ queue:RegisterEvent("SPELL_QUEUE_EVENT")
+ queue:SetScript("OnEvent", function()
+ local eventCode = arg1
+ local spellId = arg2
+
+ if eventCode == NORMAL_QUEUED or eventCode == NON_GCD_QUEUED or eventCode == ON_SWING_QUEUED then
+ -- Get spell texture from SpellInfo (SuperWoW) or GetSpellTexture
+ local texture
+ if SpellInfo then
+ local _, _, tex = SpellInfo(spellId)
+ texture = tex
+ end
+
+ if texture then
+ pfUI.spellqueue.icon:SetTexture(texture)
+ pfUI.spellqueue:Show()
+ end
+ elseif eventCode == NORMAL_QUEUE_POPPED or eventCode == NON_GCD_QUEUE_POPPED or eventCode == ON_SWING_QUEUE_POPPED then
+ pfUI.spellqueue:Hide()
+ end
+ end)
+ end
+
+ -- Enhanced Debuff Tracking using Nampower events
+ -- DEBUFF_ADDED_OTHER/DEBUFF_REMOVED_OTHER provide accurate debuff tracking with spellId
+ if libdebuff then
+ -- Storage for GUID-based debuff tracking
+ pfUI.nampower_debuffs = pfUI.nampower_debuffs or {}
+ local debuffdb = pfUI.nampower_debuffs
+
+ -- Get player GUID for tracking own debuffs
+ local playerGuid
+
+ local debuffTracker = CreateFrame("Frame")
+ debuffTracker:RegisterEvent("PLAYER_ENTERING_WORLD")
+ debuffTracker:RegisterEvent("DEBUFF_ADDED_OTHER")
+ debuffTracker:RegisterEvent("DEBUFF_REMOVED_OTHER")
+ debuffTracker:RegisterEvent("DEBUFF_ADDED_SELF")
+ debuffTracker:RegisterEvent("DEBUFF_REMOVED_SELF")
+
+ debuffTracker:SetScript("OnEvent", function()
+ if event == "PLAYER_ENTERING_WORLD" then
+ -- Cache player GUID
+ if UnitExists then
+ local _, guid = UnitExists("player")
+ playerGuid = guid
+ end
+ return
+ end
+
+ -- DEBUFF events: arg1=guid, arg2=slot, arg3=spellId, arg4=stackCount, arg5=auraLevel
+ local guid = arg1
+ local slot = arg2
+ local spellId = arg3
+ local stackCount = arg4
+ local auraLevel = arg5
+
+ if not guid or not spellId then return end
+
+ if event == "DEBUFF_ADDED_OTHER" or event == "DEBUFF_ADDED_SELF" then
+ -- Initialize storage for this GUID
+ if not debuffdb[guid] then debuffdb[guid] = {} end
+
+ -- Get spell info
+ local spellName, spellRank, texture
+ if SpellInfo then
+ spellName, spellRank, texture = SpellInfo(spellId)
+ end
+ if GetSpellNameAndRankForId then
+ spellName, spellRank = GetSpellNameAndRankForId(spellId)
+ end
+
+ if spellName then
+ -- Get duration from libdebuff's duration table or GetSpellRec
+ local duration = 0
+ if libdebuff.GetDuration then
+ duration = libdebuff:GetDuration(spellName, spellRank)
+ end
+
+ -- Try GetSpellRec for duration if libdebuff doesn't have it
+ if duration == 0 and GetSpellRec then
+ local spellRec = GetSpellRec(spellId)
+ if spellRec and spellRec.durationIndex and spellRec.durationIndex > 0 then
+ -- Duration index maps to spell duration - common values:
+ -- This is a rough approximation since we don't have the duration table
+ duration = 30 -- Default fallback
+ end
+ end
+
+ -- Store debuff data
+ debuffdb[guid][spellId] = {
+ spellId = spellId,
+ name = spellName,
+ rank = spellRank,
+ texture = texture,
+ stacks = stackCount or 1,
+ start = GetTime(),
+ duration = duration,
+ slot = slot,
+ auraLevel = auraLevel,
+ caster = (event == "DEBUFF_ADDED_SELF" or guid == playerGuid) and "player" or nil
+ }
+
+ -- Also update libdebuff's internal tracking if we have unit info
+ local unitName = UnitName and guid and UnitName(guid)
+ local unitLevel = UnitLevel and guid and UnitLevel(guid)
+ if unitName and duration > 0 then
+ libdebuff:AddEffect(unitName, unitLevel or 0, spellName, duration, "player")
+ end
+ end
+
+ elseif event == "DEBUFF_REMOVED_OTHER" or event == "DEBUFF_REMOVED_SELF" then
+ -- Remove debuff from tracking
+ if debuffdb[guid] and debuffdb[guid][spellId] then
+ debuffdb[guid][spellId] = nil
+ end
+ end
+ end)
+
+ -- Enhanced UnitDebuff function that uses Nampower data
+ -- This provides more accurate debuff information when available
+ local originalUnitDebuff = libdebuff.UnitDebuff
+ function libdebuff:UnitDebuffNampower(unit, id)
+ -- First try the original method
+ local effect, rank, texture, stacks, dtype, duration, timeleft, caster = originalUnitDebuff(self, unit, id)
+
+ -- If we have Nampower data for this unit, try to enhance it
+ local _, guid = UnitExists(unit)
+ if guid and debuffdb[guid] then
+ -- Find the debuff by slot
+ for spellId, data in pairs(debuffdb[guid]) do
+ if data.slot == id then
+ -- Use Nampower data for more accurate timing
+ if data.duration and data.duration > 0 and data.start then
+ duration = data.duration
+ timeleft = data.duration + data.start - GetTime()
+ if timeleft < 0 then timeleft = 0 end
+ caster = data.caster
+ stacks = data.stacks or stacks
+ end
+ break
+ end
+ end
+ end
+
+ return effect, rank, texture, stacks, dtype, duration, timeleft, caster
+ end
+
+ -- Expose enhanced function
+ pfUI.api.libdebuff_nampower = libdebuff.UnitDebuffNampower
+ end
+
+ -- Enhanced buff tracking using BUFF events
+ if C.unitframes.nampower_buffs == "1" then
+ pfUI.nampower_buffs = pfUI.nampower_buffs or {}
+ local buffdb = pfUI.nampower_buffs
+
+ local buffTracker = CreateFrame("Frame")
+ buffTracker:RegisterEvent("BUFF_ADDED_OTHER")
+ buffTracker:RegisterEvent("BUFF_REMOVED_OTHER")
+ buffTracker:RegisterEvent("BUFF_ADDED_SELF")
+ buffTracker:RegisterEvent("BUFF_REMOVED_SELF")
+
+ buffTracker:SetScript("OnEvent", function()
+ local guid = arg1
+ local slot = arg2
+ local spellId = arg3
+ local stackCount = arg4
+ local auraLevel = arg5
+
+ if not guid or not spellId then return end
+
+ if event == "BUFF_ADDED_OTHER" or event == "BUFF_ADDED_SELF" then
+ if not buffdb[guid] then buffdb[guid] = {} end
+
+ local spellName, spellRank, texture
+ if SpellInfo then
+ spellName, spellRank, texture = SpellInfo(spellId)
+ end
+ if GetSpellNameAndRankForId then
+ spellName, spellRank = GetSpellNameAndRankForId(spellId)
+ end
+
+ buffdb[guid][spellId] = {
+ spellId = spellId,
+ name = spellName,
+ rank = spellRank,
+ texture = texture,
+ stacks = stackCount or 1,
+ start = GetTime(),
+ slot = slot,
+ auraLevel = auraLevel
+ }
+ elseif event == "BUFF_REMOVED_OTHER" or event == "BUFF_REMOVED_SELF" then
+ if buffdb[guid] and buffdb[guid][spellId] then
+ buffdb[guid][spellId] = nil
+ end
+ end
+ end)
+ end
+
+ -- Direct Aura Access API using GetUnitField
+ -- Much faster than tooltip scanning - reads aura arrays directly from unit fields
+ if GetUnitField then
+ pfUI.api.GetUnitAuras = function(unit)
+ local auras = GetUnitField(unit, "aura")
+ local auraLevels = GetUnitField(unit, "auraLevels")
+ local auraStacks = GetUnitField(unit, "auraApplications")
+
+ if not auras then return nil end
+
+ local result = {}
+ for i = 1, 48 do
+ local spellId = auras[i]
+ if spellId and spellId > 0 then
+ local name, rank, texture
+ if SpellInfo then
+ name, rank, texture = SpellInfo(spellId)
+ elseif GetSpellNameAndRankForId then
+ name, rank = GetSpellNameAndRankForId(spellId)
+ end
+
+ result[i] = {
+ spellId = spellId,
+ name = name,
+ rank = rank,
+ texture = texture,
+ level = auraLevels and auraLevels[i] or 0,
+ stacks = auraStacks and auraStacks[i] or 1,
+ isBuff = i <= 32, -- First 32 slots are buffs, rest are debuffs
+ }
+ end
+ end
+ return result
+ end
+
+ -- Quick check if unit has specific aura by spellId
+ pfUI.api.UnitHasAura = function(unit, spellId)
+ local auras = GetUnitField(unit, "aura")
+ if not auras then return false end
+ for i = 1, 48 do
+ if auras[i] == spellId then return true, i end
+ end
+ return false
+ end
+
+ -- Get unit resistances directly
+ pfUI.api.GetUnitResistances = function(unit)
+ local res = GetUnitField(unit, "resistances")
+ if not res then return nil end
+ return {
+ armor = res[1],
+ holy = res[2],
+ fire = res[3],
+ nature = res[4],
+ frost = res[5],
+ shadow = res[6],
+ arcane = res[7]
+ }
+ end
+ end
+
+ -- Reactive Spell Indicator using IsSpellUsable
+ -- Shows when reactive abilities like Overpower, Revenge, Execute are usable
+ if IsSpellUsable and C.unitframes.reactive_indicator == "1" then
+ local size = tonumber(C.unitframes.reactive_size) or 28
+ local _, class = UnitClass("player")
+
+ -- Reactive spells by class
+ local reactiveSpells = {
+ WARRIOR = {
+ { name = "Overpower", texture = "Interface\\Icons\\Ability_MeleeDamage" },
+ { name = "Revenge", texture = "Interface\\Icons\\Ability_Warrior_Revenge" },
+ { name = "Execute", texture = "Interface\\Icons\\INV_Sword_48" },
+ },
+ ROGUE = {
+ { name = "Riposte", texture = "Interface\\Icons\\Ability_Warrior_Challange" },
+ },
+ HUNTER = {
+ { name = "Mongoose Bite", texture = "Interface\\Icons\\Ability_Hunter_SwiftStrike" },
+ { name = "Counterattack", texture = "Interface\\Icons\\Ability_Warrior_Challange" },
+ },
+ }
+
+ local spells = reactiveSpells[class]
+ if spells then
+ pfUI.reactive = CreateFrame("Frame", "pfReactiveIndicator", UIParent)
+ pfUI.reactive:SetFrameStrata("HIGH")
+ local spellCount = table.getn(spells)
+ pfUI.reactive:SetWidth(size * spellCount + 4 * (spellCount - 1))
+ pfUI.reactive:SetHeight(size)
+ pfUI.reactive:SetPoint("CENTER", UIParent, "CENTER", 0, -200)
+ pfUI.reactive:Hide()
+
+ pfUI.reactive.icons = {}
+ for i, spell in ipairs(spells) do
+ local icon = CreateFrame("Frame", nil, pfUI.reactive)
+ icon:SetWidth(size)
+ icon:SetHeight(size)
+ icon:SetPoint("LEFT", pfUI.reactive, "LEFT", (i-1) * (size + 4), 0)
+
+ icon.texture = icon:CreateTexture(nil, "ARTWORK")
+ icon.texture:SetAllPoints(icon)
+ icon.texture:SetTexture(spell.texture)
+ icon.texture:SetTexCoord(.08, .92, .08, .92)
+
+ icon.glow = icon:CreateTexture(nil, "OVERLAY")
+ icon.glow:SetPoint("TOPLEFT", icon, "TOPLEFT", -4, 4)
+ icon.glow:SetPoint("BOTTOMRIGHT", icon, "BOTTOMRIGHT", 4, -4)
+ icon.glow:SetTexture(pfUI.media["img:glow"])
+ icon.glow:SetVertexColor(1, 1, 0, 0.8)
+
+ CreateBackdrop(icon)
+ icon:Hide()
+ icon.spellName = spell.name
+ pfUI.reactive.icons[i] = icon
+ end
+
+ UpdateMovable(pfUI.reactive)
+
+ pfUI.reactive:SetScript("OnUpdate", function()
+ local anyVisible = false
+ for _, icon in ipairs(this.icons) do
+ local usable = IsSpellUsable(icon.spellName)
+ if usable == 1 then
+ icon:Show()
+ anyVisible = true
+ else
+ icon:Hide()
+ end
+ end
+ if anyVisible then
+ this:Show()
+ else
+ this:Hide()
+ end
+ end)
+ end
+ end
+
+ -- Enhanced Cooldown Tracking API using GetSpellIdCooldown
+ if GetSpellIdCooldown then
+ pfUI.api.GetPreciseCooldown = function(spellId)
+ local cd = GetSpellIdCooldown(spellId)
+ if not cd then return nil end
+ return {
+ onCooldown = cd.isOnCooldown == 1,
+ remaining = cd.cooldownRemainingMs / 1000,
+ remainingMs = cd.cooldownRemainingMs,
+ gcdRemaining = cd.gcdCategoryRemainingMs / 1000,
+ gcdRemainingMs = cd.gcdCategoryRemainingMs,
+ individualRemaining = cd.individualRemainingMs / 1000,
+ categoryRemaining = cd.categoryRemainingMs / 1000,
+ }
+ end
+
+ -- Item cooldown helper
+ pfUI.api.GetPreciseItemCooldown = function(itemId)
+ if not GetItemIdCooldown then return nil end
+ local cd = GetItemIdCooldown(itemId)
+ if not cd then return nil end
+ return {
+ onCooldown = cd.isOnCooldown == 1,
+ remaining = cd.cooldownRemainingMs / 1000,
+ remainingMs = cd.cooldownRemainingMs,
+ }
+ end
+ end
+
+ -- UNIT_DIED event handling
+ -- Can be used to clear tracking data or trigger effects on unit death
+ local deathTracker = CreateFrame("Frame")
+ deathTracker:RegisterEvent("UNIT_DIED")
+ deathTracker:SetScript("OnEvent", function()
+ local guid = arg1
+ if not guid then return end
+
+ -- Clean up debuff tracking for dead units
+ if pfUI.nampower_debuffs and pfUI.nampower_debuffs[guid] then
+ pfUI.nampower_debuffs[guid] = nil
+ end
+ if pfUI.nampower_buffs and pfUI.nampower_buffs[guid] then
+ pfUI.nampower_buffs[guid] = nil
+ end
+ end)
+
+ -- Trinket Management API
+ if GetTrinkets then
+ pfUI.api.GetEquippedTrinkets = function()
+ local trinkets = GetTrinkets()
+ local equipped = {}
+ for _, trinket in pairs(trinkets) do
+ if trinket.bagIndex == nil then -- nil bagIndex = equipped
+ table.insert(equipped, trinket)
+ end
+ end
+ return equipped
+ end
+
+ pfUI.api.GetTrinketCooldown = function(slot)
+ if not GetTrinketCooldown then return nil end
+ local cd = GetTrinketCooldown(slot)
+ if cd == -1 then return nil end
+ return {
+ onCooldown = cd.isOnCooldown == 1,
+ remaining = cd.cooldownRemainingMs / 1000,
+ remainingMs = cd.cooldownRemainingMs,
+ }
+ end
+
+ pfUI.api.UseTrinket = function(slot, target)
+ if not UseTrinket then return false end
+ return UseTrinket(slot, target) == 1
+ end
+ end
+
+ -- Nampower Item Stats API (use distinct name to avoid conflicts)
+ if GetItemStats then
+ pfUI.api.GetNampowerItemStats = function(itemId)
+ local success, stats = pcall(GetItemStats, itemId, true)
+ if not success or not stats then return nil end
+ return stats
+ end
+
+ -- Quick item level lookup
+ pfUI.api.GetNampowerItemLevel = function(itemId)
+ if GetItemLevel then
+ return GetItemLevel(itemId)
+ end
+ local success, stats = pcall(GetItemStats, itemId, true)
+ if success and stats then
+ return stats.itemLevel
+ end
+ return nil
+ end
+ end
+
+ -- Spell Modifiers API for damage/heal predictions
+ if GetSpellModifiers then
+ pfUI.api.GetSpellBonus = function(spellId, modType)
+ -- modType: 0=DAMAGE, 1=DURATION, 6=RADIUS, 7=CRIT, 10=CAST_TIME, 14=COST, etc.
+ local flat, percent, hasmod = GetSpellModifiers(spellId, modType or 0)
+ return {
+ flat = flat or 0,
+ percent = percent or 0,
+ hasModifier = hasmod and hasmod ~= 0,
+ }
+ end
+
+ -- Common spell modifier lookups
+ pfUI.api.GetSpellDamageBonus = function(spellId)
+ return pfUI.api.GetSpellBonus(spellId, 0) -- DAMAGE
+ end
+
+ pfUI.api.GetSpellCritBonus = function(spellId)
+ return pfUI.api.GetSpellBonus(spellId, 7) -- CRITICAL_CHANCE
+ end
+
+ pfUI.api.GetSpellCostReduction = function(spellId)
+ return pfUI.api.GetSpellBonus(spellId, 14) -- COST
+ end
+ end
+
+ -- Inventory/Bag API
+ if GetBagItems then
+ pfUI.api.GetAllBagItems = function()
+ return GetBagItems()
+ end
+
+ pfUI.api.FindItem = function(itemIdOrName)
+ if FindPlayerItemSlot then
+ local bag, slot = FindPlayerItemSlot(itemIdOrName)
+ return bag, slot
+ end
+ return nil, nil
+ end
+
+ pfUI.api.UseItem = function(itemIdOrName, target)
+ if UseItemIdOrName then
+ return UseItemIdOrName(itemIdOrName, target) == 1
+ end
+ return false
+ end
+ end
+
+ -- Equipment Inspection API
+ if GetEquippedItems then
+ pfUI.api.GetPlayerEquipment = function()
+ return GetEquippedItems("player")
+ end
+
+ pfUI.api.GetTargetEquipment = function()
+ return GetEquippedItems("target")
+ end
+
+ pfUI.api.GetEquippedItemInfo = function(unit, slot)
+ if GetEquippedItem then
+ return GetEquippedItem(unit, slot)
+ end
+ return nil
+ end
+ end
+
+ -- Spell Lookup Helpers
+ if GetSpellIdForName then
+ pfUI.api.GetMaxRankSpellId = function(spellName)
+ return GetSpellIdForName(spellName)
+ end
+ end
+
+ if GetSpellSlotTypeIdForName then
+ pfUI.api.GetSpellSlotInfo = function(spellName)
+ local slot, bookType, spellId = GetSpellSlotTypeIdForName(spellName)
+ return {
+ slot = slot,
+ bookType = bookType,
+ spellId = spellId,
+ }
+ end
+ end
+
+ -- Queue Script API for advanced macro functionality
+ if QueueScript then
+ pfUI.api.QueueLuaScript = function(script, priority)
+ QueueScript(script, priority or 1)
+ end
+ end
+
+ if QueueSpellByName then
+ pfUI.api.QueueSpell = function(spellName)
+ QueueSpellByName(spellName)
+ end
+ end
+
+ -- Channel optimization
+ if ChannelStopCastingNextTick then
+ pfUI.api.StopChannelNextTick = function()
+ ChannelStopCastingNextTick()
+ end
+ end
+
+ -- Spell Database Access via GetSpellRec
+ if GetSpellRec then
+ pfUI.api.GetSpellRecord = function(spellId)
+ local rec = GetSpellRec(spellId)
+ if not rec then return nil end
+ return {
+ spellId = spellId,
+ name = rec.name,
+ rank = rec.rank,
+ description = rec.description,
+ manaCost = rec.manaCost,
+ baseLevel = rec.baseLevel,
+ spellLevel = rec.spellLevel,
+ maxLevel = rec.maxLevel,
+ maxTargetLevel = rec.maxTargetLevel,
+ maxTargets = rec.maxTargets,
+ durationIndex = rec.durationIndex,
+ powerType = rec.powerType,
+ rangeIndex = rec.rangeIndex,
+ speed = rec.speed,
+ schoolMask = rec.schoolMask,
+ runeCostID = rec.runeCostID,
+ spellMissileID = rec.spellMissileID,
+ iconID = rec.iconID,
+ activeIconID = rec.activeIconID,
+ nameSubtext = rec.nameSubtext,
+ castingTimeIndex = rec.castingTimeIndex,
+ categoryRecoveryTime = rec.categoryRecoveryTime,
+ recoveryTime = rec.recoveryTime,
+ startRecoveryCategory = rec.startRecoveryCategory,
+ startRecoveryTime = rec.startRecoveryTime,
+ }
+ end
+
+ -- Get spell school (fire, frost, nature, etc.)
+ pfUI.api.GetSpellSchool = function(spellId)
+ local rec = GetSpellRec(spellId)
+ if not rec then return nil end
+ local schools = {
+ [1] = "Physical",
+ [2] = "Holy",
+ [4] = "Fire",
+ [8] = "Nature",
+ [16] = "Frost",
+ [32] = "Shadow",
+ [64] = "Arcane",
+ }
+ return schools[rec.schoolMask] or "Unknown"
+ end
+ end
+
+ -- Disenchant All utility
+ if DisenchantAll then
+ pfUI.api.DisenchantAllItems = function()
+ DisenchantAll()
+ end
+
+ SLASH_PFDISENCHANTALL1 = "/disenchantall"
+ SLASH_PFDISENCHANTALL2 = "/dea"
+ SlashCmdList["PFDISENCHANTALL"] = function()
+ DisenchantAll()
+ DEFAULT_CHAT_FRAME:AddMessage("|cff33ffccpfUI|r: Disenchanting all eligible items...")
+ end
+ end
+
+ -- Enhanced Heal Prediction with AURA_CAST events
+ -- This helps libpredict detect HoT applications more accurately
+ if libpredict then
+ local auraCastFrame = CreateFrame("Frame")
+ auraCastFrame:RegisterEvent("AURA_CAST_ON_SELF")
+ auraCastFrame:RegisterEvent("AURA_CAST_ON_OTHER")
+
+ auraCastFrame:SetScript("OnEvent", function()
+ local casterGuid = arg1
+ local targetGuid = arg2
+ local spellId = arg3
+
+ if not spellId or not targetGuid then return end
+
+ -- Get spell name
+ local spellName
+ if SpellInfo then
+ spellName = SpellInfo(spellId)
+ elseif GetSpellNameAndRankForId then
+ spellName = GetSpellNameAndRankForId(spellId)
+ end
+
+ if not spellName then return end
+
+ -- Check if this is a HoT spell we care about
+ local hotSpells = {
+ ["Rejuvenation"] = true,
+ ["Renew"] = true,
+ ["Regrowth"] = true,
+ ["Verjüngung"] = true, -- German
+ ["Erneuerung"] = true,
+ ["Nachwachsen"] = true,
+ }
+
+ if hotSpells[spellName] then
+ -- Signal to libpredict that a HoT was applied
+ -- This can be used to update heal predictions
+ if pfUI.api.libpredict and pfUI.api.libpredict.OnHotApplied then
+ pfUI.api.libpredict:OnHotApplied(targetGuid, spellName, spellId)
+ end
+ end
+ end)
+ end
+
+ -- Swing Timer Integration
+ -- Track auto-attack swing timers for melee classes
+ local swingFrame = CreateFrame("Frame")
+ swingFrame.mainHand = { start = 0, speed = 0 }
+ swingFrame.offHand = { start = 0, speed = 0 }
+ swingFrame.ranged = { start = 0, speed = 0 }
+
+ swingFrame:RegisterEvent("PLAYER_ENTER_COMBAT")
+ swingFrame:RegisterEvent("PLAYER_LEAVE_COMBAT")
+ swingFrame:RegisterEvent("CHAT_MSG_COMBAT_SELF_HITS")
+ swingFrame:RegisterEvent("CHAT_MSG_COMBAT_SELF_MISSES")
+
+ swingFrame:SetScript("OnEvent", function()
+ if event == "PLAYER_ENTER_COMBAT" then
+ local mainSpeed, offSpeed = UnitAttackSpeed("player")
+ this.mainHand.speed = mainSpeed or 2
+ this.offHand.speed = offSpeed or 0
+ this.mainHand.start = GetTime()
+ if this.offHand.speed > 0 then
+ this.offHand.start = GetTime()
+ end
+ elseif event == "CHAT_MSG_COMBAT_SELF_HITS" or event == "CHAT_MSG_COMBAT_SELF_MISSES" then
+ -- Reset swing timer on hit/miss
+ local mainSpeed, offSpeed = UnitAttackSpeed("player")
+ this.mainHand.speed = mainSpeed or 2
+ this.mainHand.start = GetTime()
+ end
+ end)
+
+ pfUI.api.GetSwingTimers = function()
+ local now = GetTime()
+ local mainRemaining = swingFrame.mainHand.speed - (now - swingFrame.mainHand.start)
+ local offRemaining = swingFrame.offHand.speed > 0 and (swingFrame.offHand.speed - (now - swingFrame.offHand.start)) or 0
+
+ return {
+ mainHand = {
+ remaining = math.max(0, mainRemaining),
+ speed = swingFrame.mainHand.speed,
+ progress = swingFrame.mainHand.speed > 0 and (1 - math.max(0, mainRemaining) / swingFrame.mainHand.speed) or 0,
+ },
+ offHand = {
+ remaining = math.max(0, offRemaining),
+ speed = swingFrame.offHand.speed,
+ progress = swingFrame.offHand.speed > 0 and (1 - math.max(0, offRemaining) / swingFrame.offHand.speed) or 0,
+ },
+ }
+ end
+end)
diff --git a/modules/panel.lua b/modules/panel.lua
index 755cd079..8f235776 100644
--- a/modules/panel.lua
+++ b/modules/panel.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("panel", "vanilla:tbc", function()
+pfUI:RegisterModule("panel", "vanilla", function()
-- initialize gold cache if not yet happened
pfUI_cache["gold"] = pfUI_cache["gold"] or {}
diff --git a/modules/pet.lua b/modules/pet.lua
index 223c633c..46a45ede 100644
--- a/modules/pet.lua
+++ b/modules/pet.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("pet", "vanilla:tbc", function ()
+pfUI:RegisterModule("pet", "vanilla", function ()
-- do not go further on disabled UFs
if C.unitframes.disable == "1" then return end
pfUI.uf.pet = pfUI.uf:CreateUnitFrame("Pet", nil, C.unitframes.pet)
diff --git a/modules/pettarget.lua b/modules/pettarget.lua
index 017c30c4..1fe945df 100644
--- a/modules/pettarget.lua
+++ b/modules/pettarget.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("pettarget", "vanilla:tbc", function ()
+pfUI:RegisterModule("pettarget", "vanilla", function ()
-- do not go further on disabled UFs
if C.unitframes.disable == "1" then return end
local rawborder, default_border = GetBorderSize("unitframes")
diff --git a/modules/pixelperfect.lua b/modules/pixelperfect.lua
index ec4166d4..16862787 100644
--- a/modules/pixelperfect.lua
+++ b/modules/pixelperfect.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("pixelperfect", "vanilla:tbc", function ()
+pfUI:RegisterModule("pixelperfect", "vanilla", function ()
-- pre-calculated min values
local statics = {
[4] = 1.4222222222222,
diff --git a/modules/player.lua b/modules/player.lua
index 59979fff..91302d80 100644
--- a/modules/player.lua
+++ b/modules/player.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("player", "vanilla:tbc", function ()
+pfUI:RegisterModule("player", "vanilla", function ()
-- do not go further on disabled UFs
if C.unitframes.disable == "1" then return end
diff --git a/modules/questitem.lua b/modules/questitem.lua
index 7a8715c6..290495e2 100644
--- a/modules/questitem.lua
+++ b/modules/questitem.lua
@@ -96,11 +96,7 @@ pfUI:RegisterModule("questitem", function ()
SelectQuestLogEntry(quest)
-- detect and ignore quest headers
- if pfUI.client <= 11200 then -- vanilla
- _, _, _, header = GetQuestLogTitle(quest)
- elseif pfUI.client > 11200 then -- tbc
- _, _, _, _, header = GetQuestLogTitle(quest)
- end
+ _, _, _, header = GetQuestLogTitle(quest)
if not header then
text, objective = GetQuestLogQuestText()
diff --git a/modules/raid.lua b/modules/raid.lua
index 5aaca7c8..6b3577ae 100644
--- a/modules/raid.lua
+++ b/modules/raid.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("raid", "vanilla:tbc", function ()
+pfUI:RegisterModule("raid", "vanilla", function ()
-- do not go further on disabled UFs
if C.unitframes.disable == "1" then return end
@@ -109,6 +109,11 @@ pfUI:RegisterModule("raid", "vanilla:tbc", function ()
end
end
+ -- rebuild unitmap after frame IDs are assigned
+ if pfUI.uf.RebuildUnitmap then
+ pfUI.uf.RebuildUnitmap()
+ end
+
this:Hide()
end)
diff --git a/modules/roll.lua b/modules/roll.lua
index 7762774c..8580e514 100644
--- a/modules/roll.lua
+++ b/modules/roll.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("roll", "vanilla:tbc", function ()
+pfUI:RegisterModule("roll", "vanilla", function ()
pfUI.roll = CreateFrame("Frame", "pfLootRoll", UIParent)
pfUI.roll.frames = {}
diff --git a/modules/screenshot.lua b/modules/screenshot.lua
index 54bb3425..d6ac5b8f 100644
--- a/modules/screenshot.lua
+++ b/modules/screenshot.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("screenshot", "vanilla:tbc", function ()
+pfUI:RegisterModule("screenshot", "vanilla", function ()
if C.screenshot.interval == "0"
and C.screenshot.levelup == "0"
and C.screenshot.pvprank == "0"
diff --git a/modules/sellvalue.lua b/modules/sellvalue.lua
index f854d089..a14427f8 100644
--- a/modules/sellvalue.lua
+++ b/modules/sellvalue.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("sellvalue", "vanilla:tbc", function ()
+pfUI:RegisterModule("sellvalue", "vanilla", function ()
local function AddVendorPrices(frame, id, count)
if pfSellData[id] then
local _, _, sell, buy = strfind(pfSellData[id], "(.*),(.*)")
diff --git a/modules/share.lua b/modules/share.lua
index a49841bc..d5cc522e 100644
--- a/modules/share.lua
+++ b/modules/share.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("share", "vanilla:tbc", function ()
+pfUI:RegisterModule("share", "vanilla", function ()
local function serialize(tbl, comp, name, ignored, spacing)
local spacing = spacing or ""
local match = nil
diff --git a/modules/skin.lua b/modules/skin.lua
index 7c890016..390a03f7 100644
--- a/modules/skin.lua
+++ b/modules/skin.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("skin", "vanilla:tbc", function ()
+pfUI:RegisterModule("skin", "vanilla", function ()
-- align UIParent panels
pfUI.panelalign = CreateFrame("Frame", "pfUIParentPanelAlign", UIParent)
pfUI.panelalign:SetScript("OnUpdate", function()
diff --git a/modules/socialmod.lua b/modules/socialmod.lua
index e18fea58..a3da0610 100644
--- a/modules/socialmod.lua
+++ b/modules/socialmod.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("socialmod", "vanilla:tbc", function ()
+pfUI:RegisterModule("socialmod", "vanilla", function ()
local playerdb = _G.pfUI_playerDB
pfUI.socialmod = CreateFrame("Frame", "pfSocialMod", UIParent)
pfUI.socialmod:RegisterEvent("CHAT_MSG_SYSTEM")
diff --git a/modules/superwow.lua b/modules/superwow.lua
index af30210d..0ffdf4c3 100644
--- a/modules/superwow.lua
+++ b/modules/superwow.lua
@@ -1,6 +1,82 @@
-- Compatibility layer to use castbars provided by SuperWoW:
-- https://github.com/balakethelock/SuperWoW
+-- DLL Status Check Command (always available)
+SLASH_PFDLLSTATUS1 = "/pfdll"
+SlashCmdList["PFDLLSTATUS"] = function()
+ local chat = DEFAULT_CHAT_FRAME
+ chat:AddMessage("|cff33ffccpfUI|r: DLL Status Check")
+
+ -- SuperWoW
+ if SUPERWOW_VERSION then
+ chat:AddMessage(" |cff00ff00SuperWoW|r: v" .. tostring(SUPERWOW_VERSION))
+ elseif SpellInfo or SetAutoloot then
+ chat:AddMessage(" |cffffff00SuperWoW|r: Detected (old version)")
+ else
+ chat:AddMessage(" |cffff0000SuperWoW|r: Not detected")
+ end
+
+ -- Nampower
+ if GetNampowerVersion then
+ chat:AddMessage(" |cff00ff00Nampower|r: v" .. tostring(GetNampowerVersion()))
+ else
+ chat:AddMessage(" |cffff0000Nampower|r: Not detected")
+ end
+
+ -- UnitXP
+ local hasUnitXP = pcall(UnitXP, "nop", "nop")
+ if hasUnitXP then
+ chat:AddMessage(" |cff00ff00UnitXP_SP3|r: Detected")
+ else
+ chat:AddMessage(" |cffff0000UnitXP_SP3|r: Not detected")
+ end
+
+ -- Check if castbar exists for indicator positioning
+ if pfUI.castbar and pfUI.castbar.player then
+ chat:AddMessage(" |cff00ff00Castbar|r: Available for indicator anchoring")
+ else
+ chat:AddMessage(" |cffffff00Castbar|r: Not available (indicators use fallback position)")
+ end
+
+ -- Check indicator frames
+ if pfUI.uf and pfUI.uf.target then
+ chat:AddMessage(" |cff00ff00Target frame|r: exists")
+ if pfUI.uf.target.behindIndicator then
+ chat:AddMessage(" |cff00ff00Behind indicator|r: created")
+ else
+ chat:AddMessage(" |cffff0000Behind indicator|r: NOT created")
+ end
+ if pfUI.uf.target.losIndicator then
+ chat:AddMessage(" |cff00ff00LOS indicator|r: created")
+ else
+ chat:AddMessage(" |cffff0000LOS indicator|r: NOT created")
+ end
+ else
+ chat:AddMessage(" |cffff0000Target frame|r: NOT found")
+ end
+end
+
+-- UnitXP Behind/LOS test command
+SLASH_PFBEHIND1 = "/pfbehind"
+SlashCmdList["PFBEHIND"] = function()
+ local chat = DEFAULT_CHAT_FRAME
+ if not UnitExists("target") then
+ chat:AddMessage("|cff33ffccpfUI|r: No target")
+ return
+ end
+
+ local hasUnitXP = pcall(UnitXP, "nop", "nop")
+ if not hasUnitXP then
+ chat:AddMessage("|cff33ffccpfUI|r: UnitXP not available")
+ return
+ end
+
+ local successB, behind = pcall(UnitXP, "behind", "player", "target")
+ local successL, inSight = pcall(UnitXP, "inSight", "player", "target")
+
+ chat:AddMessage("|cff33ffccpfUI|r: Behind=" .. tostring(behind) .. " LOS=" .. tostring(inSight))
+end
+
pfUI:RegisterModule("superwow", "vanilla", function ()
if SetAutoloot and SpellInfo and not SUPERWOW_VERSION then
-- Turn every enchanting link that we create in the enchanting frame,
@@ -248,12 +324,264 @@ pfUI:RegisterModule("superwow", "vanilla", function ()
libdebuff:AddEffect(unit, unitlevel, effect, duration, caster)
end)
- -- Enhance libcast with SuperWoW data
+ -- TrackUnit API for adding group members to minimap
+ -- Tracks friendly units on the minimap for easier group coordination
+ if TrackUnit and C.unitframes.track_group == "1" then
+ local trackFrame = CreateFrame("Frame")
+ trackFrame:RegisterEvent("PARTY_MEMBERS_CHANGED")
+ trackFrame:RegisterEvent("RAID_ROSTER_UPDATE")
+ trackFrame:RegisterEvent("PLAYER_ENTERING_WORLD")
+
+ trackFrame:SetScript("OnEvent", function()
+ -- Track party members
+ for i = 1, 4 do
+ local unit = "party" .. i
+ if UnitExists(unit) and UnitIsConnected(unit) then
+ pcall(TrackUnit, unit)
+ end
+ end
+
+ -- Track raid members
+ for i = 1, 40 do
+ local unit = "raid" .. i
+ if UnitExists(unit) and UnitIsConnected(unit) and not UnitIsUnit(unit, "player") then
+ pcall(TrackUnit, unit)
+ end
+ end
+ end)
+ end
+
+ -- Raid Marker Targeting API
+ -- Allows targeting units by raid marker ("mark1" to "mark8")
+ if SUPERWOW_VERSION then
+ pfUI.api.GetMarkedUnit = function(markIndex)
+ local markUnit = "mark" .. markIndex
+ if UnitExists(markUnit) then
+ return markUnit
+ end
+ return nil
+ end
+
+ pfUI.api.TargetMark = function(markIndex)
+ local markUnit = "mark" .. markIndex
+ if UnitExists(markUnit) then
+ TargetUnit(markUnit)
+ return true
+ end
+ return false
+ end
+
+ -- Get owner of pet/totem using "owner" suffix
+ pfUI.api.GetUnitOwner = function(unit)
+ local ownerUnit = unit .. "owner"
+ if UnitExists(ownerUnit) then
+ return UnitName(ownerUnit), ownerUnit
+ end
+ return nil
+ end
+ end
+
+ -- Enhanced SpellInfo API wrapper
+ if SpellInfo then
+ pfUI.api.GetSpellInfo = function(spellId)
+ local name, rank, texture, minRange, maxRange = SpellInfo(spellId)
+ return {
+ name = name,
+ rank = rank,
+ texture = texture,
+ minRange = minRange,
+ maxRange = maxRange,
+ spellId = spellId
+ }
+ end
+ end
+
+ -- Clickthrough Mode API
+ -- Allows clicking through corpses to loot underneath
+ if Clickthrough then
+ pfUI.api.SetClickthrough = function(enabled)
+ Clickthrough(enabled and 1 or 0)
+ end
+
+ pfUI.api.GetClickthrough = function()
+ return Clickthrough() == 1
+ end
+
+ pfUI.api.ToggleClickthrough = function()
+ local current = Clickthrough()
+ Clickthrough(current == 1 and 0 or 1)
+ return Clickthrough() == 1
+ end
+
+ -- Add slash command for clickthrough toggle
+ SLASH_PFCLICKTHROUGH1 = "/clickthrough"
+ SLASH_PFCLICKTHROUGH2 = "/ct"
+ SlashCmdList["PFCLICKTHROUGH"] = function()
+ local enabled = pfUI.api.ToggleClickthrough()
+ DEFAULT_CHAT_FRAME:AddMessage("|cff33ffccpfUI|r: Clickthrough mode " .. (enabled and "|cff00ff00enabled|r" or "|cffff0000disabled|r"))
+ end
+ end
+
+ -- Autoloot Control API
+ if SetAutoloot then
+ pfUI.api.SetAutoloot = function(enabled)
+ SetAutoloot(enabled and 1 or 0)
+ end
+
+ pfUI.api.GetAutoloot = function()
+ return SetAutoloot() == 1
+ end
+
+ pfUI.api.ToggleAutoloot = function()
+ local current = SetAutoloot()
+ SetAutoloot(current == 1 and 0 or 1)
+ return SetAutoloot() == 1
+ end
+ end
+
+ -- Config Import/Export API using ImportFile/ExportFile
+ if ImportFile and ExportFile then
+ pfUI.api.ExportConfig = function(filename)
+ filename = filename or "pfUI_config_backup.txt"
+ local configStr = ""
+
+ -- Serialize config to string
+ local function serialize(tbl, indent)
+ indent = indent or ""
+ local result = "{\n"
+ for k, v in pairs(tbl) do
+ local keyStr = type(k) == "string" and '["' .. k .. '"]' or "[" .. tostring(k) .. "]"
+ if type(v) == "table" then
+ result = result .. indent .. " " .. keyStr .. " = " .. serialize(v, indent .. " ") .. ",\n"
+ elseif type(v) == "string" then
+ result = result .. indent .. " " .. keyStr .. ' = "' .. v .. '",\n'
+ else
+ result = result .. indent .. " " .. keyStr .. " = " .. tostring(v) .. ",\n"
+ end
+ end
+ return result .. indent .. "}"
+ end
+
+ if pfUI_config then
+ configStr = "pfUI_config = " .. serialize(pfUI_config)
+ ExportFile(filename, configStr)
+ DEFAULT_CHAT_FRAME:AddMessage("|cff33ffccpfUI|r: Config exported to imports/" .. filename)
+ return true
+ end
+ return false
+ end
+
+ pfUI.api.ImportConfig = function(filename)
+ filename = filename or "pfUI_config_backup.txt"
+ local content = ImportFile(filename)
+ if content and content ~= "" then
+ -- Load the config string
+ local func, err = loadstring(content)
+ if func then
+ func()
+ DEFAULT_CHAT_FRAME:AddMessage("|cff33ffccpfUI|r: Config imported from imports/" .. filename)
+ DEFAULT_CHAT_FRAME:AddMessage("|cff33ffccpfUI|r: Please /reload to apply changes")
+ return true
+ else
+ DEFAULT_CHAT_FRAME:AddMessage("|cff33ffccpfUI|r: Error parsing config: " .. (err or "unknown"))
+ end
+ else
+ DEFAULT_CHAT_FRAME:AddMessage("|cff33ffccpfUI|r: Could not read imports/" .. filename)
+ end
+ return false
+ end
+
+ -- Slash commands for config backup
+ SLASH_PFEXPORT1 = "/pfexport"
+ SlashCmdList["PFEXPORT"] = function(msg)
+ pfUI.api.ExportConfig(msg ~= "" and msg or nil)
+ end
+
+ SLASH_PFIMPORT1 = "/pfimport"
+ SlashCmdList["PFIMPORT"] = function(msg)
+ pfUI.api.ImportConfig(msg ~= "" and msg or nil)
+ end
+ end
+
+ -- GetPlayerBuffID wrapper
+ if GetPlayerBuffID then
+ pfUI.api.GetPlayerBuffSpellId = function(buffIndex)
+ return GetPlayerBuffID(buffIndex)
+ end
+ end
+
+ -- CombatLogAdd wrapper for logging
+ if CombatLogAdd then
+ pfUI.api.LogToCombatLog = function(text, raw)
+ CombatLogAdd(text, raw and 1 or nil)
+ end
+ end
+
+ -- Local Raid Markers (marks only visible to self)
+ if SetRaidTarget then
+ local origSetRaidTarget = SetRaidTarget
+ pfUI.api.SetLocalRaidTarget = function(unit, index)
+ origSetRaidTarget(unit, index, "local")
+ end
+ end
+
+ -- Enhanced GetContainerItemInfo for charges
+ -- SuperWoW returns charges as negative numbers
+ pfUI.api.GetItemCharges = function(bag, slot)
+ local texture, count = GetContainerItemInfo(bag, slot)
+ if count and count < 0 then
+ return math.abs(count) -- Return positive charge count
+ end
+ return nil -- Not a charged item
+ end
+
+ -- Weapon Enchant Info on other players
+ if GetWeaponEnchantInfo then
+ local origGetWeaponEnchantInfo = GetWeaponEnchantInfo
+ pfUI.api.GetUnitWeaponEnchants = function(unit)
+ if unit and unit ~= "player" then
+ local mhName, ohName = GetWeaponEnchantInfo(unit)
+ return {
+ mainHand = mhName,
+ offHand = ohName,
+ }
+ else
+ local hasMainHandEnchant, mainHandExpiration, mainHandCharges, hasOffHandEnchant, offHandExpiration, offHandCharges = origGetWeaponEnchantInfo()
+ return {
+ mainHand = hasMainHandEnchant and true or false,
+ mainHandExpiration = mainHandExpiration,
+ mainHandCharges = mainHandCharges,
+ offHand = hasOffHandEnchant and true or false,
+ offHandExpiration = offHandExpiration,
+ offHandCharges = offHandCharges,
+ }
+ end
+ end
+ end
+
+ -- Enhance libcast with SuperWoW data for NPCs and other players only
+ -- Player casts use SPELLCAST_* events for proper pushback handling
local supercast = CreateFrame("Frame")
+ local playerGuid = nil
+
+ supercast:RegisterEvent("PLAYER_ENTERING_WORLD")
supercast:RegisterEvent("UNIT_CASTEVENT")
supercast:SetScript("OnEvent", function()
- if not supercast.init then
- -- disable combat parsing events in superwow mode
+ if event == "PLAYER_ENTERING_WORLD" then
+ -- Cache player GUID
+ if UnitExists then
+ local _, guid = UnitExists("player")
+ playerGuid = guid
+ end
+ return
+ end
+
+ local guid = arg1
+ local isPlayer = guid == playerGuid
+
+ -- For non-player units: disable combat parsing events (one-time init)
+ if not isPlayer and not supercast.init then
+ -- disable combat parsing events in superwow mode (for non-player units)
libcast:UnregisterEvent("CHAT_MSG_SPELL_SELF_DAMAGE")
libcast:UnregisterEvent("CHAT_MSG_SPELL_HOSTILEPLAYER_DAMAGE")
libcast:UnregisterEvent("CHAT_MSG_SPELL_HOSTILEPLAYER_BUFF")
@@ -276,13 +604,10 @@ pfUI:RegisterModule("superwow", "vanilla", function ()
end
if arg3 == "START" or arg3 == "CAST" or arg3 == "CHANNEL" then
- -- human readable argument list
- local guid = arg1
local target = arg2
local event_type = arg3
local spell_id = arg4
local timer = arg5
- local start = GetTime()
-- get spell info from spell id
local spell, icon, _
@@ -297,35 +622,31 @@ pfUI:RegisterModule("superwow", "vanilla", function ()
-- skip on buff procs during cast
if event_type == "CAST" then
if not libcast.db[guid] or libcast.db[guid].cast ~= spell then
- -- ignore casts without 'START' event, while there is already another cast.
- -- those events can be for example a frost shield proc while casting frostbolt.
- -- we want to keep the cast itself, so we simply skip those.
return
end
end
+ -- For player: store in libcast.db[playerName] so pushback tracking works
+ -- For others: store by GUID
+ local dbKey = isPlayer and UnitName("player") or guid
+
-- add cast action to the database
- if not libcast.db[guid] then libcast.db[guid] = {} end
- libcast.db[guid].cast = spell
- libcast.db[guid].rank = nil
- libcast.db[guid].start = GetTime()
- libcast.db[guid].casttime = timer
- libcast.db[guid].icon = icon
- libcast.db[guid].channel = event_type == "CHANNEL" or false
-
- -- write state variable
- superwow_active = true
+ if not libcast.db[dbKey] then libcast.db[dbKey] = {} end
+ libcast.db[dbKey].cast = spell
+ libcast.db[dbKey].rank = nil
+ libcast.db[dbKey].start = GetTime()
+ libcast.db[dbKey].casttime = timer or 0
+ libcast.db[dbKey].icon = icon
+ libcast.db[dbKey].channel = event_type == "CHANNEL" or false
elseif arg3 == "FAIL" then
- local guid = arg1
-
- -- delete all cast entries of guid
- if libcast.db[guid] then
- libcast.db[guid].cast = nil
- libcast.db[guid].rank = nil
- libcast.db[guid].start = nil
- libcast.db[guid].casttime = nil
- libcast.db[guid].icon = nil
- libcast.db[guid].channel = nil
+ local dbKey = isPlayer and UnitName("player") or guid
+ if libcast.db[dbKey] then
+ libcast.db[dbKey].cast = nil
+ libcast.db[dbKey].rank = nil
+ libcast.db[dbKey].start = nil
+ libcast.db[dbKey].casttime = nil
+ libcast.db[dbKey].icon = nil
+ libcast.db[dbKey].channel = nil
end
end
end)
diff --git a/modules/target.lua b/modules/target.lua
index 9522b8d0..11104094 100644
--- a/modules/target.lua
+++ b/modules/target.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("target", "vanilla:tbc", function ()
+pfUI:RegisterModule("target", "vanilla", function ()
-- do not go further on disabled UFs
if C.unitframes.disable == "1" then return end
diff --git a/modules/targettarget.lua b/modules/targettarget.lua
index 893ad670..e8310065 100644
--- a/modules/targettarget.lua
+++ b/modules/targettarget.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("targettarget", "vanilla:tbc", function ()
+pfUI:RegisterModule("targettarget", "vanilla", function ()
-- do not go further on disabled UFs
if C.unitframes.disable == "1" then return end
diff --git a/modules/targettargettarget.lua b/modules/targettargettarget.lua
index 6e912b3b..ec31d90c 100644
--- a/modules/targettargettarget.lua
+++ b/modules/targettargettarget.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("targettargettarget", "vanilla:tbc", function ()
+pfUI:RegisterModule("targettargettarget", "vanilla", function ()
-- do not go further on disabled UFs
if C.unitframes.disable == "1" then return end
diff --git a/modules/thirdparty.lua b/modules/thirdparty.lua
index f480df7f..f84037f7 100644
--- a/modules/thirdparty.lua
+++ b/modules/thirdparty.lua
@@ -1,10 +1,7 @@
-pfUI:RegisterModule("thirdparty", "vanilla:tbc", function()
+pfUI:RegisterModule("thirdparty", "vanilla", function()
-- This module includes the core logic of thirdparty modules.
-- Right now, in particular the functions to register addons to the
-- dockframe of the chat panel aswell as the thirdparty root-table.
- -- This module is supposed to be loaded on all expansions, so only
- -- addons that can share the same glue code across expansions will go here.
- -- For expansion related code, see: thirdparty-vanilla and thirdparty-tbc.
pfUI.thirdparty = {}
@@ -196,8 +193,7 @@ pfUI:RegisterModule("thirdparty", "vanilla:tbc", function()
end
-- MrPlow Bag Sorting Addon.
- -- Vanilla: https://www.wowace.com/projects/mr-plow/files/288059
- -- TBC: https://www.wowace.com/projects/mr-plow/files/136162
+ -- https://www.wowace.com/projects/mr-plow/files/288059
HookAddonOrVariable("MrPlow", function()
if C.thirdparty.mrplow.enable == "0" then return end
@@ -232,8 +228,7 @@ pfUI:RegisterModule("thirdparty", "vanilla:tbc", function()
end)
-- ShaguDPS Damage Meter
- -- Vanilla: https://github.com/shagu/ShaguDPS
- -- TBC: https://github.com/shagu/ShaguDPS
+ -- https://github.com/shagu/ShaguDPS
HookAddonOrVariable("ShaguDPS", function()
local docktable = { "shagudps", "ShaguDPS", "ShaguDPSWindow",
function() -- single
@@ -333,8 +328,7 @@ pfUI:RegisterModule("thirdparty", "vanilla:tbc", function()
end)
-- DPSMate Damage Meter
- -- Vanilla: https://github.com/Geigerkind/DPSMate
- -- TBC: https://github.com/Geigerkind/DPSMateTBC
+ -- https://github.com/Geigerkind/DPSMate
HookAddonOrVariable("DPSMate_DPSMate", function()
local docktable = { "dpsmate", "DPSMate", "DPSMate_DPSMate",
function() -- single
diff --git a/modules/tooltip.lua b/modules/tooltip.lua
index 03c51040..054b604b 100644
--- a/modules/tooltip.lua
+++ b/modules/tooltip.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("tooltip", "vanilla:tbc", function ()
+pfUI:RegisterModule("tooltip", "vanilla", function ()
local rawborder, default_border = GetBorderSize()
pfUI.tooltip = CreateFrame('Frame', "pfTooltip", GameTooltip)
diff --git a/modules/totems.lua b/modules/totems.lua
index 59eab973..56ab9480 100644
--- a/modules/totems.lua
+++ b/modules/totems.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("totems", "vanilla:tbc", function ()
+pfUI:RegisterModule("totems", "vanilla", function ()
local _, class = UnitClass("player")
local slots = {
@@ -42,9 +42,6 @@ pfUI:RegisterModule("totems", "vanilla:tbc", function ()
-- Try to recast totem on left click in vanilla
local active, name, start, duration, icon = GetTotemInfo(this.id)
if name then CastSpellByName(name) end
- elseif pfUI.client > 11200 and this.id and arg1 and arg1 == "RightButton" then
- -- Try to cancel totem on right click in tbc+
- DestroyTotem(this.id)
end
end
diff --git a/modules/uf_tukui.lua b/modules/uf_tukui.lua
index b48e3829..e798043c 100644
--- a/modules/uf_tukui.lua
+++ b/modules/uf_tukui.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("uf_tukui", "vanilla:tbc", function ()
+pfUI:RegisterModule("uf_tukui", "vanilla", function ()
if C.unitframes.disable == "1" or C.unitframes.layout ~= "tukui" then return end
-- update player layout
diff --git a/modules/unitxp.lua b/modules/unitxp.lua
new file mode 100644
index 00000000..bc9b1833
--- /dev/null
+++ b/modules/unitxp.lua
@@ -0,0 +1,234 @@
+-- UnitXP_SP3 integration module
+-- Provides Line of Sight indicator, OS notifications, and enhanced targeting
+-- Requires UnitXP_SP3 DLL: https://github.com/allfoxwy/UnitXP_SP3
+
+pfUI:RegisterModule("unitxp", "vanilla", function ()
+ -- Check if UnitXP is available
+ local hasUnitXP = pcall(UnitXP, "nop", "nop")
+ if not hasUnitXP then return end
+
+ local rawborder, border = GetBorderSize()
+
+ -- Helper to create indicators after target frame exists
+ local function CreateTargetIndicators()
+ if not pfUI.uf or not pfUI.uf.target then return false end
+
+ -- Behind Indicator for all units (TOP)
+ if C.unitframes.behind_indicator == "1" and not pfUI.uf.target.behindIndicator then
+ local behindFrame = CreateFrame("Frame", "pfBehindIndicator", pfUI.uf.target)
+ behindFrame:SetAllPoints(pfUI.uf.target)
+ behindFrame:SetFrameLevel(pfUI.uf.target:GetFrameLevel() + 10)
+
+ behindFrame.text = behindFrame:CreateFontString(nil, "OVERLAY")
+ behindFrame.text:SetFont(pfUI.font_default, 13, "OUTLINE")
+ behindFrame.text:SetPoint("RIGHT", behindFrame, "RIGHT", -1, 7)
+ behindFrame.text:SetTextColor(0.3, 1, 0.3, 1)
+ behindFrame.text:SetText("BEHIND")
+ behindFrame.text:Hide()
+
+ local lastCheck = 0
+ behindFrame:SetScript("OnUpdate", function()
+ if GetTime() - lastCheck < 0.1 then return end
+ lastCheck = GetTime()
+
+ if not UnitExists("target") then
+ this.text:Hide()
+ return
+ end
+
+ local success, behind = pcall(UnitXP, "behind", "player", "target")
+ if success and behind then
+ this.text:Show()
+ else
+ this.text:Hide()
+ end
+ end)
+
+ pfUI.uf.target.behindIndicator = behindFrame
+ end
+
+ -- Line of Sight Indicator on Target Frame (BELOW BEHIND)
+ if C.unitframes.los_indicator == "1" and not pfUI.uf.target.losIndicator then
+ local losFrame = CreateFrame("Frame", "pfLoSIndicator", pfUI.uf.target)
+ losFrame:SetAllPoints(pfUI.uf.target)
+ losFrame:SetFrameLevel(pfUI.uf.target:GetFrameLevel() + 10)
+
+ losFrame.text = losFrame:CreateFontString(nil, "OVERLAY")
+ losFrame.text:SetFont(pfUI.font_default, 13, "OUTLINE")
+ losFrame.text:SetPoint("RIGHT", losFrame, "RIGHT", -1, -7)
+ losFrame.text:SetTextColor(1, 0.3, 0.3, 1)
+ losFrame.text:SetText("NO LOS")
+ losFrame.text:Hide()
+
+ local lastCheck = 0
+ losFrame:SetScript("OnUpdate", function()
+ if GetTime() - lastCheck < 0.2 then return end
+ lastCheck = GetTime()
+
+ if not UnitExists("target") then
+ this.text:Hide()
+ return
+ end
+
+ local success, inSight = pcall(UnitXP, "inSight", "player", "target")
+ if success and inSight == false then
+ this.text:Show()
+ else
+ this.text:Hide()
+ end
+ end)
+
+ pfUI.uf.target.losIndicator = losFrame
+ end
+
+ return true
+ end
+
+ -- Try to create indicators now
+ CreateTargetIndicators()
+
+ -- Also try on PLAYER_ENTERING_WORLD in case target frame wasn't ready
+ local initFrame = CreateFrame("Frame")
+ initFrame:RegisterEvent("PLAYER_ENTERING_WORLD")
+ initFrame:SetScript("OnEvent", function()
+ CreateTargetIndicators()
+ this:UnregisterAllEvents()
+ end)
+
+ -- OS Notification Support
+ if C.unitframes.unitxp_notify == "1" then
+ local notifyFrame = CreateFrame("Frame")
+ notifyFrame:RegisterEvent("CHAT_MSG_WHISPER")
+ notifyFrame:RegisterEvent("CHAT_MSG_BN_WHISPER")
+ notifyFrame:RegisterEvent("READY_CHECK")
+ notifyFrame:RegisterEvent("RAID_INSTANCE_WELCOME")
+
+ notifyFrame:SetScript("OnEvent", function()
+ pcall(UnitXP, "notify", "taskbarIcon")
+ pcall(UnitXP, "notify", "systemSound")
+ end)
+
+ -- Also notify on BG queue pop
+ local origBattlefieldPortShow = BattlefieldFrame_Show
+ if origBattlefieldPortShow then
+ BattlefieldFrame_Show = function()
+ pcall(UnitXP, "notify", "taskbarIcon")
+ pcall(UnitXP, "notify", "systemSound")
+ return origBattlefieldPortShow()
+ end
+ end
+ end
+
+ -- Enhanced Distance API
+ pfUI.api.GetPreciseDistance = function(unit1, unit2)
+ if not unit2 then
+ unit2 = unit1
+ unit1 = "player"
+ end
+ local success, distance = pcall(UnitXP, "distanceBetween", unit1, unit2)
+ if success then return distance end
+ return nil
+ end
+
+ pfUI.api.IsInMeleeRange = function(unit)
+ local success, distance = pcall(UnitXP, "distanceBetween", "player", unit, "meleeAutoAttack")
+ if success and distance then
+ return distance <= 5
+ end
+ return nil
+ end
+
+ pfUI.api.GetAoEDistance = function(unit1, unit2)
+ if not unit2 then
+ unit2 = unit1
+ unit1 = "player"
+ end
+ local success, distance = pcall(UnitXP, "distanceBetween", unit1, unit2, "AoE")
+ if success then return distance end
+ return nil
+ end
+
+ -- Smart Targeting Helpers
+ pfUI.api.TargetNearestEnemy = function()
+ local success, found = pcall(UnitXP, "target", "nearestEnemy")
+ return success and found
+ end
+
+ pfUI.api.TargetHighestHP = function()
+ local success, found = pcall(UnitXP, "target", "mostHP")
+ return success and found
+ end
+
+ pfUI.api.TargetNextEnemy = function()
+ local success, found = pcall(UnitXP, "target", "nextEnemyInCycle")
+ return success and found
+ end
+
+ pfUI.api.TargetPreviousEnemy = function()
+ local success, found = pcall(UnitXP, "target", "previousEnemyInCycle")
+ return success and found
+ end
+
+ pfUI.api.TargetNextMarked = function(order)
+ local success, found = pcall(UnitXP, "target", "nextMarkedEnemyInCycle", order)
+ return success and found
+ end
+
+ pfUI.api.UnitInLineOfSight = function(unit1, unit2)
+ if not unit2 then
+ unit2 = unit1
+ unit1 = "player"
+ end
+ local success, inSight = pcall(UnitXP, "inSight", unit1, unit2)
+ if success then return inSight end
+ return nil
+ end
+
+ pfUI.api.UnitIsBehind = function(unit1, unit2)
+ if not unit2 then
+ unit2 = unit1
+ unit1 = "player"
+ end
+ local success, behind = pcall(UnitXP, "behind", unit1, unit2)
+ if success then return behind end
+ return nil
+ end
+
+ -- Debug command to test UnitXP indicators
+ SLASH_PFUNITXP1 = "/pfunitxp"
+ SlashCmdList["PFUNITXP"] = function()
+ local chat = DEFAULT_CHAT_FRAME
+ chat:AddMessage("|cff33ffccpfUI|r: UnitXP Indicator Debug")
+
+ -- Check if target exists
+ if not UnitExists("target") then
+ chat:AddMessage(" |cffff0000No target selected|r")
+ return
+ end
+
+ -- Test behind
+ local successB, behind = pcall(UnitXP, "behind", "player", "target")
+ chat:AddMessage(" Behind check: success=" .. tostring(successB) .. " value=" .. tostring(behind) .. " type=" .. type(behind))
+
+ -- Test LOS
+ local successL, inSight = pcall(UnitXP, "inSight", "player", "target")
+ chat:AddMessage(" LOS check: success=" .. tostring(successL) .. " value=" .. tostring(inSight) .. " type=" .. type(inSight))
+
+ -- Check if indicator frames exist
+ if pfUI.uf and pfUI.uf.target then
+ chat:AddMessage(" Target frame: |cff00ff00exists|r")
+ if pfUI.uf.target.behindIndicator then
+ chat:AddMessage(" Behind indicator: |cff00ff00created|r, visible=" .. tostring(pfUI.uf.target.behindIndicator:IsVisible()))
+ else
+ chat:AddMessage(" Behind indicator: |cffff0000NOT created|r (check settings)")
+ end
+ if pfUI.uf.target.losIndicator then
+ chat:AddMessage(" LOS indicator: |cff00ff00created|r")
+ else
+ chat:AddMessage(" LOS indicator: |cffff0000NOT created|r (check settings)")
+ end
+ else
+ chat:AddMessage(" Target frame: |cffff0000NOT found|r")
+ end
+ end
+end)
diff --git a/modules/unlock.lua b/modules/unlock.lua
index 59fcd473..629097d4 100644
--- a/modules/unlock.lua
+++ b/modules/unlock.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("unlock", "vanilla:tbc", function ()
+pfUI:RegisterModule("unlock", "vanilla", function ()
local rawborder, default_border = GetBorderSize()
-- grouped frames
diff --git a/modules/unusable.lua b/modules/unusable.lua
index 73a9d992..f51c2b6b 100644
--- a/modules/unusable.lua
+++ b/modules/unusable.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("unusable", "vanilla:tbc", function ()
+pfUI:RegisterModule("unusable", "vanilla", function ()
if not pfUI.bag then return end
if C.appearance.bags.unusable ~= "1" then return end
diff --git a/modules/updatenotify.lua b/modules/updatenotify.lua
index a88730dd..31aa9cdc 100644
--- a/modules/updatenotify.lua
+++ b/modules/updatenotify.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("updatenotify", "vanilla:tbc", function ()
+pfUI:RegisterModule("updatenotify", "vanilla", function ()
local alreadyshown = false
local localversion = tonumber(pfUI.version.major*10000 + pfUI.version.minor*100 + pfUI.version.fix)
local remoteversion = tonumber(pfUI_init.updateavailable) or 0
diff --git a/modules/xpbar.lua b/modules/xpbar.lua
index 7b1ed36f..54ca6a7d 100644
--- a/modules/xpbar.lua
+++ b/modules/xpbar.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("xpbar", "vanilla:tbc", function ()
+pfUI:RegisterModule("xpbar", "vanilla", function ()
local rawborder, default_border = GetBorderSize()
local parse_faction = SanitizePattern(FACTION_STANDING_INCREASED)
From b0a0d88a7b608f11ea2fa93e31a5bc295cc79bfd Mon Sep 17 00:00:00 2001
From: Meow <30401521+me0wg4ming@users.noreply.github.com>
Date: Sat, 3 Jan 2026 12:33:23 +0100
Subject: [PATCH 08/40] performance update
performance update
---
libs/libcast.lua | 124 +++++++++++++++++++++++++++++++++++++-------
libs/libpredict.lua | 77 ++++++---------------------
libs/librange.lua | 40 +++++++++-----
3 files changed, 151 insertions(+), 90 deletions(-)
diff --git a/libs/libcast.lua b/libs/libcast.lua
index 11cada49..d8fc6c0d 100644
--- a/libs/libcast.lua
+++ b/libs/libcast.lua
@@ -53,14 +53,50 @@ local scanner = libtipscan:GetScanner("libcast")
local libcast = CreateFrame("Frame", "pfEnemyCast")
local player = UnitName("player")
-UnitChannelInfo = _G.UnitChannelInfo or function(unit)
+-- Store original SuperWoW UnitChannelInfo if it exists
+local SuperWoW_UnitChannelInfo = _G.UnitChannelInfo
+
+UnitChannelInfo = function(unit)
-- convert to name if unitstring was given
- unit = pfValidUnits[unit] and UnitName(unit) or unit
+ local unitName = pfValidUnits[unit] and UnitName(unit) or unit
+
+ -- For player: ALWAYS use libcast.db because it handles channel updates correctly
+ local isPlayer = unit == "player" or unitName == player
+
+ if isPlayer then
+ local cast, nameSubtext, text, texture, startTime, endTime, isTradeSkill
+ local db = libcast.db[player]
+ if db and db.cast and db.start + db.casttime / 1000 > GetTime() then
+ if not db.channel then return end
+ cast = db.cast
+ nameSubtext = db.rank
+ text = ""
+ texture = db.icon
+ startTime = db.start * 1000
+ endTime = startTime + db.casttime
+ isTradeSkill = nil
+ elseif db then
+ db.cast = nil
+ db.rank = nil
+ db.start = nil
+ db.casttime = nil
+ db.icon = nil
+ db.channel = nil
+ end
+
+ return cast, nameSubtext, text, texture, startTime, endTime, isTradeSkill
+ end
+
+ -- For non-player units: use SuperWoW if available, otherwise use libcast.db
+ if SuperWoW_UnitChannelInfo then
+ return SuperWoW_UnitChannelInfo(unit)
+ end
+
+ -- Fallback to libcast.db for non-player units
local cast, nameSubtext, text, texture, startTime, endTime, isTradeSkill
- local db = libcast.db[unit]
+ local db = libcast.db[unitName]
- -- clean legacy values
if db and db.cast and db.start + db.casttime / 1000 > GetTime() then
if not db.channel then return end
cast = db.cast
@@ -71,7 +107,6 @@ UnitChannelInfo = _G.UnitChannelInfo or function(unit)
endTime = startTime + db.casttime
isTradeSkill = nil
elseif db then
- -- remove cast action to the database
db.cast = nil
db.rank = nil
db.start = nil
@@ -83,14 +118,51 @@ UnitChannelInfo = _G.UnitChannelInfo or function(unit)
return cast, nameSubtext, text, texture, startTime, endTime, isTradeSkill
end
-UnitCastingInfo = _G.UnitCastingInfo or function(unit)
+-- Store original SuperWoW UnitCastingInfo if it exists
+local SuperWoW_UnitCastingInfo = _G.UnitCastingInfo
+
+UnitCastingInfo = function(unit)
-- convert to name if unitstring was given
- unit = pfValidUnits[unit] and UnitName(unit) or unit
+ local unitName = pfValidUnits[unit] and UnitName(unit) or unit
+
+ -- For player: ALWAYS use libcast.db because it handles pushback correctly
+ -- SuperWoW's UnitCastingInfo doesn't track SPELLCAST_DELAYED events
+ local isPlayer = unit == "player" or unitName == player
+
+ if isPlayer then
+ local cast, nameSubtext, text, texture, startTime, endTime, isTradeSkill
+ local db = libcast.db[player]
+ if db and db.cast and db.start + db.casttime / 1000 > GetTime() then
+ if db.channel then return end
+ cast = db.cast
+ nameSubtext = db.rank or ""
+ text = ""
+ texture = db.icon
+ startTime = db.start * 1000
+ endTime = startTime + db.casttime
+ isTradeSkill = nil
+ elseif db then
+ db.cast = nil
+ db.rank = nil
+ db.start = nil
+ db.casttime = nil
+ db.icon = nil
+ db.channel = nil
+ end
+
+ return cast, nameSubtext, text, texture, startTime, endTime, isTradeSkill
+ end
+
+ -- For non-player units: use SuperWoW if available, otherwise use libcast.db
+ if SuperWoW_UnitCastingInfo then
+ return SuperWoW_UnitCastingInfo(unit)
+ end
+
+ -- Fallback to libcast.db for non-player units
local cast, nameSubtext, text, texture, startTime, endTime, isTradeSkill
- local db = libcast.db[unit]
+ local db = libcast.db[unitName]
- -- clean legacy values
if db and db.cast and db.start + db.casttime / 1000 > GetTime() then
if db.channel then return end
cast = db.cast
@@ -101,7 +173,6 @@ UnitCastingInfo = _G.UnitCastingInfo or function(unit)
endTime = startTime + db.casttime
isTradeSkill = nil
elseif db then
- -- remove cast action to the database
db.cast = nil
db.rank = nil
db.start = nil
@@ -182,17 +253,31 @@ libcast:RegisterEvent("SPELLCAST_CHANNEL_STOP")
libcast:RegisterEvent("SPELLCAST_CHANNEL_UPDATE")
local mob, spell, icon, _
+
libcast:SetScript("OnEvent", function()
-- Fill database with player casts
if event == "SPELLCAST_START" then
icon = L["spells"][arg1] and L["spells"][arg1].icon and string.format("%s%s", "Interface\\Icons\\", L["spells"][arg1].icon) or lastcasttex
- -- add cast action to the database
- this.db[player].cast = arg1
- this.db[player].rank = lastrank
- this.db[player].start = GetTime()
- this.db[player].casttime = arg2
- this.db[player].icon = icon
- this.db[player].channel = nil
+
+ -- Check if SuperWoW already set the cast data (with correct haste-adjusted casttime)
+ -- If so, only update icon if needed, don't overwrite casttime
+ local superWowAlreadySet = this.db[player].cast == arg1 and this.db[player].casttime and this.db[player].casttime > 0
+
+ if superWowAlreadySet then
+ -- SuperWoW already set correct casttime, only update icon if better
+ if icon and not this.db[player].icon then
+ this.db[player].icon = icon
+ end
+ else
+ -- No SuperWoW data, use SPELLCAST_START data
+ this.db[player].cast = arg1
+ this.db[player].rank = lastrank
+ this.db[player].start = GetTime()
+ this.db[player].casttime = arg2
+ this.db[player].icon = icon
+ this.db[player].channel = nil
+ end
+
if not L["spells"][arg1] or not L["spells"][arg1].icon or not L["spells"][arg1].t then
L["spells"][arg1] = L["spells"][arg1] or { }
L["spells"][arg1].icon = L["spells"][arg1].icon or icon
@@ -214,7 +299,9 @@ libcast:SetScript("OnEvent", function()
end
elseif event == "SPELLCAST_DELAYED" then
if this.db[player].cast then
- this.db[player].start = this.db[player].start + arg1/1000
+ -- Pushback: increase casttime instead of shifting start
+ -- arg1 is the delay amount in milliseconds
+ this.db[player].casttime = this.db[player].casttime + arg1
end
elseif event == "SPELLCAST_CHANNEL_START" then
-- add cast action to the database
@@ -224,6 +311,7 @@ libcast:SetScript("OnEvent", function()
this.db[player].casttime = arg1
this.db[player].icon = L["spells"][arg2] and L["spells"][arg2].icon and string.format("%s%s", "Interface\\Icons\\", L["spells"][arg2].icon) or lastcasttex
this.db[player].channel = true
+
lastcasttex, lastrank = nil, nil
elseif event == "SPELLCAST_CHANNEL_STOP" then
if this.db[player] and this.db[player].channel then
diff --git a/libs/libpredict.lua b/libs/libpredict.lua
index 77701f0b..83698369 100644
--- a/libs/libpredict.lua
+++ b/libs/libpredict.lua
@@ -9,10 +9,9 @@ setfenv(1, pfUI:GetEnvironment())
-- UnitGetIncomingHeals(unit)
-- UnitHasIncomingResurrection(unit)
--
--- The library is able to receive and send compatible messages to HealComm (vanilla)
--- and HealComm (tbc) including the ressurections of both versions. It has an option
--- to disable the sending of those messages in case one of the mentioned libraries
--- is already active.
+-- The library is able to receive and send compatible messages to HealComm
+-- including resurrections. It has an option to disable the sending of those
+-- messages in case HealComm is already active.
-- return instantly when another libpredict is already active
if pfUI.api.libpredict then return end
@@ -457,15 +456,6 @@ libpredict.sender:SetScript("OnUpdate", function()
end
end)
--- tbc
-libpredict.sender:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
-libpredict.sender:RegisterEvent("UNIT_SPELLCAST_START")
-libpredict.sender:RegisterEvent("UNIT_SPELLCAST_STOP")
-libpredict.sender:RegisterEvent("UNIT_SPELLCAST_FAILED")
-libpredict.sender:RegisterEvent("UNIT_SPELLCAST_INTERRUPTED")
-libpredict.sender:RegisterEvent("UNIT_SPELLCAST_SENT")
-
--- vanilla
libpredict.sender:RegisterEvent("CHAT_MSG_SPELL_SELF_BUFF")
libpredict.sender:RegisterEvent("SPELLCAST_START")
libpredict.sender:RegisterEvent("SPELLCAST_STOP")
@@ -502,24 +492,9 @@ libpredict.sender:SetScript("OnEvent", function()
if spell == spell_queue[1] then UpdateCache(spell_queue[2], heal, true) end
return
end
- elseif event == "COMBAT_LOG_EVENT_UNFILTERED" and arg2 == "SPELL_HEAL" and arg4 == player then -- tbc
- local spell, heal, crit = arg10, arg12, arg13
- if spell and heal and crit then
- if spell == spell_queue[1] then UpdateCache(spell_queue[2], heal, true) end
- elseif spell and heal then
- if spell == spell_queue[1] then UpdateCache(spell_queue[2], heal) end
- end
- elseif event == "UNIT_SPELLCAST_SENT" and arg4 then -- fix tbc mouseover macros
- senttarget = arg4
- elseif strfind(event, "SPELLCAST_START", 1) then
+ elseif event == "SPELLCAST_START" then
local spell, time = arg1, arg2
- if strfind(event, "UNIT_", 1) then -- tbc
- if arg1 ~= "player" then return end
- local spellname, _, _, _, starttime, endtime = UnitCastingInfo("player")
- spell, time = spellname, endtime - starttime
- end
-
if spell_queue[1] == spell and cache[spell_queue[2]] then
local sender = player
local target = senttarget or spell_queue[3]
@@ -540,22 +515,14 @@ libpredict.sender:SetScript("OnEvent", function()
for i=1,4 do
if CheckInteractDistance("party"..i, 4) then
libpredict:Heal(player, UnitName("party"..i), amount, casttime)
- if pfUI.client < 20000 then -- vanilla
- libpredict.sender:SendHealCommMsg("Heal/" .. UnitName("party"..i) .. "/" .. amount .. "/" .. casttime .. "/")
- else -- tbc
- libpredict.sender:SendHealCommMsg(string.format("002%05d%s", math.min(amount, 99999), UnitName("party"..i)))
- end
+ libpredict.sender:SendHealCommMsg("Heal/" .. UnitName("party"..i) .. "/" .. amount .. "/" .. casttime .. "/")
libpredict.sender.healing = true
end
end
end
libpredict:Heal(player, target, amount, casttime)
- if pfUI.client < 20000 then -- vanilla
- libpredict.sender:SendHealCommMsg("Heal/" .. target .. "/" .. amount .. "/" .. casttime .. "/")
- else -- tbc
- libpredict.sender:SendHealCommMsg(string.format("002%05d%s", math.min(amount, 99999), target))
- end
+ libpredict.sender:SendHealCommMsg("Heal/" .. target .. "/" .. amount .. "/" .. casttime .. "/")
libpredict.sender.healing = true
elseif spell_queue[1] == spell and L["resurrections"][spell] then
@@ -565,15 +532,10 @@ libpredict.sender:SetScript("OnEvent", function()
libpredict.sender:SendResCommMsg("RES " .. target)
libpredict.sender.resurrecting = true
end
- elseif strfind(event, "SPELLCAST_FAILED", 1) or strfind(event, "SPELLCAST_INTERRUPTED", 1) then
- if strfind(event, "UNIT_", 1) and arg1 ~= "player" then return end
+ elseif event == "SPELLCAST_FAILED" or event == "SPELLCAST_INTERRUPTED" then
if libpredict.sender.healing then
libpredict:HealStop(player)
- if pfUI.client < 20000 then -- vanilla
- libpredict.sender:SendHealCommMsg("HealStop")
- else -- tbc
- libpredict.sender:SendHealCommMsg("001F")
- end
+ libpredict.sender:SendHealCommMsg("HealStop")
libpredict.sender.healing = nil
elseif libpredict.sender.resurrecting then
local target = senttarget or spell_queue[3]
@@ -590,21 +552,16 @@ libpredict.sender:SetScript("OnEvent", function()
libpredict:HealDelay(player, arg1)
libpredict.sender:SendHealCommMsg("Healdelay/" .. arg1 .. "/")
end
- elseif strfind(event, "SPELLCAST_STOP", 1) then
- if strfind(event, "UNIT_", 1) and arg1 ~= "player" then return end
+ elseif event == "SPELLCAST_STOP" then
libpredict:HealStop(player)
- if pfUI.client < 20000 then -- vanilla
- if spell_queue[1] == REJUVENATION then
- libpredict:Hot(player, spell_queue[3], "Reju", rejuvDuration)
- libpredict.sender:SendHealCommMsg("Reju/"..spell_queue[3].."/"..rejuvDuration.."/")
- elseif spell_queue[1] == RENEW then
- libpredict:Hot(player, spell_queue[3], "Renew", renewDuration)
- libpredict.sender:SendHealCommMsg("Renew/"..spell_queue[3].."/"..renewDuration.."/")
- elseif spell_queue[1] == REGROWTH then
- this.regrowth_timer = GetTime() + 0.1
- end
- else -- tbc
- --todo
+ if spell_queue[1] == REJUVENATION then
+ libpredict:Hot(player, spell_queue[3], "Reju", rejuvDuration)
+ libpredict.sender:SendHealCommMsg("Reju/"..spell_queue[3].."/"..rejuvDuration.."/")
+ elseif spell_queue[1] == RENEW then
+ libpredict:Hot(player, spell_queue[3], "Renew", renewDuration)
+ libpredict.sender:SendHealCommMsg("Renew/"..spell_queue[3].."/"..renewDuration.."/")
+ elseif spell_queue[1] == REGROWTH then
+ this.regrowth_timer = GetTime() + 0.1
end
end
end)
diff --git a/libs/librange.lua b/libs/librange.lua
index c6e9c1a2..05c06743 100644
--- a/libs/librange.lua
+++ b/libs/librange.lua
@@ -39,10 +39,10 @@ local spells = {
},
}
--- use native IsSpellInRange checker for tbc and skip
--- the whole targeting approach that is required for vanilla
-if pfUI.expansion == "tbc" then
- local spell
+-- Use Nampower's IsSpellInRange if available (vanilla only)
+-- This provides more accurate range checking without needing to find spell slots
+local nampower_spell
+if GetNampowerVersion then
librange:RegisterEvent("LEARNED_SPELL_IN_TAB")
librange:RegisterEvent("PLAYER_ENTERING_WORLD")
librange:SetScript("OnEvent", function()
@@ -53,12 +53,14 @@ if pfUI.expansion == "tbc" then
local _, _, offset, num = GetSpellTabInfo(i)
for id = offset + 1, offset + num do
local name, rank = GetSpellName(id, BOOKTYPE_SPELL)
- local texture = GetSpellTexture(name)
+ local texture = GetSpellTexture(id, BOOKTYPE_SPELL)
- for _, tex in pairs(spells[class]) do
- if tex == texture then
- spell = name
- return
+ if texture then
+ for _, tex in pairs(spells[class]) do
+ if tex == texture then
+ nampower_spell = name
+ return
+ end
end
end
end
@@ -66,8 +68,12 @@ if pfUI.expansion == "tbc" then
end)
function librange:UnitInSpellRange(unit)
- if not spell then return nil end
- return IsSpellInRange(spell, unit) == 1 and true or nil
+ if not nampower_spell then return nil end
+ -- Nampower's IsSpellInRange returns 1 if in range, 0 if not, -1 if invalid
+ local result = IsSpellInRange(nampower_spell, unit)
+ if result == 1 then return 1
+ elseif result == 0 then return nil
+ else return nil end
end
-- add librange to pfUI API
@@ -161,7 +167,17 @@ librange:SetScript("OnUpdate", function()
if this.id <= numunits and librange.slot then
local unit = units[this.id]
if not UnitIsUnit("target", unit) then
- -- try to read distance via superwow first
+ -- Try UnitXP_SP3 first (most accurate distance measurement)
+ local unitxp_success, unitxp_distance = pcall(function()
+ return UnitXP("distanceBetween", "player", unit)
+ end)
+ if unitxp_success and unitxp_distance then
+ unitdata[unit] = unitxp_distance < 45 and 1 or 0
+ this.id = this.id + 1
+ return
+ end
+
+ -- try to read distance via superwow second
if superwow_active then
local x1, y1, z1 = UnitPosition("player")
local x2, y2, z2 = UnitPosition(unit)
From 9e434b515bc01770c0b0cf609f2f3dfb22da7d66 Mon Sep 17 00:00:00 2001
From: Meow <30401521+me0wg4ming@users.noreply.github.com>
Date: Sat, 3 Jan 2026 12:33:39 +0100
Subject: [PATCH 09/40] performance update
performance update
---
api/api.lua | 76 ++++++++++++++++++++++++++++++++++++++++++++++
api/config.lua | 13 ++++++++
api/unitframes.lua | 76 ++++++++++++----------------------------------
3 files changed, 109 insertions(+), 56 deletions(-)
diff --git a/api/api.lua b/api/api.lua
index e4a94402..dfa73621 100644
--- a/api/api.lua
+++ b/api/api.lua
@@ -7,6 +7,82 @@ setfenv(1, pfUI:GetEnvironment())
gfind = string.gmatch or string.gfind
mod = math.mod or mod
+-- [ DLL Detection Helpers ]
+-- Detects presence of various DLL extensions for enhanced functionality
+
+-- [ HasSuperWoW ]
+-- Returns true if SuperWoW DLL is active
+-- SuperWoW provides: UNIT_CASTEVENT, UnitPosition, SetMouseoverUnit, SpellInfo, etc.
+function pfUI.api.HasSuperWoW()
+ return SUPERWOW_VERSION or (SetAutoloot and SpellInfo)
+end
+
+-- [ HasUnitXP ]
+-- Returns true if UnitXP_SP3 DLL is active
+-- UnitXP provides: distance, line of sight, behind detection, targeting helpers
+function pfUI.api.HasUnitXP()
+ local success = pcall(UnitXP, "nop", "nop")
+ return success
+end
+
+-- [ HasNampower ]
+-- Returns true if Nampower DLL is active
+-- Nampower provides: spell queuing, GetCastInfo, GetSpellIdCooldown, IsSpellInRange, etc.
+function pfUI.api.HasNampower()
+ return GetNampowerVersion and true or false
+end
+
+-- [ GetUnitDistance ]
+-- Returns distance to unit using best available method
+-- 'unit1' [string] first unit (default: "player")
+-- 'unit2' [string] second unit
+-- returns: [number] distance in yards, or nil if unavailable
+function pfUI.api.GetUnitDistance(unit1, unit2)
+ if not unit2 then
+ unit2 = unit1
+ unit1 = "player"
+ end
+
+ if not UnitExists(unit2) then return nil end
+
+ -- Try UnitXP first (most accurate)
+ if pfUI.api.HasUnitXP() then
+ local success, distance = pcall(UnitXP, "distanceBetween", unit1, unit2)
+ if success and distance then return distance end
+ end
+
+ -- Try SuperWoW UnitPosition
+ if pfUI.api.HasSuperWoW() and UnitPosition then
+ local x1, y1, z1 = UnitPosition(unit1)
+ local x2, y2, z2 = UnitPosition(unit2)
+ if x1 and y1 and z1 and x2 and y2 and z2 then
+ return ((x2 - x1)^2 + (y2 - y1)^2 + (z2 - z1)^2)^0.5
+ end
+ end
+
+ return nil
+end
+
+-- [ UnitInLineOfSight ]
+-- Returns true if unit1 has line of sight to unit2
+-- Requires UnitXP_SP3
+function pfUI.api.UnitInLineOfSight(unit1, unit2)
+ if not pfUI.api.HasUnitXP() then return nil end
+ local success, inSight = pcall(UnitXP, "inSight", unit1, unit2)
+ if success then return inSight end
+ return nil
+end
+
+-- [ UnitIsBehind ]
+-- Returns true if unit1 is behind unit2
+-- Requires UnitXP_SP3
+function pfUI.api.UnitIsBehind(unit1, unit2)
+ if not pfUI.api.HasUnitXP() then return nil end
+ local success, behind = pcall(UnitXP, "behind", unit1, unit2)
+ if success then return behind end
+ return nil
+end
+
-- [ strsplit ]
-- Splits a string using a delimiter.
-- 'delimiter' [string] characters that will be interpreted as delimiter
diff --git a/api/config.lua b/api/config.lua
index 7dd2114c..b7e3ceee 100644
--- a/api/config.lua
+++ b/api/config.lua
@@ -221,6 +221,18 @@ function pfUI:LoadConfig()
pfUI:UpdateConfig("unitframes", nil, "druidmanabar", "1")
pfUI:UpdateConfig("unitframes", nil, "druidmanaheight", "2")
pfUI:UpdateConfig("unitframes", nil, "druidmanatext", "0")
+ pfUI:UpdateConfig("unitframes", nil, "spellqueue", "1")
+ pfUI:UpdateConfig("unitframes", nil, "spellqueuesize", "24")
+ pfUI:UpdateConfig("unitframes", nil, "gcd_indicator", "0")
+ pfUI:UpdateConfig("unitframes", nil, "gcd_size", "4")
+ pfUI:UpdateConfig("unitframes", nil, "nampower_buffs", "1")
+ pfUI:UpdateConfig("unitframes", nil, "reactive_indicator", "0")
+ pfUI:UpdateConfig("unitframes", nil, "reactive_size", "28")
+ pfUI:UpdateConfig("unitframes", nil, "damage_tracking", "0")
+ pfUI:UpdateConfig("unitframes", nil, "los_indicator", "0")
+ pfUI:UpdateConfig("unitframes", nil, "behind_indicator", "0")
+ pfUI:UpdateConfig("unitframes", nil, "unitxp_notify", "0")
+ pfUI:UpdateConfig("unitframes", nil, "track_group", "0")
pfUI:UpdateConfig("unitframes", nil, "rangechecki", "4")
pfUI:UpdateConfig("unitframes", nil, "combowidth", "6")
pfUI:UpdateConfig("unitframes", nil, "comboheight", "6")
@@ -713,6 +725,7 @@ function pfUI:LoadConfig()
pfUI:UpdateConfig("chat", "text", "playerlinks", "1")
pfUI:UpdateConfig("chat", "text", "detecturl", "1")
pfUI:UpdateConfig("chat", "text", "classcolor", "1")
+ pfUI:UpdateConfig("chat", "text", "playerlevel", "1")
pfUI:UpdateConfig("chat", "text", "whosearchunknown", "0")
pfUI:UpdateConfig("chat", "left", "width", "380")
pfUI:UpdateConfig("chat", "left", "height", "180")
diff --git a/api/unitframes.lua b/api/unitframes.lua
index 36e8eaed..9b590ba3 100644
--- a/api/unitframes.lua
+++ b/api/unitframes.lua
@@ -420,21 +420,7 @@ function pfUI.uf:UpdateVisibility()
self.visible = nil
end
- -- tbc visibility
- if pfUI.client > 11200 then
- self:SetAttribute("unit", unitstr)
-
- -- update visibility condition on change
- if self.visibilitycondition ~= visibility then
- RegisterStateDriver(self, 'visibility', visibility)
- self.visibilitycondition = visibility
- self.visible = true
- end
-
- return
- end
-
- -- vanilla visibility
+ -- visibility
if self.unitname and self.unitname ~= "focus" and self.unitname ~= "focustarget" then
self:Show()
elseif visibility == "hide" then
@@ -866,8 +852,6 @@ function pfUI.uf:UpdateConfig()
if f:GetName() == "pfPlayer" then
f.buffs[i]:SetScript("OnUpdate", BuffOnUpdate)
- elseif f:GetName() == "pfTarget" and pfUI.expansion == "tbc" then
- f.buffs[i]:SetScript("OnUpdate", TargetBuffOnUpdate)
end
f.buffs[i]:SetScript("OnEnter", BuffOnEnter)
@@ -1209,6 +1193,18 @@ end
function pfUI.uf.OnEnter()
if not this.label then return end
+
+ -- SuperWoW: Set native mouseover unit for macro/addon compatibility
+ if SetMouseoverUnit then
+ local unitstr = this.label .. this.id
+ -- For GUID-based frames (focus), use the GUID directly
+ if this.label and string.find(this.label, "^0x") then
+ SetMouseoverUnit(this.label)
+ elseif UnitExists(unitstr) then
+ SetMouseoverUnit(unitstr)
+ end
+ end
+
if this.config.showtooltip == "0" then return end
GameTooltip_SetDefaultAnchor(GameTooltip, this)
GameTooltip:SetUnit(this.label .. this.id)
@@ -1216,6 +1212,11 @@ function pfUI.uf.OnEnter()
end
function pfUI.uf.OnLeave()
+ -- SuperWoW: Clear native mouseover unit
+ if SetMouseoverUnit then
+ SetMouseoverUnit()
+ end
+
GameTooltip:FadeOut()
end
@@ -2139,33 +2140,8 @@ function pfUI.uf:EnableClickCast()
local bconf = bid == 1 and "" or bid
if pfUI_config.unitframes["clickcast"..bconf..mconf] ~= "" then
-- prepare click casting
- if pfUI.client > 11200 then
- -- set attributes for tbc+
- local prefix = modifier == "" and "" or modifier .. "-"
-
- -- check for "/" in the beginning of the string, to detect macros
- if string.find(pfUI_config.unitframes["clickcast"..bconf..mconf], "^%/(.+)") then
- self:SetAttribute(prefix.."type"..bid, "macro")
- self:SetAttribute(prefix.."macrotext"..bid, pfUI_config.unitframes["clickcast"..bconf..mconf])
- self:SetAttribute(prefix.."spell"..bid, nil)
- elseif string.find(pfUI_config.unitframes["clickcast"..bconf..mconf], "^target") then
- self:SetAttribute(prefix.."type"..bid, "target")
- self:SetAttribute(prefix.."macrotext"..bid, nil)
- self:SetAttribute(prefix.."spell"..bid, nil)
- elseif string.find(pfUI_config.unitframes["clickcast"..bconf..mconf], "^menu") then
- self:SetAttribute(prefix.."type"..bid, "showmenu")
- self:SetAttribute(prefix.."macrotext"..bid, nil)
- self:SetAttribute(prefix.."spell"..bid, nil)
- else
- self:SetAttribute(prefix.."type"..bid, "spell")
- self:SetAttribute(prefix.."spell"..bid, pfUI_config.unitframes["clickcast"..bconf..mconf])
- self:SetAttribute(prefix.."macro"..bid, nil)
- end
- else
- -- fill clickaction table for vanillla
- self.clickactions = self.clickactions or {}
- self.clickactions[modifier..button] = pfUI_config.unitframes["clickcast"..bconf..mconf]
- end
+ self.clickactions = self.clickactions or {}
+ self.clickactions[modifier..button] = pfUI_config.unitframes["clickcast"..bconf..mconf]
end
end
end
@@ -2427,8 +2403,6 @@ function pfUI.uf:SetupBuffIndicators(config)
if myclass == "WARRIOR" then
-- Battle Shout
table.insert(indicators, "interface\\icons\\ability_warrior_battleshout")
- -- Commanding Shout (TBC)
- table.insert(indicators, "interface\\icons\\ability_warrior_rallyingcry")
end
if myclass == "MAGE" then
@@ -2447,14 +2421,6 @@ function pfUI.uf:SetupBuffIndicators(config)
-- Aspect of the Pack
table.insert(indicators, "interface\\icons\\ability_mount_whitetiger")
-
- -- Misdirection (TBC)
- table.insert(indicators, "interface\\icons\\ability_hunter_misdirection")
- end
-
- if myclass == "SHAMAN" then
- -- Earth Shield (TBC)
- table.insert(indicators, "interface\\icons\\spell_nature_skinofearth")
end
end
@@ -2483,8 +2449,6 @@ function pfUI.uf:SetupBuffIndicators(config)
table.insert(indicators, "interface\\icons\\spell_holy_renew")
-- Power Word: Shield
table.insert(indicators, "interface\\icons\\spell_holy_powerwordshield")
- -- Prayer of Mending (TBC)
- table.insert(indicators, "interface\\icons\\spell_holy_prayerofmendingtga")
end
if myclass == "DRUID" or config.all_hots == "1" then
From 62a53b3c4330e5c8af77d7524df7213b13a3f9db Mon Sep 17 00:00:00 2001
From: Meow <30401521+me0wg4ming@users.noreply.github.com>
Date: Sat, 3 Jan 2026 12:34:15 +0100
Subject: [PATCH 10/40] Add files via upload
---
README.md | 145 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
pfUI.lua | 36 +++-----------
2 files changed, 152 insertions(+), 29 deletions(-)
diff --git a/README.md b/README.md
index 0c9fbe83..f65eb3d7 100644
--- a/README.md
+++ b/README.md
@@ -1 +1,146 @@
pfUI performance updates, use on own risk.
+
+## DLL Integrations
+
+pfUI includes optional integration modules for client DLLs that provide enhanced functionality beyond what the standard WoW 1.12 client supports. These features are only enabled when the corresponding DLL is installed.
+
+---
+
+### SuperWoW
+
+**Repository:** https://github.com/balakethelock/SuperWoW
+
+SuperWoW provides GUID-based unit tracking, spell information APIs, and various client enhancements.
+
+#### Features
+
+- **GUID-Based Focus Frame** - Focus frame uses actual unit GUIDs instead of name-based emulation
+- **Native Mouseover Casting** - `/pfcast` supports true mouseover targeting via `CastSpellByName(spell, unit)`
+- **Druid Mana Bar** - Shows mana while in feral forms (requires `unitframes.druidmanabar` config)
+- **Enhanced Cast Bars** - Uses `UNIT_CASTEVENT` for accurate cast/channel tracking with spell IDs
+- **Enhanced Debuff Tracking** - Accurate debuff application via `UNIT_CASTEVENT` with caster info
+- **Group Minimap Tracking** - Track party/raid members on minimap via `TrackUnit()` API
+- **Raid Marker Targeting** - Target units by raid marker (`mark1` to `mark8`)
+- **Clickthrough Mode** - Click through corpses to loot underneath (`/clickthrough` or `/ct`)
+- **Config Import/Export** - Save and load pfUI configs via `/pfexport` and `/pfimport`
+- **Local Raid Markers** - Set raid markers visible only to yourself
+- **Enchanting Link Fixes** - Converts enchant links for compatibility with non-SuperWoW clients
+
+#### API Functions
+
+| Function | Description |
+|----------|-------------|
+| `pfUI.api.GetMarkedUnit(index)` | Get unit ID for raid marker 1-8 |
+| `pfUI.api.TargetMark(index)` | Target unit with raid marker |
+| `pfUI.api.GetUnitOwner(unit)` | Get owner of pet/totem |
+| `pfUI.api.GetSpellInfo(spellId)` | Get spell name, rank, texture, range |
+| `pfUI.api.SetClickthrough(enabled)` | Enable/disable clickthrough |
+| `pfUI.api.ToggleClickthrough()` | Toggle clickthrough mode |
+| `pfUI.api.SetAutoloot(enabled)` | Enable/disable autoloot |
+| `pfUI.api.ExportConfig(filename)` | Export config to file |
+| `pfUI.api.ImportConfig(filename)` | Import config from file |
+| `pfUI.api.GetPlayerBuffSpellId(index)` | Get spell ID for player buff |
+| `pfUI.api.LogToCombatLog(text)` | Add text to combat log |
+| `pfUI.api.SetLocalRaidTarget(unit, index)` | Set local-only raid marker |
+| `pfUI.api.GetItemCharges(bag, slot)` | Get item charges (returns positive) |
+| `pfUI.api.GetUnitWeaponEnchants(unit)` | Get weapon enchant info |
+
+---
+
+### Nampower
+
+**Repository:** https://gitea.com/avitasia/nampower
+
+Nampower provides spell queuing, precise cooldown tracking, and detailed aura/buff information.
+
+#### Features
+
+- **Spell Queue Indicator** - Shows queued spell icon near castbar (requires `unitframes.spellqueue` config)
+- **Reactive Spell Indicator** - Highlights when Overpower, Revenge, Execute, Riposte, etc. are usable (requires `unitframes.reactive_indicator`)
+- **Enhanced Debuff Tracking** - GUID-based debuff tracking via `DEBUFF_ADDED/REMOVED` events
+- **Enhanced Buff Tracking** - GUID-based buff tracking via `BUFF_ADDED/REMOVED` events (requires `unitframes.nampower_buffs`)
+- **Swing Timer** - Track main-hand and off-hand auto-attack timers
+- **Disenchant All** - `/disenchantall` or `/dea` to disenchant eligible items
+
+#### API Functions
+
+| Function | Description |
+|----------|-------------|
+| `pfUI.api.GetUnitAuras(unit)` | Get all buffs/debuffs with spell IDs via `GetUnitField` |
+| `pfUI.api.UnitHasAura(unit, spellId)` | Check if unit has specific aura |
+| `pfUI.api.GetUnitResistances(unit)` | Get unit's resistances (armor, fire, frost, etc.) |
+| `pfUI.api.GetPreciseCooldown(spellId)` | Get precise cooldown info (remaining ms, GCD state) |
+| `pfUI.api.GetPreciseItemCooldown(itemId)` | Get precise item cooldown |
+| `pfUI.api.GetEquippedTrinkets()` | Get equipped trinket info |
+| `pfUI.api.GetTrinketCooldown(slot)` | Get trinket cooldown |
+| `pfUI.api.UseTrinket(slot, target)` | Use trinket |
+| `pfUI.api.GetNampowerItemStats(itemId)` | Get item stats |
+| `pfUI.api.GetNampowerItemLevel(itemId)` | Get item level |
+| `pfUI.api.GetSpellBonus(spellId, modType)` | Get spell modifiers (damage, crit, cost) |
+| `pfUI.api.GetSpellDamageBonus(spellId)` | Get spell damage bonus |
+| `pfUI.api.GetSpellCritBonus(spellId)` | Get spell crit bonus |
+| `pfUI.api.GetSpellCostReduction(spellId)` | Get spell cost reduction |
+| `pfUI.api.GetAllBagItems()` | Get all bag items |
+| `pfUI.api.FindItem(itemIdOrName)` | Find item in bags |
+| `pfUI.api.UseItem(itemIdOrName, target)` | Use item |
+| `pfUI.api.GetPlayerEquipment()` | Get player's equipped items |
+| `pfUI.api.GetTargetEquipment()` | Get target's equipped items |
+| `pfUI.api.GetMaxRankSpellId(spellName)` | Get spell ID for max rank |
+| `pfUI.api.GetSpellSlotInfo(spellName)` | Get spell slot/book info |
+| `pfUI.api.QueueLuaScript(script, priority)` | Queue Lua script for execution |
+| `pfUI.api.QueueSpell(spellName)` | Queue spell by name |
+| `pfUI.api.StopChannelNextTick()` | Stop channeling next tick |
+| `pfUI.api.GetSpellRecord(spellId)` | Get full spell database record |
+| `pfUI.api.GetSpellSchool(spellId)` | Get spell school (Fire, Frost, etc.) |
+| `pfUI.api.GetSwingTimers()` | Get auto-attack swing timers |
+| `pfUI.api.libdebuff_nampower(unit, id)` | Enhanced UnitDebuff with Nampower data |
+
+---
+
+### UnitXP_SP3
+
+**Repository:** https://github.com/allfoxwy/UnitXP_SP3
+
+UnitXP provides line-of-sight checks, positional information, precise distances, and OS-level notifications.
+
+#### Features
+
+- **Line of Sight Indicator** - Shows "NO LOS" text on target frame when target is obstructed (requires `unitframes.los_indicator`)
+- **Behind Indicator** - Shows "BEHIND" text on target frame when positioned behind target (requires `unitframes.behind_indicator`)
+- **OS Notifications** - Flashes taskbar and plays system sound on whispers, ready checks, BG queue pops (requires `unitframes.unitxp_notify`)
+- **Precise Distance** - Exact yard distance between units
+- **Smart Targeting** - Target nearest enemy, highest HP, cycle through enemies
+
+#### API Functions
+
+| Function | Description |
+|----------|-------------|
+| `pfUI.api.GetPreciseDistance(unit1, unit2)` | Get exact distance in yards |
+| `pfUI.api.IsInMeleeRange(unit)` | Check if unit is in melee range |
+| `pfUI.api.GetAoEDistance(unit1, unit2)` | Get distance for AoE calculations |
+| `pfUI.api.TargetNearestEnemy()` | Target nearest hostile unit |
+| `pfUI.api.TargetHighestHP()` | Target enemy with most HP |
+| `pfUI.api.TargetNextEnemy()` | Cycle to next enemy |
+| `pfUI.api.TargetPreviousEnemy()` | Cycle to previous enemy |
+| `pfUI.api.TargetNextMarked(order)` | Target next marked enemy in order |
+| `pfUI.api.UnitInLineOfSight(unit1, unit2)` | Check line of sight between units |
+| `pfUI.api.UnitIsBehind(unit1, unit2)` | Check if unit1 is behind unit2 |
+
+---
+
+### Configuration Options
+
+These DLL features can be enabled/disabled via `/pfui` settings under Unit Frames:
+
+| Setting | DLL | Description |
+|---------|-----|-------------|
+| `unitframes.druidmanabar` | SuperWoW | Show mana bar while shapeshifted |
+| `unitframes.track_group` | SuperWoW | Track group members on minimap |
+| `unitframes.spellqueue` | Nampower | Show spell queue indicator |
+| `unitframes.spellqueuesize` | Nampower | Spell queue icon size |
+| `unitframes.reactive_indicator` | Nampower | Show reactive ability procs |
+| `unitframes.reactive_size` | Nampower | Reactive indicator icon size |
+| `unitframes.nampower_buffs` | Nampower | Enhanced buff tracking |
+| `unitframes.los_indicator` | UnitXP | Show line of sight indicator |
+| `unitframes.behind_indicator` | UnitXP | Show behind indicator |
+| `unitframes.unitxp_notify` | UnitXP | Enable OS notifications |
diff --git a/pfUI.lua b/pfUI.lua
index 606919f8..b8229436 100644
--- a/pfUI.lua
+++ b/pfUI.lua
@@ -77,17 +77,9 @@ end})
local _, _, _, client = GetBuildInfo()
client = client or 11200
--- detect client expansion
-if client >= 20000 and client <= 20400 then
- pfUI.expansion = "tbc"
- pfUI.client = client
-elseif client >= 30000 and client <= 30300 then
- pfUI.expansion = "wotlk"
- pfUI.client = client
-else
- pfUI.expansion = "vanilla"
- pfUI.client = client
-end
+-- set expansion to vanilla
+pfUI.expansion = "vanilla"
+pfUI.client = client
-- setup pfUI namespace
setmetatable(pfUI.env, {__index = getfenv(0)})
@@ -119,34 +111,20 @@ function pfUI:UpdateFonts()
-- load font configuration
local default, tooltip, unit, unit_name, combat
- if pfUI_config.global.force_region == "1" and GetLocale() == "zhCN" and pfUI.expansion == "vanilla" then
+ if pfUI_config.global.force_region == "1" and GetLocale() == "zhCN" then
-- force locale compatible fonts (zhCN 1.12)
default = "Fonts\\FZXHLJW.TTF"
tooltip = "Fonts\\FZXHLJW.TTF"
combat = "Fonts\\FZXHLJW.TTF"
unit = "Fonts\\FZXHLJW.TTF"
unit_name = "Fonts\\FZXHLJW.TTF"
- elseif pfUI_config.global.force_region == "1" and GetLocale() == "zhCN" and pfUI.expansion == "tbc" then
- -- force locale compatible fonts (zhCN 2.4.3)
- default = "Fonts\\ZYHei.ttf"
- tooltip = "Fonts\\ZYHei.ttf"
- combat = "Fonts\\ZYKai_C.ttf"
- unit = "Fonts\\ZYKai_T.ttf"
- unit_name = "Fonts\\ZYHei.ttf"
- elseif pfUI_config.global.force_region == "1" and GetLocale() == "zhTW" and pfUI.expansion == "vanilla" then
+ elseif pfUI_config.global.force_region == "1" and GetLocale() == "zhTW" then
-- force locale compatible fonts (zhTW 1.12)
default = "Fonts\\FZXHLJW.ttf"
tooltip = "Fonts\\FZXHLJW.ttf"
combat = "Fonts\\FZXHLJW.ttf"
unit = "Fonts\\FZXHLJW.ttf"
unit_name = "Fonts\\FZXHLJW.ttf"
- elseif pfUI_config.global.force_region == "1" and GetLocale() == "zhTW" and pfUI.expansion == "tbc" then
- -- force locale compatible fonts (zhTW 2.4.3)
- default = "Fonts\\bHEI01B.ttf"
- tooltip = "Fonts\\bHEI01B.ttf"
- combat = "Fonts\\bHEI01B.ttf"
- unit = "Fonts\\bHEI01B.ttf"
- unit_name = "Fonts\\bHEI01B.ttf"
elseif pfUI_config.global.force_region == "1" and GetLocale() == "koKR" then
-- force locale compatible fonts (koKR)
default = "Fonts\\2002.TTF"
@@ -244,7 +222,7 @@ end
function pfUI:RegisterModule(name, a2, a3)
if pfUI.module[name] then return end
local hasv = type(a2) == "string"
- local func, version = hasv and a3 or a2, hasv and a2 or "vanilla:tbc:wotlk"
+ local func, version = hasv and a3 or a2, hasv and a2 or "vanilla"
-- check for client compatibility
if not strfind(version, pfUI.expansion) then return end
@@ -259,7 +237,7 @@ end
function pfUI:RegisterSkin(name, a2, a3)
if pfUI.skin[name] then return end
local hasv = type(a2) == "string"
- local func, version = hasv and a3 or a2, hasv and a2 or "vanilla:tbc:wotlk"
+ local func, version = hasv and a3 or a2, hasv and a2 or "vanilla"
-- check for client compatibility
if not strfind(version, pfUI.expansion) then return end
From f5d2f659992c5937586de0fab29f62db886dbb9a Mon Sep 17 00:00:00 2001
From: Meow <30401521+me0wg4ming@users.noreply.github.com>
Date: Sat, 3 Jan 2026 12:55:04 +0100
Subject: [PATCH 11/40] performance update
performance update
---
init/compat.xml | 1 -
init/modules.xml | 4 +-
init/skins.xml | 10 ---
pfUI-tbc.toc | 17 ----
skins/blizzard/auction.lua | 15 ++--
skins/blizzard/battlefield.lua | 2 +-
skins/blizzard/battlefield_minimap.lua | 2 +-
skins/blizzard/character.lua | 25 ++----
skins/blizzard/dressup.lua | 2 +-
skins/blizzard/friends.lua | 60 +-------------
skins/blizzard/game_menu.lua | 8 +-
skins/blizzard/gossipquest.lua | 2 +-
skins/blizzard/guild_registrar.lua | 2 +-
skins/blizzard/help.lua | 14 +---
skins/blizzard/inspect.lua | 105 -------------------------
skins/blizzard/itemtext.lua | 2 +-
skins/blizzard/keybindings.lua | 2 +-
skins/blizzard/macro.lua | 2 +-
skins/blizzard/mail.lua | 48 +----------
skins/blizzard/merchant.lua | 18 +----
skins/blizzard/miscellaneous.lua | 12 +--
skins/blizzard/options-sound.lua | 44 +++--------
skins/blizzard/options-video.lua | 48 +++--------
skins/blizzard/popup_dialogs.lua | 9 +--
skins/blizzard/professions.lua | 34 +-------
skins/blizzard/questlog.lua | 21 +----
skins/blizzard/readycheck.lua | 10 +--
skins/blizzard/spellbook.lua | 2 +-
skins/blizzard/stable.lua | 2 +-
skins/blizzard/tabard.lua | 2 +-
skins/blizzard/talents.lua | 12 +--
skins/blizzard/taxi.lua | 2 +-
skins/blizzard/tooltips.lua | 2 +-
skins/blizzard/trade.lua | 2 +-
skins/blizzard/trainer.lua | 2 +-
35 files changed, 77 insertions(+), 468 deletions(-)
delete mode 100644 pfUI-tbc.toc
diff --git a/init/compat.xml b/init/compat.xml
index 7d9f7b2d..173883ce 100644
--- a/init/compat.xml
+++ b/init/compat.xml
@@ -1,4 +1,3 @@
-
diff --git a/init/modules.xml b/init/modules.xml
index 9c17cf52..07f703ff 100644
--- a/init/modules.xml
+++ b/init/modules.xml
@@ -35,7 +35,6 @@
-
@@ -66,10 +65,11 @@
-
+
+
diff --git a/init/skins.xml b/init/skins.xml
index 010e2b96..088c2d55 100644
--- a/init/skins.xml
+++ b/init/skins.xml
@@ -26,7 +26,6 @@
-
@@ -34,13 +33,4 @@
-
-
-
-
-
-
-
-
-
diff --git a/pfUI-tbc.toc b/pfUI-tbc.toc
deleted file mode 100644
index 1686229a..00000000
--- a/pfUI-tbc.toc
+++ /dev/null
@@ -1,17 +0,0 @@
-## Interface: 20400
-## Title: |cff33ffccpf|cffffffffUI
-## Author: Shagu
-## Notes: A complete user interface replacement.
-## Notes-ruRU: Полная замена пользовательского интерфейса.
-## Version: 5.5.4
-## SavedVariables: pfUI_profiles, pfUI_addon_profiles, pfUI_cache
-## SavedVariablesPerCharacter: pfUI_config, pfUI_init, pfUI_playerDB
-
-pfUI.lua
-
-init\env.xml
-init\compat.xml
-init\api.xml
-init\libs.xml
-init\skins.xml
-init\modules.xml
diff --git a/skins/blizzard/auction.lua b/skins/blizzard/auction.lua
index 0cd64855..f94c3e3a 100644
--- a/skins/blizzard/auction.lua
+++ b/skins/blizzard/auction.lua
@@ -1,16 +1,11 @@
-pfUI:RegisterSkin("Auctionhouse", "vanilla:tbc", function ()
+pfUI:RegisterSkin("Auctionhouse", "vanilla", function ()
local rawborder, border = GetBorderSize()
local bpad = rawborder > 1 and border - GetPerfectPixel() or GetPerfectPixel()
HookAddonOrVariable("Blizzard_AuctionUI", function()
- -- Compatibility
- if BrowseResetButton then -- tbc
- SkinButton(BrowseResetButton)
- else -- vanilla
- SkinArrowButton(BidPrevPageButton, "left", 18)
- SkinArrowButton(BidNextPageButton, "right", 18)
- SkinArrowButton(AuctionsPrevPageButton, "left", 18)
- SkinArrowButton(AuctionsNextPageButton, "right", 18)
- end
+ SkinArrowButton(BidPrevPageButton, "left", 18)
+ SkinArrowButton(BidNextPageButton, "right", 18)
+ SkinArrowButton(AuctionsPrevPageButton, "left", 18)
+ SkinArrowButton(AuctionsNextPageButton, "right", 18)
hooksecurefunc("AuctionFrame_OnShow", function()
AuctionFrame:ClearAllPoints()
diff --git a/skins/blizzard/battlefield.lua b/skins/blizzard/battlefield.lua
index 7ff50008..f8dcb283 100644
--- a/skins/blizzard/battlefield.lua
+++ b/skins/blizzard/battlefield.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterSkin("Battlefield", "vanilla:tbc", function ()
+pfUI:RegisterSkin("Battlefield", "vanilla", function ()
local rawborder, border = GetBorderSize()
local bpad = rawborder > 1 and border - GetPerfectPixel() or GetPerfectPixel()
diff --git a/skins/blizzard/battlefield_minimap.lua b/skins/blizzard/battlefield_minimap.lua
index e0a21d5e..e2eb12b7 100644
--- a/skins/blizzard/battlefield_minimap.lua
+++ b/skins/blizzard/battlefield_minimap.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterSkin("Battlefield Minimap", "vanilla:tbc", function ()
+pfUI:RegisterSkin("Battlefield Minimap", "vanilla", function ()
local rawborder, border = GetBorderSize()
HookAddonOrVariable("Blizzard_BattlefieldMinimap", function()
diff --git a/skins/blizzard/character.lua b/skins/blizzard/character.lua
index 88d4775f..fea07800 100644
--- a/skins/blizzard/character.lua
+++ b/skins/blizzard/character.lua
@@ -1,26 +1,13 @@
-pfUI:RegisterSkin("Character", "vanilla:tbc", function ()
+pfUI:RegisterSkin("Character", "vanilla", function ()
local rawborder, border = GetBorderSize()
local bpad = rawborder > 1 and border - GetPerfectPixel() or GetPerfectPixel()
- -- Compatibility
- if PlayerTitleDropDown then -- tbc, wotlk
- -- Character Tab
- SkinDropDown(PlayerTitleDropDown)
- PlayerTitleDropDown:SetPoint("TOP", CharacterLevelText, "BOTTOM", 0, -2)
- PlayerTitleDropDownText:SetPoint("LEFT", PlayerTitleDropDown.backdrop, "LEFT", 6, 2)
- SkinDropDown(PlayerStatFrameLeftDropDown)
- SkinDropDown(PlayerStatFrameRightDropDown)
+ -- Honor Tab
+ StripTextures(HonorFrame)
- -- Honor Tab
- StripTextures(PVPFrame)
- else -- vanilla
- -- Honor Tab
- StripTextures(HonorFrame)
-
- HonorFrameProgressBar:SetStatusBarTexture(pfUI.media["img:bar"])
- CreateBackdrop(HonorFrameProgressBar)
- HonorFrameProgressBar:SetHeight(24)
- end
+ HonorFrameProgressBar:SetStatusBarTexture(pfUI.media["img:bar"])
+ CreateBackdrop(HonorFrameProgressBar)
+ HonorFrameProgressBar:SetHeight(24)
local magicResTextureCords = {
{0.21875, 0.78125, 0.25, 0.3203125},
diff --git a/skins/blizzard/dressup.lua b/skins/blizzard/dressup.lua
index d618a36c..cf5c0ffe 100644
--- a/skins/blizzard/dressup.lua
+++ b/skins/blizzard/dressup.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterSkin("Dress Up Frame", "vanilla:tbc", function ()
+pfUI:RegisterSkin("Dress Up Frame", "vanilla", function ()
local rawborder, border = GetBorderSize()
local bpad = rawborder > 1 and border - GetPerfectPixel() or GetPerfectPixel()
diff --git a/skins/blizzard/friends.lua b/skins/blizzard/friends.lua
index fe6080e6..26b21ce3 100644
--- a/skins/blizzard/friends.lua
+++ b/skins/blizzard/friends.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterSkin("Friends", "vanilla:tbc", function ()
+pfUI:RegisterSkin("Friends", "vanilla", function ()
local rawborder, border = GetBorderSize()
local bpad = rawborder > 1 and border - GetPerfectPixel() or GetPerfectPixel()
local maxtab = pfUI.expansion == "vanilla" and 4 or 5
@@ -336,24 +336,6 @@ pfUI:RegisterSkin("Friends", "vanilla:tbc", function ()
GuildInfoCancelButton:ClearAllPoints()
GuildInfoCancelButton:SetPoint("BOTTOMRIGHT", GuildInfoFrame, "BOTTOMRIGHT", -10, 8)
- if GuildInfoGuildEventButton then -- log button (tbc+)
- SkinButton(GuildInfoGuildEventButton)
- GuildInfoGuildEventButton:ClearAllPoints()
- GuildInfoGuildEventButton:SetPoint("BOTTOM", GuildInfoFrame, "BOTTOM", 0, 8)
- end
-
- if GuildEventLogFrame then -- guild log frame (tbc+)
- StripTextures(GuildEventFrame)
- CreateBackdrop(GuildEventFrame, nil, true, .75)
- StripTextures(GuildEventLogFrame)
- CreateBackdrop(GuildEventLogFrame, nil, true, .75)
- StripTextures(GuildEventLogScrollFrame)
- SkinScrollbar(GuildEventLogScrollFrameScrollBar)
- SkinCloseButton(GuildEventLogCloseButton)
- GuildEventLogCancelButton:SetPoint("BOTTOMRIGHT", -9, 8)
- SkinButton(GuildEventLogCancelButton)
- end
-
-- guild control
StripTextures(GuildControlPopupFrame)
CreateBackdrop(GuildControlPopupFrame, nil, true, .75)
@@ -392,46 +374,6 @@ pfUI:RegisterSkin("Friends", "vanilla:tbc", function ()
GuildControlPopupAcceptButton:SetPoint("RIGHT", GuildControlPopupFrameCancelButton, "LEFT", -2*bpad, 0)
end
- if ChannelFrameVerticalBar then -- Channel Tab (TBC+)
- StripTextures(ChannelFrameVerticalBar)
- SkinButton(ChannelFrameNewButton)
- ChannelFrameNewButton:SetPoint("BOTTOMRIGHT", -15, 82)
-
- StripTextures(ChannelListScrollFrame)
- SkinScrollbar(ChannelListScrollFrameScrollBar)
-
- for i = 1, MAX_DISPLAY_CHANNEL_BUTTONS do
- StripTextures(_G["ChannelButton"..i])
- SkinButton(_G["ChannelButton"..i])
- end
-
- for i = 1, 22 do
- StripTextures(_G["ChannelMemberButton"..i])
- end
-
- CreateBackdrop(ChannelMemberButton1)
- ChannelMemberButton1.backdrop:SetPoint("BOTTOMRIGHT", ChannelMemberButton22, "BOTTOMRIGHT", -1, 0)
-
- StripTextures(ChannelRosterScrollFrame)
- SkinScrollbar(ChannelRosterScrollFrameScrollBar)
-
- StripTextures(ChannelFrameDaughterFrame)
- CreateBackdrop(ChannelFrameDaughterFrame)
-
- StripTextures(ChannelFrameDaughterFrameChannelName)
- CreateBackdrop(ChannelFrameDaughterFrameChannelName, nil, true)
- ChannelFrameDaughterFrameChannelName:SetTextInsets(5,5,5,5)
-
- StripTextures(ChannelFrameDaughterFrameChannelPassword)
- CreateBackdrop(ChannelFrameDaughterFrameChannelPassword, nil, true)
- ChannelFrameDaughterFrameChannelPassword:SetTextInsets(5,5,5,5)
-
- SkinCloseButton(ChannelFrameDaughterFrameDetailCloseButton)
-
- SkinButton(ChannelFrameDaughterFrameCancelButton)
- SkinButton(ChannelFrameDaughterFrameOkayButton)
- end
-
do -- Raid Tab
StripTextures(RaidInfoFrame)
CreateBackdrop(RaidInfoFrame, nil, true, .75)
diff --git a/skins/blizzard/game_menu.lua b/skins/blizzard/game_menu.lua
index 9b6d440b..9e202c7a 100644
--- a/skins/blizzard/game_menu.lua
+++ b/skins/blizzard/game_menu.lua
@@ -1,14 +1,10 @@
-pfUI:RegisterSkin("Game Menu", "vanilla:tbc", function ()
+pfUI:RegisterSkin("Game Menu", "vanilla", function ()
StripTextures(GameMenuFrame)
CreateBackdrop(GameMenuFrame, nil, true, .75)
CreateBackdropShadow(GameMenuFrame)
GameMenuFrame:SetWidth(GameMenuFrame:GetWidth() - 30)
- if pfUI.expansion == 'tbc' then
- GameMenuFrame:SetHeight(GameMenuFrame:GetHeight() + 10)
- elseif pfUI.expansion == 'vanilla' then
- GameMenuFrame:SetHeight(GameMenuFrame:GetHeight() + 6)
- end
+ GameMenuFrame:SetHeight(GameMenuFrame:GetHeight() + 6)
local title = GetNoNameObject(GameMenuFrame, "FontString", "ARTWORK", MAIN_MENU)
title:SetTextColor(1,1,1,1)
diff --git a/skins/blizzard/gossipquest.lua b/skins/blizzard/gossipquest.lua
index 183347d7..dec691a6 100644
--- a/skins/blizzard/gossipquest.lua
+++ b/skins/blizzard/gossipquest.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterSkin("Gossip and Quest", "vanilla:tbc", function ()
+pfUI:RegisterSkin("Gossip and Quest", "vanilla", function ()
local frames = {'Quest', 'Gossip'}
local panels = {'Greeting', 'Detail', 'Progress', 'Reward'}
local buttons = {
diff --git a/skins/blizzard/guild_registrar.lua b/skins/blizzard/guild_registrar.lua
index 44c1459d..62955cf4 100644
--- a/skins/blizzard/guild_registrar.lua
+++ b/skins/blizzard/guild_registrar.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterSkin("Guild Registrar", "vanilla:tbc", function ()
+pfUI:RegisterSkin("Guild Registrar", "vanilla", function ()
StripTextures(GuildRegistrarFrame)
StripTextures(GuildRegistrarGreetingFrame)
CreateBackdrop(GuildRegistrarFrame, nil, nil, .75)
diff --git a/skins/blizzard/help.lua b/skins/blizzard/help.lua
index 54413aa1..b47060b7 100644
--- a/skins/blizzard/help.lua
+++ b/skins/blizzard/help.lua
@@ -1,19 +1,7 @@
-pfUI:RegisterSkin("Help", "vanilla:tbc", function ()
+pfUI:RegisterSkin("Help", "vanilla", function ()
local rawborder, border = GetBorderSize()
local bpad = rawborder > 1 and border - GetPerfectPixel() or GetPerfectPixel()
- -- not much here for tbc yet
- if pfUI.client > 11200 then
- local ticket, background = TicketStatusFrame:GetChildren()
- CreateBackdrop(background, nil, true, .75)
- TicketStatusFrame:SetHeight(40)
- TicketStatusFrame:ClearAllPoints()
- TicketStatusFrame:SetPoint("TOP", 0, -5)
-
- UpdateMovable(TicketStatusFrame)
- return
- end
-
StripTextures(HelpFrame)
CreateBackdrop(HelpFrame, nil, nil, .75)
CreateBackdropShadow(HelpFrame)
diff --git a/skins/blizzard/inspect.lua b/skins/blizzard/inspect.lua
index b81609c3..cbbc39b4 100644
--- a/skins/blizzard/inspect.lua
+++ b/skins/blizzard/inspect.lua
@@ -20,111 +20,6 @@ local slots = {
"RangedSlot",
}
-pfUI:RegisterSkin("Inspect", "tbc", function ()
- local rawborder, border = GetBorderSize()
- local bpad = rawborder > 1 and border - GetPerfectPixel() or GetPerfectPixel()
-
- HookAddonOrVariable("Blizzard_InspectUI", function()
- CreateBackdrop(InspectFrame, nil, nil, .75)
- CreateBackdropShadow(InspectFrame)
-
- InspectFrame.backdrop:SetPoint("TOPLEFT", 10, -10)
- InspectFrame.backdrop:SetPoint("BOTTOMRIGHT", -30, 72)
- InspectFrame:SetHitRectInsets(10,30,10,72)
- EnableMovable("InspectFrame", "Blizzard_InspectUI", INSPECTFRAME_SUBFRAMES)
-
- SkinCloseButton(InspectFrameCloseButton, InspectFrame.backdrop, -6, -6)
-
- InspectFrame:DisableDrawLayer("ARTWORK")
-
- InspectNameText:ClearAllPoints()
- InspectNameText:SetPoint("TOP", InspectFrame.backdrop, "TOP", 0, -10)
- InspectGuildText:Show()
- InspectGuildText:ClearAllPoints()
- InspectGuildText:SetPoint("TOP", InspectLevelText, "BOTTOM", 0, -1)
-
- for i = 1, 3 do
- local tab = _G["InspectFrameTab"..i]
- local lastTab = _G["InspectFrameTab"..(i-1)]
- tab:ClearAllPoints()
- if lastTab then
- tab:SetPoint("LEFT", lastTab, "RIGHT", border*2 + 1, 0)
- else
- tab:SetPoint("TOPLEFT", InspectFrame.backdrop, "BOTTOMLEFT", bpad, -(border + (border == 1 and 1 or 2)))
- end
- SkinTab(tab)
- end
-
- do -- Character Tab
- StripTextures(InspectPaperDollFrame)
-
- EnableClickRotate(InspectModelFrame)
- InspectModelRotateLeftButton:Hide()
- InspectModelRotateRightButton:Hide()
-
- for _, slot in pairs(slots) do
- local frame = _G["Inspect"..slot]
- SkinButton(frame, nil, nil, nil, _G["Inspect"..slot.."IconTexture"], true)
- end
-
- hooksecurefunc("InspectPaperDollFrame_OnShow", function()
- local guild, title = GetGuildInfo(InspectFrame.unit)
- local text = guild and format(TEXT(GUILD_TITLE_TEMPLATE), title, guild) or ""
- InspectGuildText:SetText(text)
- end)
-
- hooksecurefunc("InspectPaperDollItemSlotButton_Update", function(button)
- local unit = InspectFrame.unit
- local link = GetInventoryItemLink(unit, button:GetID())
- if link then
- local quality = select(3, GetItemInfo(link))
- button:SetBackdropBorderColor(GetItemQualityColor(quality))
- else
- button:SetBackdropBorderColor(pfUI.cache.er, pfUI.cache.eg, pfUI.cache.eb, pfUI.cache.ea)
- end
- end)
- end
-
- do -- PVP Tab
- StripTextures(InspectPVPFrame)
- end
-
- do -- Talent Tab
- StripTextures(InspectTalentFrame)
- InspectTalentFrameCancelButton:Hide()
- InspectTalentFrameCloseButton:Hide()
-
- InspectTalentFrameSpentPoints:ClearAllPoints()
- InspectTalentFrameSpentPoints:SetPoint("BOTTOMRIGHT", InspectTalentFrame, "BOTTOMRIGHT", 0, 83)
-
- StripTextures(InspectTalentFrameScrollFrame)
- SkinScrollbar(InspectTalentFrameScrollFrameScrollBar)
-
- for i = 1, MAX_NUM_TALENTS do
- local talent = _G["InspectTalentFrameTalent"..i]
- if talent then
- StripTextures(talent)
- SkinButton(talent, nil, nil, nil, _G["InspectTalentFrameTalent"..i.."IconTexture"])
-
- _G["InspectTalentFrameTalent"..i.."Rank"]:SetFont(pfUI.font_default, C.global.font_size, "OUTLINE")
- end
- end
-
- for i = 1, 3 do
- local tab = _G["InspectTalentFrameTab"..i]
- local lastTab = _G["InspectTalentFrameTab"..(i-1)]
- tab:ClearAllPoints()
- if lastTab then
- tab:SetPoint("LEFT", lastTab, "RIGHT", border*2 + 1, 0)
- else
- tab:SetPoint("TOPLEFT", 70, -50)
- end
- SkinTab(tab)
- end
- end
- end)
-end)
-
pfUI:RegisterSkin("Inspect", "vanilla", function ()
local rawborder, border = GetBorderSize()
local bpad = rawborder > 1 and border - GetPerfectPixel() or GetPerfectPixel()
diff --git a/skins/blizzard/itemtext.lua b/skins/blizzard/itemtext.lua
index 2455919a..568901d9 100644
--- a/skins/blizzard/itemtext.lua
+++ b/skins/blizzard/itemtext.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterSkin("Books", "vanilla:tbc", function ()
+pfUI:RegisterSkin("Books", "vanilla", function ()
StripTextures(ItemTextFrame)
CreateBackdrop(ItemTextFrame, nil, nil, .75)
CreateBackdropShadow(ItemTextFrame)
diff --git a/skins/blizzard/keybindings.lua b/skins/blizzard/keybindings.lua
index 049aac20..9b570b88 100644
--- a/skins/blizzard/keybindings.lua
+++ b/skins/blizzard/keybindings.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterSkin("KeyBindings", "vanilla:tbc", function ()
+pfUI:RegisterSkin("KeyBindings", "vanilla", function ()
local rawborder, border = GetBorderSize()
local bpad = rawborder > 1 and border - GetPerfectPixel() or GetPerfectPixel()
diff --git a/skins/blizzard/macro.lua b/skins/blizzard/macro.lua
index 890ad6bc..efe4c582 100644
--- a/skins/blizzard/macro.lua
+++ b/skins/blizzard/macro.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterSkin("Macro", "vanilla:tbc", function ()
+pfUI:RegisterSkin("Macro", "vanilla", function ()
local rawborder, border = GetBorderSize()
local bpad = rawborder > 1 and border - GetPerfectPixel() or GetPerfectPixel()
diff --git a/skins/blizzard/mail.lua b/skins/blizzard/mail.lua
index 861c7d1f..8830e0fe 100644
--- a/skins/blizzard/mail.lua
+++ b/skins/blizzard/mail.lua
@@ -1,53 +1,10 @@
-pfUI:RegisterSkin("Mailbox", "vanilla:tbc", function ()
+pfUI:RegisterSkin("Mailbox", "vanilla", function ()
local rawborder, border = GetBorderSize()
local bpad = rawborder > 1 and border - GetPerfectPixel() or GetPerfectPixel()
- -- Compatibility
local StationeryBackgroundLeft, StationeryBackgroundRight
- if ATTACHMENTS_MAX_SEND then -- tbc
- do -- SendMailFrame
- for i = 1, ATTACHMENTS_MAX_SEND do
- local btn = _G["SendMailAttachment"..i]
- StripTextures(btn)
- SkinButton(btn, nil, nil, nil, nil, true)
- end
- hooksecurefunc("SendMailFrame_Update", function()
- for i = 1, ATTACHMENTS_MAX_SEND do
- local btn = _G["SendMailAttachment"..i]
- HandleIcon(btn, btn:GetNormalTexture())
-
- local link = GetSendMailItemLink(i)
- if link then
- local r,g,b = GetItemQualityColor(select(3, GetItemInfo(link)))
- btn:SetBackdropBorderColor(r,g,b,1)
- else
- btn:SetBackdropBorderColor(GetStringColor(pfUI_config.appearance.border.color))
- end
- end
- end)
-
- StationeryBackgroundLeft, StationeryBackgroundRight = SendStationeryBackgroundLeft, SendStationeryBackgroundRight
- end
-
- do -- OpenMailFrame
- for i = 1, ATTACHMENTS_MAX_RECEIVE do
- SkinButton(_G["OpenMailAttachmentButton"..i], nil, nil, nil, _G["OpenMailAttachmentButton"..i.."IconTexture"], true)
- end
-
- hooksecurefunc("InboxFrame_OnClick", function(index)
- for i=1, ATTACHMENTS_MAX_RECEIVE do
- local link = GetInboxItemLink(index, i)
- if not link then return end
- local r,g,b = GetItemQualityColor(select(3, GetItemInfo(link)))
- _G["OpenMailAttachmentButton"..i]:SetBackdropBorderColor(r,g,b,1)
- end
- end)
-
- SkinButton(OpenMailReportSpamButton)
- end
- else -- vanilla
- do -- SendMailFrame
+ do -- SendMailFrame
local skin = CreateFrame("Frame")
skin:SetScript("OnEvent", function()
this:UnregisterEvent("MAIL_SHOW")
@@ -122,7 +79,6 @@ pfUI:RegisterSkin("Mailbox", "vanilla:tbc", function ()
end
end)
end
- end
StripTextures(MailFrame, true)
CreateBackdrop(MailFrame, nil, nil, .75)
diff --git a/skins/blizzard/merchant.lua b/skins/blizzard/merchant.lua
index ccceba7e..084285cf 100644
--- a/skins/blizzard/merchant.lua
+++ b/skins/blizzard/merchant.lua
@@ -1,21 +1,9 @@
-pfUI:RegisterSkin("Merchant", "vanilla:tbc", function ()
+pfUI:RegisterSkin("Merchant", "vanilla", function ()
local rawborder, border = GetBorderSize()
local bpad = rawborder > 1 and border - GetPerfectPixel() or GetPerfectPixel()
- -- Compatibility
- if MerchantGuildBankRepairButton then -- tbc
- SkinButton(MerchantGuildBankRepairButton, nil, nil, nil, MerchantGuildBankRepairButtonIcon)
- MerchantGuildBankRepairButtonIcon:SetTexCoord(.59, .82, .06, .54)
- hooksecurefunc("MerchantFrame_UpdateRepairButtons", function()
- MerchantGuildBankRepairButton:ClearAllPoints()
- MerchantGuildBankRepairButton:SetPoint("RIGHT", MerchantBuyBackItemItemButton, "LEFT", -14, 0)
- MerchantRepairAllButton:ClearAllPoints()
- MerchantRepairAllButton:SetPoint("RIGHT", MerchantGuildBankRepairButton, "LEFT", -6, 0)
- end)
- else -- vanilla
- MerchantRepairAllButton:ClearAllPoints()
- MerchantRepairAllButton:SetPoint("RIGHT", MerchantBuyBackItemItemButton, "LEFT", -6, 0)
- end
+ MerchantRepairAllButton:ClearAllPoints()
+ MerchantRepairAllButton:SetPoint("RIGHT", MerchantBuyBackItemItemButton, "LEFT", -6, 0)
StripTextures(MerchantFrame)
CreateBackdrop(MerchantFrame, nil, nil, .75)
diff --git a/skins/blizzard/miscellaneous.lua b/skins/blizzard/miscellaneous.lua
index ea67ac3b..2af1e4de 100644
--- a/skins/blizzard/miscellaneous.lua
+++ b/skins/blizzard/miscellaneous.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterSkin("Stack Split", "vanilla:tbc", function ()
+pfUI:RegisterSkin("Stack Split", "vanilla", function ()
StripTextures(StackSplitFrame)
CreateBackdrop(StackSplitFrame, nil, nil, .75)
CreateBackdropShadow(StackSplitFrame)
@@ -7,7 +7,7 @@ pfUI:RegisterSkin("Stack Split", "vanilla:tbc", function ()
SkinButton(StackSplitCancelButton)
end)
-pfUI:RegisterSkin("Coin Pickup", "vanilla:tbc", function ()
+pfUI:RegisterSkin("Coin Pickup", "vanilla", function ()
StripTextures(CoinPickupFrame)
CreateBackdrop(CoinPickupFrame, nil, nil, .75)
CreateBackdropShadow(CoinPickupFrame)
@@ -16,7 +16,7 @@ pfUI:RegisterSkin("Coin Pickup", "vanilla:tbc", function ()
SkinButton(CoinPickupCancelButton)
end)
-pfUI:RegisterSkin("Color Picker", "vanilla:tbc", function ()
+pfUI:RegisterSkin("Color Picker", "vanilla", function ()
CreateBackdrop(ColorPickerFrame)
CreateBackdropShadow(ColorPickerFrame)
@@ -32,7 +32,7 @@ pfUI:RegisterSkin("Color Picker", "vanilla:tbc", function ()
SkinSlider(OpacitySliderFrame)
end)
-pfUI:RegisterSkin("Opacity", "vanilla:tbc", function ()
+pfUI:RegisterSkin("Opacity", "vanilla", function ()
CreateBackdrop(OpacityFrame, nil, true, .75)
CreateBackdropShadow(OpacityFrame)
@@ -41,7 +41,7 @@ pfUI:RegisterSkin("Opacity", "vanilla:tbc", function ()
OpacityFrameSlider:SetPoint("CENTER", 0, 0)
end)
-pfUI:RegisterSkin("Tutorial", "vanilla:tbc", function ()
+pfUI:RegisterSkin("Tutorial", "vanilla", function ()
CreateBackdrop(TutorialFrame, nil, true, .75)
CreateBackdropShadow(TutorialFrame)
@@ -49,7 +49,7 @@ pfUI:RegisterSkin("Tutorial", "vanilla:tbc", function ()
SkinButton(TutorialFrameOkayButton)
end)
-pfUI:RegisterSkin("Quest Timer", "vanilla:tbc", function ()
+pfUI:RegisterSkin("Quest Timer", "vanilla", function ()
CreateBackdrop(QuestTimerFrame, nil, nil, .75)
CreateBackdropShadow(QuestTimerFrame)
UpdateMovable(QuestTimerFrame, true)
diff --git a/skins/blizzard/options-sound.lua b/skins/blizzard/options-sound.lua
index 341486ab..257d4023 100644
--- a/skins/blizzard/options-sound.lua
+++ b/skins/blizzard/options-sound.lua
@@ -1,40 +1,18 @@
-pfUI:RegisterSkin("Options - Sound", "vanilla:tbc", function ()
+pfUI:RegisterSkin("Options - Sound", "vanilla", function ()
local rawborder, border = GetBorderSize()
local bpad = rawborder > 1 and border - GetPerfectPixel() or GetPerfectPixel()
- -- Compatibility
- local SoundOptionsFrameHeaderText, NUM_CHECKBOXES, NUM_SLIDERS
- if SOUND_OPTIONS then -- tbc
- SoundOptionsFrameHeaderText = GetNoNameObject(SoundOptionsFrame, "FontString", "BACKGROUND", SOUND_OPTIONS)
- NUM_CHECKBOXES = 11
- NUM_SLIDERS = 6
+ local SoundOptionsFrameHeaderText = GetNoNameObject(SoundOptionsFrame, "FontString", "ARTWORK", SOUNDOPTIONS_MENU)
+ local NUM_CHECKBOXES = 8
+ local NUM_SLIDERS = 4
- StripTextures(AudioOptionsFrame)
- CreateBackdrop(SoundOptionsFramePlayback, nil, true, .75)
- CreateBackdrop(SoundOptionsFrameHardware, nil, true, .75)
- CreateBackdrop(SoundOptionsFrameVolume, nil, true, .75)
-
- SkinDropDown(SoundOptionsOutputDropDown)
-
- SoundOptionsFrameDefaults:ClearAllPoints()
- SoundOptionsFrameDefaults:SetPoint("TOPLEFT", SoundOptionsFramePlayback, "BOTTOMLEFT", 0, -10)
- SoundOptionsFrameCancel:ClearAllPoints()
- SoundOptionsFrameCancel:SetPoint("TOPRIGHT", SoundOptionsFrameVolume, "BOTTOMRIGHT", 0, -10)
- SoundOptionsFrameOkay:ClearAllPoints()
- SoundOptionsFrameOkay:SetPoint("RIGHT", SoundOptionsFrameCancel, "LEFT", -2*bpad, 0)
- else -- vanilla
- SoundOptionsFrameHeaderText = GetNoNameObject(SoundOptionsFrame, "FontString", "ARTWORK", SOUNDOPTIONS_MENU)
- NUM_CHECKBOXES = 8
- NUM_SLIDERS = 4
-
- SoundOptionsFrameOkay:ClearAllPoints()
- SoundOptionsFrameOkay:SetPoint("RIGHT", SoundOptionsFrameCancel, "LEFT", -2*bpad, 0)
- SoundOptionsFrameSlider1:ClearAllPoints()
- SoundOptionsFrameSlider1:SetPoint("TOPRIGHT", SoundOptionsFrame, "TOPRIGHT", -18, -43)
- for i=2, NUM_SLIDERS do
- _G["SoundOptionsFrameSlider"..i]:ClearAllPoints()
- _G["SoundOptionsFrameSlider"..i]:SetPoint("TOP", _G["SoundOptionsFrameSlider"..i-1], "BOTTOM", 0, -30)
- end
+ SoundOptionsFrameOkay:ClearAllPoints()
+ SoundOptionsFrameOkay:SetPoint("RIGHT", SoundOptionsFrameCancel, "LEFT", -2*bpad, 0)
+ SoundOptionsFrameSlider1:ClearAllPoints()
+ SoundOptionsFrameSlider1:SetPoint("TOPRIGHT", SoundOptionsFrame, "TOPRIGHT", -18, -43)
+ for i=2, NUM_SLIDERS do
+ _G["SoundOptionsFrameSlider"..i]:ClearAllPoints()
+ _G["SoundOptionsFrameSlider"..i]:SetPoint("TOP", _G["SoundOptionsFrameSlider"..i-1], "BOTTOM", 0, -30)
end
StripTextures(SoundOptionsFrame)
diff --git a/skins/blizzard/options-video.lua b/skins/blizzard/options-video.lua
index 70c7e325..853bdcb0 100644
--- a/skins/blizzard/options-video.lua
+++ b/skins/blizzard/options-video.lua
@@ -1,45 +1,19 @@
-pfUI:RegisterSkin("Options - Video", "vanilla:tbc", function ()
+pfUI:RegisterSkin("Options - Video", "vanilla", function ()
local rawborder, border = GetBorderSize()
local bpad = rawborder > 1 and border - GetPerfectPixel() or GetPerfectPixel()
- -- Compatibility
- local MAX_SLIDERS, MAX_CHECKBOXES
- if OptionsFrameSlider10 then -- tbc
- MAX_SLIDERS = 11
- MAX_CHECKBOXES = 19
+ local MAX_SLIDERS = 9
+ local MAX_CHECKBOXES = 18
- for i=1, MAX_SLIDERS do
- local slider = _G["OptionsFrameSlider"..i]
- local shift = 0
- if i == 4 or i == 5 or i == 7 or i == 8 or i == 10 or i == 11 then shift = 10 end
- local point, anchor, anchorPoint, x, y = slider:GetPoint()
- slider:ClearAllPoints()
- slider:SetPoint(point, anchor, anchorPoint, x, y - shift)
- end
-
- hooksecurefunc("OptionsFrame_Load", function()
- OptionsFramePixelShaders:SetWidth(230)
- OptionsFrameMiscellaneous:ClearAllPoints()
- OptionsFrameMiscellaneous:SetPoint("LEFT", OptionsFramePixelShaders, "RIGHT", 6, 0)
- end)
- OptionsFrameDefaults:ClearAllPoints()
- OptionsFrameDefaults:SetPoint("TOPLEFT", OptionsFramePixelShaders, "BOTTOMLEFT", 0, -10)
- OptionsFrameCancel:ClearAllPoints()
- OptionsFrameCancel:SetPoint("TOPRIGHT", OptionsFrameMiscellaneous, "BOTTOMRIGHT", 0, -10)
- else -- vanilla
- MAX_SLIDERS = 9
- MAX_CHECKBOXES = 18
-
- for i=1, MAX_SLIDERS do
- local slider = _G["OptionsFrameSlider"..i]
- local shift = 0
- if i == 1 or i == 6 then shift = 4
- elseif i == 4 or i == 8 then shift = 10
- end
- local point, anchor, anchorPoint, x, y = slider:GetPoint()
- slider:ClearAllPoints()
- slider:SetPoint(point, anchor, anchorPoint, x, y - shift)
+ for i=1, MAX_SLIDERS do
+ local slider = _G["OptionsFrameSlider"..i]
+ local shift = 0
+ if i == 1 or i == 6 then shift = 4
+ elseif i == 4 or i == 8 then shift = 10
end
+ local point, anchor, anchorPoint, x, y = slider:GetPoint()
+ slider:ClearAllPoints()
+ slider:SetPoint(point, anchor, anchorPoint, x, y - shift)
end
CreateBackdrop(OptionsFrame, nil, nil, .75)
diff --git a/skins/blizzard/popup_dialogs.lua b/skins/blizzard/popup_dialogs.lua
index d795a7bf..fc3aed02 100644
--- a/skins/blizzard/popup_dialogs.lua
+++ b/skins/blizzard/popup_dialogs.lua
@@ -1,12 +1,5 @@
-pfUI:RegisterSkin("Popup Dialogs", "vanilla:tbc", function ()
+pfUI:RegisterSkin("Popup Dialogs", "vanilla", function ()
for i = 1, STATICPOPUP_NUMDIALOGS do
- -- Compatibility
- local money = _G["StaticPopup"..i.."MoneyInputFrame"]
- if money then -- tbc
- SkinMoneyInputFrame(money)
- end
-
-
local dialog = _G["StaticPopup"..i]
CreateBackdrop(dialog, nil, true, .75)
CreateBackdropShadow(dialog)
diff --git a/skins/blizzard/professions.lua b/skins/blizzard/professions.lua
index eab6d31e..bbd266d1 100644
--- a/skins/blizzard/professions.lua
+++ b/skins/blizzard/professions.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterSkin("Profession", "vanilla:tbc", function ()
+pfUI:RegisterSkin("Profession", "vanilla", function ()
local rawborder, border = GetBorderSize()
local bpad = rawborder > 1 and border - GetPerfectPixel() or GetPerfectPixel()
@@ -219,37 +219,7 @@ pfUI:RegisterSkin("Profession", "vanilla:tbc", function ()
end)
end
- -- Compatibility
- if search then -- tbc
- _G[displayed] = 21
- scrollframe:SetHeight(338)
-
- local rank = _G[name.."RankFrameSkillRank"]
- rank:ClearAllPoints()
- rank:SetPoint("CENTER", rankbar, "CENTER", 0, 0)
-
- local available = _G[frame:GetName().."AvailableFilterCheckButton"]
- SkinCheckbox(available)
- available:ClearAllPoints()
- available:SetPoint("TOPLEFT", scrollframe.backdrop, "BOTTOMLEFT", -4, -5)
-
- search:DisableDrawLayer("BACKGROUND")
- CreateBackdrop(search, nil, nil, 1)
- search.backdrop:SetAllPoints(search)
- search:SetTextInsets(5, 5, 5, 5)
- search:SetHeight(22)
- search:ClearAllPoints()
- search:SetPoint("TOPRIGHT", scrollframe.backdrop, "BOTTOMRIGHT", 0, -5)
-
- local craft_filter = CraftFrameFilterDropDown
- if craft_filter then
- SkinDropDown(craft_filter)
- craft_filter:ClearAllPoints()
- craft_filter:SetPoint("BOTTOMRIGHT", scrollframe.backdrop, "TOPRIGHT", 15, 0)
- end
- else -- vanilla
- _G[displayed] = 23
- end
+ _G[displayed] = 23
-- build remaining tradeskills
for i = 9, _G[displayed] do
local button = _G[template..i] or CreateFrame("Button", template..i, frame, template.."ButtonTemplate")
diff --git a/skins/blizzard/questlog.lua b/skins/blizzard/questlog.lua
index 23b4d0e8..748b2fb9 100644
--- a/skins/blizzard/questlog.lua
+++ b/skins/blizzard/questlog.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterSkin("Quest Log", "vanilla:tbc", function ()
+pfUI:RegisterSkin("Quest Log", "vanilla", function ()
local rawborder, border = GetBorderSize()
local bpad = rawborder > 1 and border - GetPerfectPixel() or GetPerfectPixel()
@@ -6,23 +6,10 @@ pfUI:RegisterSkin("Quest Log", "vanilla:tbc", function ()
_G.MAX_WATCHABLE_QUESTS = 20 -- TODO
do -- quest log frame
- -- Compatibility
- local QUEST_COUNT
- if QuestLogCount then -- tbc
- QUEST_COUNT = QuestLogCount
+ local QUEST_COUNT = QuestLogQuestCount
- StripTextures(QUEST_COUNT)
- QUEST_COUNT:ClearAllPoints()
- hooksecurefunc("QuestLogUpdateQuestCount", function(numQuests)
- QUEST_COUNT:ClearAllPoints()
- QUEST_COUNT:SetPoint("BOTTOMRIGHT", QuestLogFrame, "TOPRIGHT", 0, -50)
- end)
- else -- vanilla
- QUEST_COUNT = QuestLogQuestCount
-
- QUEST_COUNT:ClearAllPoints()
- QUEST_COUNT:SetPoint("TOPRIGHT", -10, -30)
- end
+ QUEST_COUNT:ClearAllPoints()
+ QUEST_COUNT:SetPoint("TOPRIGHT", -10, -30)
hooksecurefunc("QuestLog_OnShow", function()
QuestLogFrame:ClearAllPoints()
diff --git a/skins/blizzard/readycheck.lua b/skins/blizzard/readycheck.lua
index 51ec176b..0d21ec89 100644
--- a/skins/blizzard/readycheck.lua
+++ b/skins/blizzard/readycheck.lua
@@ -1,12 +1,6 @@
-pfUI:RegisterSkin("Readycheck", "vanilla:tbc", function ()
+pfUI:RegisterSkin("Readycheck", "vanilla", function ()
HookAddonOrVariable("Blizzard_RaidUI", function()
- -- Compatibility
- local update_func
- if ReadyCheckFrame_OnUpdate then -- tbc
- update_func = "ReadyCheckFrame_OnUpdate"
- else -- vanilla
- update_func = "ReadyCheck_OnUpdate"
- end
+ local update_func = "ReadyCheck_OnUpdate"
StripTextures(ReadyCheckFrame, true)
CreateBackdrop(ReadyCheckFrame, nil, nil, .75)
diff --git a/skins/blizzard/spellbook.lua b/skins/blizzard/spellbook.lua
index e28383c3..db5bf427 100644
--- a/skins/blizzard/spellbook.lua
+++ b/skins/blizzard/spellbook.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterSkin("Spellbook", "vanilla:tbc", function ()
+pfUI:RegisterSkin("Spellbook", "vanilla", function ()
local rawborder, border = GetBorderSize()
local bpad = rawborder > 1 and border - GetPerfectPixel() or GetPerfectPixel()
diff --git a/skins/blizzard/stable.lua b/skins/blizzard/stable.lua
index 9e6e7a52..fdf6f7f1 100644
--- a/skins/blizzard/stable.lua
+++ b/skins/blizzard/stable.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterSkin("Pet Stable Master", "vanilla:tbc", function ()
+pfUI:RegisterSkin("Pet Stable Master", "vanilla", function ()
StripTextures(PetStableFrame)
CreateBackdrop(PetStableFrame, nil, nil, .75)
CreateBackdropShadow(PetStableFrame)
diff --git a/skins/blizzard/tabard.lua b/skins/blizzard/tabard.lua
index e8e48c21..46efde05 100644
--- a/skins/blizzard/tabard.lua
+++ b/skins/blizzard/tabard.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterSkin("Guild Tabard", "vanilla:tbc", function ()
+pfUI:RegisterSkin("Guild Tabard", "vanilla", function ()
local rawborder, border = GetBorderSize()
local bpad = rawborder > 1 and border - GetPerfectPixel() or GetPerfectPixel()
diff --git a/skins/blizzard/talents.lua b/skins/blizzard/talents.lua
index f26e5a4c..11c9370a 100644
--- a/skins/blizzard/talents.lua
+++ b/skins/blizzard/talents.lua
@@ -1,16 +1,10 @@
-pfUI:RegisterSkin("Talents", "vanilla:tbc", function ()
+pfUI:RegisterSkin("Talents", "vanilla", function ()
local rawborder, border = GetBorderSize()
local bpad = rawborder > 1 and border - GetPerfectPixel() or GetPerfectPixel()
HookAddonOrVariable("Blizzard_TalentUI", function()
- -- Compatibility
- local TALENT_FRAME, TALENT_FRAME_NAME
- if PlayerTalentFrame then -- tbc
- TALENT_FRAME = _G.PlayerTalentFrame
- else -- vanilla
- TALENT_FRAME = _G.TalentFrame
- end
- TALENT_FRAME_NAME = TALENT_FRAME:GetName()
+ local TALENT_FRAME = _G.TalentFrame
+ local TALENT_FRAME_NAME = TALENT_FRAME:GetName()
StripTextures(TALENT_FRAME)
diff --git a/skins/blizzard/taxi.lua b/skins/blizzard/taxi.lua
index fac03ade..79a7bc36 100644
--- a/skins/blizzard/taxi.lua
+++ b/skins/blizzard/taxi.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterSkin("Flightmaster", "vanilla:tbc", function ()
+pfUI:RegisterSkin("Flightmaster", "vanilla", function ()
StripTextures(TaxiFrame)
CreateBackdrop(TaxiFrame, nil, nil, .75)
CreateBackdropShadow(TaxiFrame)
diff --git a/skins/blizzard/tooltips.lua b/skins/blizzard/tooltips.lua
index c050c541..d1195ee8 100644
--- a/skins/blizzard/tooltips.lua
+++ b/skins/blizzard/tooltips.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterSkin("Tooltips", "vanilla:tbc", function ()
+pfUI:RegisterSkin("Tooltips", "vanilla", function ()
local rawborder, border = GetBorderSize()
local alpha = tonumber(C.tooltip.alpha)
diff --git a/skins/blizzard/trade.lua b/skins/blizzard/trade.lua
index fd6237d6..fe0a9e4c 100644
--- a/skins/blizzard/trade.lua
+++ b/skins/blizzard/trade.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterSkin("Trade", "vanilla:tbc", function ()
+pfUI:RegisterSkin("Trade", "vanilla", function ()
local rawborder, border = GetBorderSize()
local bpad = rawborder > 1 and border - GetPerfectPixel() or GetPerfectPixel()
diff --git a/skins/blizzard/trainer.lua b/skins/blizzard/trainer.lua
index 62df6005..e752f7bb 100644
--- a/skins/blizzard/trainer.lua
+++ b/skins/blizzard/trainer.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterSkin("Trainer", "vanilla:tbc", function ()
+pfUI:RegisterSkin("Trainer", "vanilla", function ()
local rawborder, border = GetBorderSize()
local bpad = rawborder > 1 and border - GetPerfectPixel() or GetPerfectPixel()
From 921a5833fa73cdf31a7ecf1aad0b17bc818848a6 Mon Sep 17 00:00:00 2001
From: Meow <30401521+me0wg4ming@users.noreply.github.com>
Date: Sat, 3 Jan 2026 12:55:51 +0100
Subject: [PATCH 12/40] Update pfUI.toc
---
pfUI.toc | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pfUI.toc b/pfUI.toc
index 72c42fa4..187f4a22 100644
--- a/pfUI.toc
+++ b/pfUI.toc
@@ -3,7 +3,7 @@
## Author: Shagu
## Notes: A complete user interface replacement.
## Notes-ruRU: Полная замена пользовательского интерфейса.
-## Version: 5.5.4
+## Version: 5.5.5
## SavedVariables: pfUI_profiles, pfUI_addon_profiles, pfUI_cache
## SavedVariablesPerCharacter: pfUI_config, pfUI_init, pfUI_playerDB
From 5e44fcd2d32690c0abe7624569562f71202247d3 Mon Sep 17 00:00:00 2001
From: Meow <30401521+me0wg4ming@users.noreply.github.com>
Date: Sat, 3 Jan 2026 15:21:37 +0100
Subject: [PATCH 13/40] nameplate color fix
nameplate color fix
---
modules/nameplates.lua | 3 +++
1 file changed, 3 insertions(+)
diff --git a/modules/nameplates.lua b/modules/nameplates.lua
index ce25a161..cb926b50 100644
--- a/modules/nameplates.lua
+++ b/modules/nameplates.lua
@@ -2,6 +2,9 @@ pfUI:RegisterModule("nameplates", "vanilla", function ()
-- disable original castbars
pcall(SetCVar, "ShowVKeyCastbar", 0)
+ -- check for SuperWoW support
+ local superwow_active = HasSuperWoW()
+
local unitcolors = {
["ENEMY_NPC"] = { .9, .2, .3, .8 },
["NEUTRAL_NPC"] = { 1, 1, .3, .8 },
From d6356836fb7172321dfc118a8657a2736598e896 Mon Sep 17 00:00:00 2001
From: Meow <30401521+me0wg4ming@users.noreply.github.com>
Date: Sat, 3 Jan 2026 17:08:53 +0100
Subject: [PATCH 14/40] Delete .github directory
---
.github/FUNDING.yml | 2 --
.github/workflows/close-issues.yml | 24 ------------------------
2 files changed, 26 deletions(-)
delete mode 100644 .github/FUNDING.yml
delete mode 100644 .github/workflows/close-issues.yml
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
deleted file mode 100644
index 4cb83f66..00000000
--- a/.github/FUNDING.yml
+++ /dev/null
@@ -1,2 +0,0 @@
-github: [shagu]
-ko_fi: shagu
diff --git a/.github/workflows/close-issues.yml b/.github/workflows/close-issues.yml
deleted file mode 100644
index da0f0103..00000000
--- a/.github/workflows/close-issues.yml
+++ /dev/null
@@ -1,24 +0,0 @@
-name: Close inactive issues
-on:
- workflow_dispatch:
- schedule:
- - cron: "30 1 * * *"
-
-jobs:
- close-issues:
- runs-on: ubuntu-latest
- permissions:
- issues: write
- pull-requests: write
- steps:
- - uses: actions/stale@v5
- with:
- operations-per-run: 100
- days-before-issue-stale: 30
- days-before-issue-close: 14
- stale-issue-label: "stale"
- stale-issue-message: "This issue is stale because it has been open for 30 days with no activity."
- close-issue-message: "This issue was closed because it has been inactive for 14 days since being marked as stale."
- days-before-pr-stale: -1
- days-before-pr-close: -1
- repo-token: ${{ secrets.GITHUB_TOKEN }}
From 0cae1cf1ab364a9217160e5db5162bf45281adf4 Mon Sep 17 00:00:00 2001
From: Meow <30401521+me0wg4ming@users.noreply.github.com>
Date: Sat, 3 Jan 2026 19:48:41 +0100
Subject: [PATCH 15/40] small changes
small changes
---
.github/FUNDING.yml | 2 +
.github/workflows/close-issues.yml | 24 +
api/unitframes.lua | 2 +
compat/tbc.lua | 1960 ++++++++++++++++++++++++++
libs/librange.lua | 2 +
modules/castbar.lua | 2 +
modules/combatlogfix.lua | 7 +
modules/nameplates.lua | 4 +
modules/thirdparty-tbc.lua | 381 +++++
pfUI.toc | 2 +-
skins/blizzard/arena.lua | 55 +
skins/blizzard/arena_registrar.lua | 119 ++
skins/blizzard/guildbank.lua | 131 ++
skins/blizzard/lfg.lua | 75 +
skins/blizzard/options-interface.lua | 175 +++
skins/blizzard/socket.lua | 39 +
skins/blizzard/time_manager.lua | 122 ++
skins/blizzard/tracking.lua | 11 +
18 files changed, 3112 insertions(+), 1 deletion(-)
create mode 100644 .github/FUNDING.yml
create mode 100644 .github/workflows/close-issues.yml
create mode 100644 compat/tbc.lua
create mode 100644 modules/combatlogfix.lua
create mode 100644 modules/thirdparty-tbc.lua
create mode 100644 skins/blizzard/arena.lua
create mode 100644 skins/blizzard/arena_registrar.lua
create mode 100644 skins/blizzard/guildbank.lua
create mode 100644 skins/blizzard/lfg.lua
create mode 100644 skins/blizzard/options-interface.lua
create mode 100644 skins/blizzard/socket.lua
create mode 100644 skins/blizzard/time_manager.lua
create mode 100644 skins/blizzard/tracking.lua
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
new file mode 100644
index 00000000..4cb83f66
--- /dev/null
+++ b/.github/FUNDING.yml
@@ -0,0 +1,2 @@
+github: [shagu]
+ko_fi: shagu
diff --git a/.github/workflows/close-issues.yml b/.github/workflows/close-issues.yml
new file mode 100644
index 00000000..da0f0103
--- /dev/null
+++ b/.github/workflows/close-issues.yml
@@ -0,0 +1,24 @@
+name: Close inactive issues
+on:
+ workflow_dispatch:
+ schedule:
+ - cron: "30 1 * * *"
+
+jobs:
+ close-issues:
+ runs-on: ubuntu-latest
+ permissions:
+ issues: write
+ pull-requests: write
+ steps:
+ - uses: actions/stale@v5
+ with:
+ operations-per-run: 100
+ days-before-issue-stale: 30
+ days-before-issue-close: 14
+ stale-issue-label: "stale"
+ stale-issue-message: "This issue is stale because it has been open for 30 days with no activity."
+ close-issue-message: "This issue was closed because it has been inactive for 14 days since being marked as stale."
+ days-before-pr-stale: -1
+ days-before-pr-close: -1
+ repo-token: ${{ secrets.GITHUB_TOKEN }}
diff --git a/api/unitframes.lua b/api/unitframes.lua
index 9b590ba3..db4fe46e 100644
--- a/api/unitframes.lua
+++ b/api/unitframes.lua
@@ -1,6 +1,8 @@
-- load pfUI environment
setfenv(1, pfUI:GetEnvironment())
+local superwow_active = HasSuperWoW()
+
pfUI.uf = CreateFrame("Frame", nil, UIParent)
pfUI.uf:SetScript("OnUpdate", function()
if InCombatLockdown and not InCombatLockdown() then
diff --git a/compat/tbc.lua b/compat/tbc.lua
new file mode 100644
index 00000000..526d94bf
--- /dev/null
+++ b/compat/tbc.lua
@@ -0,0 +1,1960 @@
+-- load pfUI environment
+setfenv(1, pfUI:GetEnvironment())
+if pfUI.expansion ~= "tbc" then return end
+
+-- [[ Constants ]]--
+CASTBAR_EVENT_CAST_DELAY = "UNIT_SPELLCAST_DELAYED"
+CASTBAR_EVENT_CHANNEL_DELAY = "UNIT_SPELLCAST_CHANNEL_UPDATE"
+CASTBAR_EVENT_CAST_START = "UNIT_SPELLCAST_START"
+CASTBAR_EVENT_CHANNEL_START = "UNIT_SPELLCAST_CHANNEL_START"
+
+EVENTS_MINIMAP_ZONE_UPDATE = {"PLAYER_ENTERING_WORLD", "ZONE_CHANGED_NEW_AREA", "ZONE_CHANGED"}
+
+MICRO_BUTTONS = {
+ 'CharacterMicroButton', 'SpellbookMicroButton', 'TalentMicroButton',
+ 'QuestLogMicroButton', 'SocialsMicroButton', 'LFGMicroButton',
+ 'MainMenuMicroButton', 'HelpMicroButton',
+}
+
+NAMEPLATE_OBJECTORDER = { "border", "castborder", "casticon", "glow", "name", "level", "levelicon", "raidicon" }
+
+NAMEPLATE_FRAMETYPE = "Frame"
+
+MINIMAP_TRACKING_FRAME = _G.MiniMapTracking
+
+FRIENDS_NAME_LOCATION = "ButtonTextLocation"
+
+COOLDOWN_FRAME_TYPE = "Cooldown"
+LOOT_BUTTON_FRAME_TYPE = "Button"
+
+PLAYER_BUFF_START_ID = 0
+
+ACTIONBAR_SECURE_TEMPLATE_BAR = "SecureStateHeaderTemplate"
+ACTIONBAR_SECURE_TEMPLATE_BUTTON = "SecureActionButtonTemplate"
+UNITFRAME_SECURE_TEMPLATE = "SecureUnitButtonTemplate"
+
+--[[ TBC API Extensions ]]--
+function UnitBuff(unitstr, i)
+ -- fake return values to be vanilla alike
+ local name, rank, icon, count = _G.UnitBuff(unitstr, i)
+ return icon, count
+end
+
+function UnitDebuff(unitstr, i)
+ -- fake return values to be vanilla alike
+ local name, rank, texture, stacks, dtype, duration, timeLeft = _G.UnitDebuff(unitstr, i)
+ return texture, stacks, dtype
+end
+
+-- the function GetContainerNumSlots returns numbers for keyrings in tbc
+function GetContainerNumSlots(bag)
+ if bag == -2 and pfUI.bag and not pfUI.bag.showKeyring then
+ return 0
+ else
+ return _G.GetContainerNumSlots(bag)
+ end
+end
+
+-- map libdebuff to the regular function
+libdebuff = {
+ ["UnitDebuff"] = function(self, a1, a2, a3)
+ return _G.UnitDebuff(a1,a2,a3)
+ end
+}
+
+-- map reveal positions
+pfMapOverlayData = {
+ ["Teldrassil"] = { "RUTTHERANVILLAGE:128:100:494:548", "STARBREEZEVILLAGE:200:200:561:292", "GNARLPINEHOLD:185:128:368:443", "LAKEALAMETH:256:185:436:380", "WELLSPRINGLAKE:180:256:377:93", "THEORACLEGLADE:170:240:272:127", "BANETHILHOLLOW:160:210:382:281", "DOLANAAR:190:128:462:323", "SHADOWGLEN:225:225:491:153", "POOLSOFARLITHRIEN:128:190:335:313", "DARNASSUS:315:256:101:247", },
+ ["Sunwell"] = { "SunsReachHarbor:512:416:252:252", "SunsReachSanctum:512:512:251:4", },
+ ["DunMorogh"] = { "AMBERSTILLRANCH:128:128:573:280", "FROSTMANEHOLD:125:125:217:287", "ICEFLOWLAKE:128:180:281:167", "THEGRIZZLEDDEN:200:185:314:311", "HELMSBEDLAKE:155:170:694:273", "SHIMMERRIDGE:128:190:347:163", "CHILLBREEZEVALLEY:180:128:274:296", "ANVILMAR:240:185:155:403", "MISTYPINEREFUGE:128:165:502:221", "GOLBOLARQUARRY:165:165:608:291", "KHARANOS:200:200:386:294", "THETUNDRIDHILLS:155:128:522:322", "IRONFORGE:315:200:397:163", "COLDRIDGEPASS:150:128:295:385", "NORTHERNGATEOUTPOST:128:165:759:173", "SOUTHERNGATEOUTPOST:128:120:792:279", "GNOMERAGON:180:165:166:184", "BREWNALLVILLAGE:115:115:252:249", },
+ ["Elwynn"] = { "EASTVALELOGGINGCAMP:256:210:704:330", "BRACKWELLPUMPKINPATCH:256:249:577:419", "FORESTSEDGE:256:341:124:327", "FARGODEEPMINE:256:240:238:428", "JERODSLANDING:256:237:425:431", "STORMWIND:485:405:0:0", "GOLDSHIRE:240:220:250:270", "TOWEROFAZORA:255:250:551:292", "CRYSTALLAKE:225:220:422:332", "RIDGEPOINTTOWER:306:233:696:435", "STONECAIRNLAKE:310:256:587:190", "NORTHSHIREVALLEY:256:256:381:147", },
+ ["Mulgore"] = { "WINTERHOOFWATERWELL:170:128:458:369", "THUNDERHORNWATERWELL:128:155:379:242", "RAVAGEDCARAVAN:128:120:473:260", "PALEMANEROCK:128:205:303:307", "WINDFURYRIDGE:205:128:395:0", "REDCLOUDMESA:470:243:270:425", "THUNDERBLUFF:280:240:249:59", "BAELDUNDIGSITE:210:180:255:214", "WILDMANEWATERWELL:185:128:291:0", "THEGOLDENPLAINS:215:240:428:80", "REDROCKS:205:230:502:16", "BLOODHOOFVILLAGE:256:200:367:303", "THEROLLINGPLAINS:256:190:523:356", "THEVENTURECOMINE:225:235:532:238", },
+ ["Tirisfal"] = { "SCARLETWATCHPOST:175:247:689:104", "SOLLIDENFARMSTEAD:256:156:239:250", "GARRENSHAUNT:174:220:497:145", "VENOMWEBVALE:237:214:757:205", "NIGHTMAREVALE:243:199:363:349", "AGAMANDMILLS:256:210:335:139", "CRUSADEROUTPOST:173:128:694:289", "DEATHKNELL:245:205:227:328", "BALNIRFARMSTEAD:216:179:630:326", "BRIGHTWATERLAKE:201:288:587:139", "BULWARK:230:205:698:362", "RUINSOFLORDAERON:315:235:463:361", "COLDHEARTHMANOR:150:128:474:327", "MONASTARY:211:189:746:125", "STILLWATERPOND:186:128:395:277", "BRILL:128:256:537:299", },
+ ["Durotar"] = { "RAZORMANEGROUNDS:230:230:301:189", "VALLEYOFTRIALS:215:215:355:320", "SKULLROCK:128:110:464:33", "DRYGULCHRAVINE:210:160:427:78", "THUNDERRIDGE:190:200:327:60", "ORGRIMMAR:445:160:244:0", "SENJINVILLAGE:160:190:474:384", "TIRAGARDEKEEP:190:180:462:286", "ECHOISLES:200:240:549:427", "RAZORHILL:220:230:432:170", "KOLKARCRAG:160:120:413:476", },
+ ["Westfall"] = { "WESTFALLLIGHTHOUSE:280:190:205:467", "FURLBROWSPUMPKINFARM:210:215:387:11", "JANGOLODEMINE:215:215:307:29", "SALDEANSFARM:225:210:459:105", "THEDUSTPLAINS:288:235:523:377", "SENTINELHILL:195:240:442:241", "DEMONTSPLACE:200:185:208:375", "THEMOLSENFARM:225:205:328:148", "THEDEADACRE:200:240:524:252", "THEJANSENSTEAD:165:200:488:0", "THEDAGGERHILLS:256:175:339:418", "GOLDCOASTQUARRY:225:256:220:102", "ALEXSTONFARMSTEAD:305:210:204:260", "MOONBROOK:220:200:317:331", },
+ ["Silverpine"] = { "THEDECREPITFERRY:180:185:457:144", "FENRISISLE:250:215:593:74", "THEDEADFIELD:175:165:402:65", "MALDENSORCHARD:256:160:465:0", "OLSENSFARTHING:165:185:382:252", "DEEPELEMMINE:160:170:470:261", "SHADOWFANGKEEP:220:160:364:359", "BERENSPERIL:240:180:491:417", "THESEPULCHER:210:160:352:168", "PYREWOODVILLAGE:140:125:391:446", "AMBERMILL:240:240:494:262", "THESKITTERINGDARK:185:165:286:37", "NORTHTIDESHOLLOW:180:128:323:128", "THEGREYMANEWALL:210:215:379:447", "THESHININGSTRAND:256:220:459:13", },
+ ["LochModan"] = { "SILVERSTREAMMINE:235:270:229:11", "MOGROSHSTRONGHOLD:315:235:542:48", "STONESPLINTERVALLEY:255:285:215:348", "IRONBANDSEXCAVATIONSITE:345:256:482:321", "VALLEYOFKINGS:195:250:109:370", "GRIZZLEPAWRIDGE:295:358:309:310", "THELSAMAR:256:230:217:203", "THELOCH:320:410:352:87", "NORTHGATEPASS:230:300:125:12", "STONEWROUGHTDAM:290:175:339:11", "THEFARSTRIDERLODGE:370:295:546:199", },
+ ["Darkshore"] = { "RUINSOFMATHYSTRA:195:215:510:0", "TOWEROFALTHALAXX:170:195:468:85", "GROVEOFTHEANCIENTS:200:170:305:412", "BASHALARAN:180:195:365:181", "AMETHARAN:190:205:324:306", "THEMASTERSGLAIVE:175:158:329:510", "REMTRAVELSEXCAVATION:175:183:229:485", "AUBERDINE:150:215:318:162", "CLIFFSPRINGRIVER:230:190:375:94", },
+ ["Redridge"] = { "STONEWATCH:255:300:500:215", "GALARDELLVALLEY:250:250:654:161", "ALTHERSMILL:235:270:399:129", "RENDERSVALLEY:465:255:484:361", "LAKEEVERSTILL:535:275:133:240", "REDRIDGECANYONS:365:245:121:72", "STONEWATCHFALLS:320:210:595:320", "LAKESHIRE:340:195:83:197", "RENDERSCAMP:275:256:277:0", "THREECORNERS:365:350:0:284", "LAKERIDGEHIGHWAY:430:290:187:333", },
+ ["Wetlands"] = { "ANGERFANGENCAMPMENT:225:185:347:218", "DUNMODR:205:180:401:21", "SUNDOWNMARSH:300:240:92:82", "THELGANROCK:230:190:470:371", "BLACKCHANNELMARSH:240:175:77:245", "BLUEGILLMARSH:225:190:89:142", "MOSSHIDEFEN:205:245:527:264", "IRONBEARDSTOMB:200:185:349:115", "THEGREENBELT:185:240:456:125", "SALTSPRAYGLEN:200:240:237:41", "MENETHILHARBOR:175:128:13:314", "GRIMBATOL:350:360:611:230", "RAPTORRIDGE:190:160:628:176", "DIREFORGEHILL:256:250:507:115", "WHELGARSEXCAVATIONSITE:195:185:247:205", },
+ ["Hilsbrad"] = { "DARROWHILL:205:155:414:154", "NETHANDERSTEAD:215:240:541:236", "DURNHOLDEKEEP:384:365:605:75", "SOUTHSHORE:235:270:418:201", "HILLSBRADFIELDS:305:275:198:155", "TARRENMILL:220:310:509:0", "AZURELOADMINE:165:200:175:275", "SOUTHPOINTTOWER:288:225:2:192", "DUNGAROK:240:275:637:294", "EASTERNSTRAND:230:320:524:339", "WESTERNSTRAND:285:155:208:368", "PURGATIONISLE:125:100:109:482", },
+ ["Duskwood"] = { "THEYORGENFARMSTEAD:235:250:390:382", "THEROTTINGORCHARD:250:230:539:369", "VULGOLOGREMOUND:255:285:243:348", "TWILIGHTGROVE:360:420:298:79", "ADDLESSTEAD:275:250:55:342", "MANORMISTMANTLE:200:175:653:120", "THEDARKENEDBANK:910:210:89:31", "RAVENHILL:195:145:102:302", "THEHUSHEDBANK:160:330:19:132", "DARKSHIRE:315:280:631:162", "BRIGHTWOODGROVE:220:340:504:117", "TRANQUILGARDENSCEMETARY:220:220:690:353", "RAVENHILLCEMETARY:350:300:85:149", },
+ ["Alterac"] = { "LORDAMEREINTERNMENTCAMP:330:265:44:403", "DANDREDSFOLD:285:230:276:0", "MISTYSHORE:220:280:196:131", "CHILLWINDPOINT:350:370:626:253", "GALLOWSCORNER:200:200:406:279", "CORRAHNSDAGGER:195:288:399:380", "CRUSHRIDGEHOLD:280:240:334:162", "THEUPLANDS:235:200:462:77", "GAVINSNAZE:160:175:225:478", "GROWLESSCAVE:190:170:317:372", "RUINSOFALTERAC:255:255:270:197", "STRAHNBRAD:370:300:549:105", "THEHEADLAND:165:197:314:471", "SOFERASNAZE:255:320:462:307", "DALARAN:300:300:26:262", },
+ ["Barrens"] = { "THEFORGOTTENPOOLS:120:125:384:115", "THESTAGNANTOASIS:155:128:481:211", "THEMORSHANRAMPART:128:100:412:0", "DREADMISTPEAK:128:105:419:63", "THEDRYHILLS:200:145:317:29", "BOULDERLODEMINE:120:110:555:0", "THESLUDGEFEN:170:120:456:0", "THECROSSROADS:155:155:431:118", "NORTHWATCHFOLD:150:120:527:307", "RAPTORGROUNDS:115:110:507:294", "THORNHILL:140:128:498:119", "THEMERCHANTCOAST:95:100:581:247", "LUSHWATEROASIS:175:185:365:177", "RATCHET:125:125:556:189", "HONORSSTAND:128:128:306:130", "BRAMBLESCAR:125:165:442:298", "BLACKTHORNRIDGE:155:128:335:462", "BAELMODAN:128:128:431:479", "RAZORFENKRAUL:128:128:341:537", "RAZORFENDOWNS:155:115:407:553", "CAMPTAURAJO:145:125:365:350", "GROLDOMFARM:125:115:492:63", "FARWATCHPOST:100:165:564:52", "AGAMAGOR:200:185:340:234", "FIELDOFGIANTS:210:150:355:402", },
+ ["Stranglethorn"] = { "NESINGWARYSEXPEDITION:140:110:269:26", "RUINSOFJUBUWAL:110:110:306:301", "ZIATAJAIRUINS:128:125:364:231", "BOOTYBAY:145:128:203:433", "NEKMANIWELLSPRING:90:115:211:359", "RUINSOFABORAZ:95:95:350:335", "CRYSTALVEINMINE:120:120:345:276", "MIZJAHRUINS:105:110:311:131", "WILDSHORE:165:190:229:422", "BLOODSAILCOMPOUND:165:175:194:284", "JAGUEROISLE:125:120:314:493", "GROMGOLBASECAMP:110:105:260:132", "MOSHOGGOGREMOUND:128:175:432:94", "KALAIRUINS:95:95:299:88", "RUINSOFZULMAMWE:170:125:394:212", "MISTVALEVALLEY:125:125:280:368", "THEARENA:200:185:235:189", "ZUULDAIARUINS:115:115:156:42", "BALIAMAHRUINS:110:140:371:129", "LAKENAZFERITI:128:125:331:59", "KURZENSCOMPOUND:155:150:388:0", "RUINSOFZULKUNDA:125:140:196:3", "ZULGURUB:245:220:483:8", "THEVILEREEF:190:175:152:90", "VENTURECOBASECAMP:105:125:387:64", "BALALRUINS:90:80:241:92", "REBELCAMP:170:90:284:0", },
+ ["SwampOfSorrows"] = { "SPLINTERSPEARJUNCTION:275:240:129:236", "THEHARBORAGE:235:205:171:145", "FALLOWSANCTUARY:365:305:492:0", "MISTYREEDSTRAND:256:668:746:0", "POOLOFTEARS:300:275:565:218", "THESHIFTINGMIRE:315:235:286:110", "MISTYVALLEY:245:305:0:140", "ITHARIUSSCAVE:240:245:0:262", "STONARD:360:315:279:237", "STAGALBOG:345:250:552:378", "SORROWMURK:215:365:724:120", },
+ ["Arathi"] = { "CIRCLEOFINNERBINDING:210:185:286:310", "CIRCLEOFOUTERBINDING:170:155:419:293", "NORTHFOLDMANOR:230:240:192:90", "BOULDERGOR:245:245:232:145", "STROMGARDEKEEP:240:230:108:287", "FALDIRSCOVE:256:215:171:424", "THANDOLSPAN:200:220:355:412", "BOULDERFISTHALL:215:235:432:362", "GOSHEKFARM:230:195:531:276", "HAMMERFALL:205:250:655:120", "WITHERBARKVILLAGE:215:210:559:333", "DABYRIESFARMSTEAD:180:210:472:165", "CIRCLEOFEASTBINDING:160:230:558:112", "REFUGEPOINT:175:225:370:186", "THORADINSWALL:190:240:87:138", "CIRCLEOFWESTBINDING:190:210:138:54", },
+ ["Badlands"] = { "CAMPKOSH:220:220:551:48", "LETHLORRAVINE:370:455:611:110", "AGMONDSEND:265:270:345:389", "CAMPBOFF:255:280:501:341", "THEDUSTBOWL:270:275:159:199", "HAMMERTOESDIGSITE:200:195:445:120", "VALLEYOFFANGS:230:230:349:256", "ANGORFORTRESS:195:200:325:148", "DUSTWINDGULCH:245:205:498:209", "THEMAKERSTERRACE:245:205:389:7", "CAMPCAGG:256:256:12:428", "KARGATH:256:256:0:148", "APOCRYPHANSREST:256:256:17:310", "MIRAGEFLATS:256:256:148:384", },
+ ["Hinterlands"] = { "JINTHAALOR:235:285:505:333", "THEOVERLOOKCLIFFS:170:310:693:303", "AERIEPEAK:255:205:13:245", "PLAGUEMISTRAVINE:145:220:158:149", "THEALTAROFZUL:200:165:373:365", "HIRIWATHA:225:200:171:306", "QUELDANILLODGE:185:195:237:185", "VALORWINDLAKE:170:170:319:302", "SHADRAALOR:195:185:240:387", "AGOLWATHA:205:195:374:164", "THECREEPINGRUIN:180:170:408:260", "SERADANE:275:275:509:19", "SKULKROCK:160:145:512:232", "SHAOLWATHA:280:205:571:239", },
+ ["UngoroCrater"] = { "GOLAKKAHOTSPRINGS:315:345:121:151", "THESLITHERINGSCAR:345:285:367:380", "FIREPLUMERIDGE:295:270:367:178", "TERRORRUN:345:285:158:368", "THEMARSHLANDS:310:355:560:240", "IRONSTONEPLATEAU:285:285:582:67", "LAKKARITARPITS:570:265:160:6", },
+ ["Tanaris"] = { "THISTLESHRUBVALLEY:185:250:203:286", "VALLEYOFTHEWATCHERS:150:160:291:434", "LANDSENDBEACH:205:157:445:511", "ABYSSALSANDS:215:180:363:194", "ZALASHJISDEN:110:140:611:147", "CAVERNSOFTIME:155:150:561:256", "EASTMOONRUINS:160:150:395:346", "GADGETZAN:175:165:421:91", "BROKENPILLAR:110:180:473:234", "SOUTHMOONRUINS:195:210:323:359", "ZULFARRAK:210:175:254:0", "THEGAPINGCHASM:220:210:449:372", "SOUTHBREAKSHORE:215:175:499:293", "DUNEMAULCOMPOUND:205:145:325:289", "THENOXIOUSLAIR:180:200:252:199", "WATERSPRINGFIELD:165:180:509:168", "LOSTRIGGERCOVE:160:190:629:220", "STEAMWHEEDLEPORT:155:150:592:75", "NOONSHADERUINS:120:135:533:104", "SANDSORROWWATCH:195:175:299:100", },
+ ["Dustwallow"] = { "THEWYRMBOG:285:240:367:381", "ALCAZISLAND:200:195:660:21", "THERAMOREISLE:230:205:534:224", "WITCHHILL:250:315:422:0", "BRACKENWALLVILLAGE:280:270:230:0", "BACKBAYWETLANDS:400:255:239:189", "THEDENOFFLAME:255:250:257:313", },
+ ["ThousandNeedles"] = { "THEGREATLIFT:210:180:205:70", "DARKCLOUDPINNACLE:205:195:259:131", "THESHIMMERINGFLATS:320:365:610:300", "SPLITHOOFCRAG:210:195:391:192", "CAMPETHOK:305:310:0:0", "WINDBREAKCANYON:240:220:492:250", "FREEWINDPOST:210:190:357:264", "HIGHPERCH:190:190:31:155", "THESCREECHINGCANYON:250:240:179:200", },
+ ["SearingGorge"] = { "GRIMSILTDIGSITE:305:220:494:300", "THESEAOFCINDERS:360:280:247:388", "TANNERCAMP:305:230:545:407", "DUSTFIREVALLEY:460:365:422:8", "FIREWATCHRIDGE:405:430:85:30", "THECAULDRON:425:325:250:170", "BLACKCHARCAVE:275:235:77:366", },
+ ["Ashenvale"] = { "THISTLEFURVILLAGE:255:195:203:158", "THESHRINEOFAESSINA:220:195:104:259", "THEZORAMSTRAND:245:245:19:28", "LAKEFALATHIM:128:195:131:137", "MAESTRASPOST:215:305:205:38", "ASTRANAAR:205:185:272:251", "IRISLAKE:200:205:392:218", "THERUINSOFSTARDUST:155:150:260:373", "FIRESCARSHRINE:165:175:189:324", "MYSTRALLAKE:275:240:356:347", "BOUGHSHADOW:146:200:856:151", "THEHOWLINGVALE:210:185:463:141", "FELFIREHILL:245:255:713:344", "NIGHTRUN:225:255:597:258", "WARSONGLUMBERCAMP:200:160:796:311", "RAYNEWOODRETREAT:180:245:520:238", "FALLENSKYLAKE:235:205:547:426", "SATYRNAAR:285:185:694:225", },
+ ["Desolace"] = { "SHADOWPREYVILLAGE:230:230:167:389", "THUNDERAXEFORTRESS:190:220:447:102", "ETHELRETHOR:205:250:311:61", "GELKISVILLAGE:195:242:293:426", "VALLEYOFSPEARS:245:285:212:215", "RANAZJARISLE:100:100:241:6", "MAGRAMVILLAGE:205:285:590:365", "MANNOROCCOVEN:285:280:399:380", "SARGERON:285:245:625:33", "KOLKARVILLAGE:220:220:607:215", "KORMEKSHUT:170:160:555:181", "SHADOWBREAKRAVINE:205:195:690:444", "KODOGRAVEYARD:275:250:387:244", "NIJELSPOINT:200:250:554:0", "TETHRISARAN:205:145:431:0", },
+ ["BurningSteppes"] = { "DRACODAR:415:315:56:258", "RUINSOFTHAURISSAN:270:285:513:99", "DREADMAULROCK:220:225:707:168", "MORGANSVIGIL:294:270:708:311", "ALTAROFSTORMS:225:220:36:109", "TERRORWINGPATH:280:355:722:46", "BLACKROCKPASS:270:310:589:279", "PILLAROFASH:320:270:377:285", "BLACKROCKSTRONGHOLD:245:265:334:114", "BLACKROCKMOUNTAIN:256:280:173:101", },
+ ["BlastedLands"] = { "DREADMAULPOST:245:195:361:195", "THETAINTEDSCAR:384:450:212:178", "DREADMAULHOLD:195:180:361:15", "GARRISONARMORY:170:200:472:9", "ALTAROFSTORMS:185:155:310:133", "SERPENTSCOIL:225:170:501:140", "DARKPORTAL:265:220:453:259", "NETHERGARDEKEEP:185:190:559:30", "RISEOFTHEDEFILER:170:145:405:123", },
+ ["Aszhara"] = { "SHADOWSONGSHRINE:225:180:35:422", "TIMBERMAWHOLD:235:270:250:106", "BAYOFSTORMS:270:300:479:201", "THESHATTEREDSTRAND:160:210:404:194", "JAGGEDREEF:570:170:366:0", "BITTERREACHES:245:185:644:40", "TOWEROFELDARA:120:155:818:107", "FORLORNRIDGE:220:255:191:369", "TEMPLEOFARKKORAN:190:200:681:153", "LEGASHENCAMPMENT:235:140:478:44", "URSOLAN:145:215:422:95", "RUINSOFELDARATH:265:280:238:221", "SOUTHRIDGEBEACH:370:220:389:353", "VALORMOK:215:175:84:229", "THALASSIANBASECAMP:240:155:499:119", "RAVENCRESTMONUMENT:240:125:552:499", "HALDARRENCAMPMENT:200:150:77:331", "THERUINEDREACHES:395:128:396:540", "LAKEMENNAR:315:200:296:429", },
+ ["Felwood"] = { "RUINSOFCONSTELLAS:235:155:297:381", "EMERALDSANCTUARY:185:160:405:429", "FELPAWVILLAGE:240:145:483:0", "TALONBRANCHGLADE:160:145:548:90", "MORLOSARAN:145:159:496:509", "JADEFIRERUN:195:170:330:29", "SHATTERSCARVALE:235:200:307:123", "JAEDENAR:245:128:271:331", "BLOODVENOMFALLS:235:145:292:263", "DEADWOODVILLAGE:175:135:408:533", "JADEFIREGLEN:165:155:332:465", "IRONTREEWOODS:215:215:420:54", },
+ ["EasternPlaguelands"] = { "THENOXIOUSGLADE:225:215:722:166", "QUELLITHIENLODGE:230:150:422:36", "NORTHPASSTOWER:240:195:457:109", "TERRORDALE:190:205:79:98", "BLACKWOODLAKE:230:235:442:199", "EASTWALLTOWER:180:160:592:241", "DARROWSHIRE:210:179:309:489", "CORINSCROSSING:165:160:537:367", "THEMARRISSTEAD:200:205:156:360", "NORTHDALE:190:205:620:128", "PLAGUEWOOD:360:270:169:83", "LAKEMERELDAR:250:175:537:463", "THEINFECTISSCAR:195:275:620:291", "PESTILENTSCAR:205:250:409:345", "ZULMASHAR:205:165:614:30", "CROWNGUARDTOWER:205:165:291:401", "THONDRORILRIVER:220:360:7:231", "LIGHTSHOPECHAPEL:175:245:716:299", "TYRSHAND:245:170:717:471", "STRATHOLME:240:200:194:9", "THEFUNGALVALE:210:210:271:261", "THEUNDERCROFT:185:150:172:477", },
+ ["StonetalonMountains"] = { "BOULDERSLIDERAVINE:145:107:572:561", "WEBWINDERPATH:288:355:457:282", "MIRKFALLONLAKE:200:215:390:145", "CAMPAPARAJE:190:97:718:571", "SISHIRCANYON:125:125:475:433", "STONETALONPEAK:270:205:247:0", "GRIMTOTEMPOST:225:120:668:515", "MALAKAJIN:125:86:663:582", "WINDSHEARCRAG:320:275:553:197", "THECHARREDVALE:230:355:210:234", "SUNROCKRETREAT:150:150:389:320", },
+ ["WesternPlaguelands"] = { "DARROWMERELAKE:370:270:504:343", "RUINSOFANDORHOL:285:230:260:355", "THEBULWARK:225:185:137:293", "FELSTONEFIELD:160:125:300:311", "THEWEEPINGCAVE:160:200:566:198", "CAERDARROW:170:165:600:412", "SORROWHILL:300:206:355:462", "GAHRRONSWITHERING:180:205:520:250", "HEARTHGLEN:340:288:307:16", "DALSONSTEARS:220:150:381:265", "THEWRITHINGHAUNT:170:190:451:323", "NORTHRIDGELUMBERCAMP:220:180:382:164", "THONDRORILRIVER:205:340:590:86", },
+ ["Feralas"] = { "THEFORGOTTENCOAST:145:320:404:256", "FRAYFEATHERHIGHLANDS:110:170:478:386", "RUINSOFRAVENWIND:190:155:305:0", "THETWINCOLOSSALS:285:245:319:75", "DREAMBOUGH:150:125:454:0", "GORDUNNIOUTPOST:140:165:690:141", "ISLEOFDREAD:215:293:192:375", "LOWERWILDS:225:180:751:198", "FERALSCARVALE:115:115:486:329", "RUINSOFISILDIEN:190:250:540:320", "ONEIROS:110:110:493:70", "DIREMAUL:230:195:454:201", "SARDORISLE:180:180:208:234", "CAMPMOJACHE:155:160:689:233", "THEWRITHINGDEEP:240:220:618:298", "GRIMTOTEMCOMPOUND:120:195:623:167", },
+ ["Winterspring"] = { "WINTERFALLVILLAGE:145:125:617:158", "ICETHISTLEHILLS:125:165:611:242", "LAKEKELTHERIL:215:185:401:198", "STARFALLVILLAGE:185:160:392:137", "EVERLOOK:165:200:509:107", "FROSTFIREHOTSPRINGS:240:140:222:172", "FROSTWHISPERGORGE:200:160:523:376", "THEHIDDENGROVE:175:185:555:27", "DARKWHISPERGORGE:255:205:447:441", "FROSTSABERROCK:250:180:368:7", "OWLWINGTHICKET:165:140:593:340", "TIMBERMAWPOST:230:120:229:243", "MAZTHORIL:185:180:493:258", },
+ ["Silithus"] = { "THESCARABWALL:288:256:116:413", "THECRYSTALVALE:320:289:104:24", "HIVEASHI:512:320:265:12", "SOUTHWINDVILLAGE:384:384:500:65", "TWILIGHTBASECAMP:320:256:344:197", "HIVEZORA:384:512:97:144", "HIVEREGAL:512:384:245:285", },
+ ["DeadwindPass"] = { "THEVICE:270:270:426:299", "KARAZHAN:300:245:269:337", "DEADMANSCROSSING:380:365:249:76", },
+ ["AlteracValley"] = { "DUNBALDAR:270:240:348:13", "ICEBLOODGARRISON:300:300:335:172", "FROSTWOLFKEEP:235:290:399:375", },
+ ["Moonglade"] = { "LAKEELUNEARA:555:510:244:89", },
+ ["Hellfire"] = { "TheLegionFront:256:512:579:128", "RuinsofShanaar:256:378:25:290", "HellfireCitadel:256:458:338:210", "FallenSkyRidge:256:256:34:142", "ExpeditionArmory:512:255:261:413", "Thrallmar:256:256:467:154", "MagharPost:256:256:206:110", "DenofHaalesh:256:256:182:412", "TempleofTelhamat:512:512:38:152", "PoolsofAggonar:256:512:326:45", "ForgeCampRage:512:512:478:25", "ThroneofKiljaeden:512:256:477:6", "ZethGor:422:238:580:430", "TheStairofDestiny:256:512:737:156", "VoidRidge:256:256:705:368", "WarpFields:256:260:308:408", "FalconWatch:512:342:183:326", "HonorHold:256:256:469:298", },
+ ["Zangarmarsh"] = { "TheLagoon:256:256:512:303", "FeralfenVillage:512:336:314:332", "OreborHarborage:256:512:329:25", "TheDeadMire:286:512:716:128", "CoilfangReservoir:256:512:462:90", "Sporeggar:512:256:20:202", "MarshlightLake:256:256:81:152", "QuaggRidge:256:343:141:325", "ZabraJin:256:256:175:232", "TheHewnBog:256:512:219:51", "UmbrafenVillage:256:207:720:461", "Telredor:256:512:569:112", "AngoroshStronghold:256:128:124:0", "CenarionRefuge:308:256:694:321", "BloodscaleEnclave:256:256:596:412", "TwinspireRuins:256:256:342:249", "AngoroshGrounds:256:256:88:50", "TheSpawningGlen:256:256:31:339", },
+ ["Nagrand"] = { "WindyreedPass:256:256:598:79", "Telaar:256:256:387:390", "BurningBladeRUins:256:334:660:334", "Halaa:256:256:335:193", "WarmaulHill:256:256:157:32", "SunspringPost:256:256:219:199", "TwilightRidge:256:512:10:107", "SouthwindCleft:256:256:391:258", "KilsorrowFortress:256:241:558:427", "LaughingSkullRuins:256:256:351:52", "OshuGun:512:334:168:334", "ThroneoftheElements:256:256:504:53", "ClanWatch:256:256:532:363", "RingofTrials:256:256:533:267", "ForgeCampHate:256:256:162:154", "ZangarRidge:256:256:277:54", "ForgeCampFear:512:420:36:248", "WindyreedVillage:256:256:666:233", "Garadar:256:256:431:143", },
+ ["TerokkarForest"] = { "RaastokGlade:256:256:505:154", "ShattrathCity:512:512:104:4", "BleedingHollowClanRuins:256:367:103:301", "CarrionHill:256:256:377:272", "SethekkTomb:256:256:245:289", "RazorthornShelf:256:256:478:19", "GrangolvarVilliage:512:256:143:171", "Tuurem:256:512:455:34", "TheBarrierHills:256:256:116:4", "StonebreakerHold:256:256:397:165", "CenarionThicket:256:256:314:0", "FirewingPoint:385:512:617:149", "AllerianStronghold:256:256:480:277", "BonechewerRuins:256:256:521:275", "SkethylMountains:512:320:449:348", "RingofObservance:256:256:310:345", "WrithingMound:256:256:417:327", "VeilRhaze:256:256:222:362", "AuchenaiGrounds:256:234:247:434", "SmolderingCaravan:256:208:321:460", "RefugeCaravan:128:256:316:268", "TheBoneWastes:512:400:224:268", -- Seems to have been replaced by separate regions...
+ },
+ ["ShadowmoonValley"] = { "NetherwingLedge:492:223:510:445", "WildhammerStronghold:512:439:168:229", "LegionHold:512:512:104:155", "TheWardensCage:512:410:469:258", "IlladarPoint:256:256:143:256", "ShadowmoonVilliage:512:512:116:35", "TheHandofGuldan:512:512:394:90", "CoilskarPoint:512:512:348:8", "NetherwingCliffs:256:256:554:308", "TheBlackTemple:396:512:606:126", "AltarofShatar:256:256:520:93", "TheDeathForge:256:512:290:129", "EclipsePoint:512:358:343:310", },
+ ["BladesEdgeMountains"] = { "VeilRuuan:256:128:563:151", "VortexPinnacle:256:462:166:206", "BladedGulch:256:256:623:147", "Grishnath:256:256:286:28", "BrokenWilds:256:256:733:109", "ThunderlordStronghold:256:396:405:272", "RuuanWeald:256:512:479:98", "BloodmaulOutpost:256:297:342:371", "VeilLashh:256:240:271:428", "RavensWood:512:256:214:55", "MokNathalVillage:256:256:658:297", "Skald:256:256:673:71", "JaggedRidge:256:254:446:414", "BladesipreHold:256:507:314:161", "DeathsDoor:256:419:512:249", "GruulsLayer:256:256:527:81", "ForgeCampAnger:416:256:586:147", "BloodmaulCamp:256:256:412:95", "ForgeCampTerror:512:252:144:416", "ForgeCampWrath:256:256:254:176", "VekhaarStand:256:256:629:406", "Sylvanaar:256:318:289:350", "BashirLanding:256:256:422:0", "CircleofWrath:256:256:439:210", "RazorRidge:256:336:533:332", "RidgeofMadness:256:410:554:258", "TheCrystalpine:256:256:585:0", },
+ ["Netherstorm"] = { "ManaforgeBanar:256:387:147:281", "RuinedManaforge:256:256:513:138", "SunfuryHold:256:217:454:451", "ManafrogeAra:256:256:171:155", "SocretharsSeat:256:256:229:38", "EtheriumStagingGrounds:256:256:481:208", "TempestKeep:409:384:593:284", "ManaforgeDuro:256:256:465:336", "TheScrapField:256:256:356:261", "CelestialRidge:256:256:644:173", "TheStormspire:256:256:298:134", "Area52:256:128:241:388", "ArklonRuins:256:256:328:397", "RuinsofEnkaat:256:256:253:301", "ManaforgeCoruu:256:179:357:489", "Netherstone:256:256:411:20", "KirinVarVillage:256:145:490:523", "ForgeBaseOG:256:256:237:22", "RuinsofFarahlon:512:256:354:49", "EcoDomeFarfield:256:256:396:10", "TheHeap:256:213:239:455", "NetherstormBridge:256:256:132:294", },
+ ["Ghostlands"] = { "ThalassiaPass:256:262:364:406", "ZebNowa:512:431:466:237", "AmaniPass:404:436:598:232", "SanctumoftheSun:256:512:448:150", "Deatholme:512:293:95:375", "BleedingZiggurat:256:256:184:238", "WindrunnerVillage:256:512:60:117", "WindrunnerSpire:256:256:40:287", "HowlingZiggurat:256:449:340:219", "SanctumoftheMoon:256:256:210:126", "GoldenmistVillage:512:512:44:0", "Tranquillien:256:512:365:2", "ElrendarCrossing:512:256:326:0", "SuncrownVillage:512:256:460:0", "DawnstarSpire:427:256:575:0", "FarstriderEnclave:429:256:573:136", "IsleofTribulations:256:256:585:0", },
+ ["EversongWoods"] = { "SunstriderIsle:512:512:195:5", "TorWatha:256:353:648:315", "RunestoneFalithas:256:172:378:496", "TheScortchedGrove:256:128:255:507", "TheGoldenStrand:128:253:183:415", "SunsailAnchorage:256:128:231:404", "GoldenboughPass:256:128:243:469", "SatherilsHaven:256:256:324:384", "FairbreezeVilliage:256:256:386:386", "TheLivingWood:128:248:511:420", "RunestoneShandor:256:174:464:494", "Zebwatha:128:193:554:475", "LakeElrendar:128:197:584:471", "ElrendarFalls:128:256:580:399", "EastSanctum:256:256:460:373", "FarstriderRetreat:256:128:524:359", "SilvermoonCity:512:512:440:87", "StillwhisperPond:256:256:474:314", "ThuronsLivery:256:128:539:305", "NorthSanctum:256:256:361:298", "WestSanctum:128:256:292:319", "TranquilShore:256:256:215:298", "RuinsofSilvermoon:256:256:307:136", "DuskwitherGrounds:256:256:605:253", },
+ ["AzuremystIsle"] = { "AmmenVale:475:512:527:104", "AmmenFord:256:256:515:279", "MoongrazeWoods:256:256:449:183", "Emberglade:256:256:488:24", "FairbridgeStrand:256:128:356:0", "ValaarsBerth:256:256:176:303", "BristlelimbVillage:256:256:174:363", "WrathscalePoint:256:247:220:421", "SilvermystIsle:256:222:23:446", "OdesyusLanding:256:256:352:378", "GreezlesCamp:256:256:507:350", "PodWreckage:128:256:462:349", "AzureWatch:256:256:383:249", "PodCluster:256:256:281:305", "TheExodar:512:512:74:85", "StillpineHold:256:256:365:49", "SiltingShore:256:256:291:3", },
+ ["BloodmystIsle"] = { "KesselsCrossing:485:141:517:527", "TheCrimsonReach:256:256:555:87", "BristlelimbEnclave:256:256:546:410", "WrathscaleLair:256:256:598:338", "RuinsofLorethAran:256:256:556:216", "WyrmscarIsland:256:256:613:82", "BloodscaleIsle:239:256:763:256", -- "BloodcurseIsle:239:256:763:256", replaced by BloodscaleIsle in the data
+ "VeridianPoint:256:256:637:0", "TalonStand:256:256:657:78", "RagefeatherRidge:256:256:481:117", "Bladewood:256:256:367:209", "TheWarpPiston:256:256:451:29", "TheBloodwash:256:256:302:27", "Axxarien:256:256:297:136", "TheFoulPool:256:256:221:136", "AmberwebPass:256:512:44:62", "TheVectorCoil:512:430:43:238", "VindicatorsRest:256:256:232:242", "BlacksiltShore:512:242:177:426", "Nazzivian:256:256:250:404", "Mystwood:256:185:309:483", "TheLostFold:256:198:503:470", "BloodWatch:256:256:437:258", "TheCryoCore:256:256:293:285", "Middenvale:256:256:414:406", "TelathionsCamp:128:128:180:216", }}
+
+-- patch pfSellData table for TBC
+local pfSellData_tbc = {
+ [25]="7,36", [35]="9,48", [37]="7,39", [40]="1,5", [43]="1,5", [47]="1,5",
+ [79]="10,53", [80]="7,36", [85]="12,63", [121]="1,5", [140]="1,5", [193]="9,49",
+ [195]="7,37", [202]="343,1715", [209]="12,61", [237]="561,2806", [287]="488,2442", [710]="72,362",
+ [711]="5,26", [719]="4,24", [720]="1070,5351", [727]="245,1225", [753]="3842,19212", [756]="4963,24819",
+ [763]="58,294", [766]="57,287", [776]="5765,28827", [791]="7069,35348", [792]="41,208", [794]="56,280",
+ [795]="56,281", [797]="35,177", [798]="71,355", [799]="71,356", [816]="305,1528", [820]="947,4739",
+ [826]="732,3662", [827]="971,4859", [837]="225,1125", [838]="225,1129", [844]="144,721", [849]="265,1327",
+ [854]="604,3023", [864]="9716,48581", [868]="21533,107665", [871]="29628,148140", [872]="2414,12070", [885]="2301,11505",
+ [890]="3517,17589", [892]="370,1850", [897]="1022,5113", [899]="1248,6242", [914]="2669,13348", [920]="2821,14107",
+ [922]="2407,12039", [923]="1748,8744", [924]="2194,10973", [926]="1957,9785", [927]="1390,6954", [934]="10682,53412",
+ [935]="1742,8713", [937]="14577,72886", [944]="80153,400765", [1008]="144,721", [1010]="99,499", [1155]="5954,29771",
+ [1158]="146,732", [1161]="25,129", [1190]="418,2091", [1197]="533,2667", [1198]="535,2677", [1211]="347,1739",
+ [1213]="87,438", [1214]="930,4652", [1251]="8,34", [1263]="79064,395324", [1265]="11775,58875", [1273]="1656,8283",
+ [1275]="1668,8343", [1280]="3696,18482", [1296]="1681,8409", [1297]="2038,10194", [1299]="390,1954", [1300]="1854,9271",
+ [1304]="279,1399", [1306]="352,1762", [1310]="715,3577", [1351]="768,3844", [1355]="201,1008", [1359]="19,96",
+ [1366]="2,12", [1374]="3,17", [1376]="4,24", [1377]="1,7", [1382]="24,123", [1383]="25,127",
+ [1388]="14,72", [1389]="58,292", [1405]="1184,5924", [1406]="2079,10399", [1413]="55,277", [1423]="19,95",
+ [1427]="29,148", [1429]="7,39", [1430]="7,39", [1431]="20,102", [1433]="14,73", [1436]="458,2291",
+ [1440]="1230,6152", [1445]="584,2920", [1448]="405,2028", [1465]="9825,49125", [1479]="47,239", [1480]="954,4774",
+ [1481]="3337,16689", [1484]="2922,14613", [1486]="1202,6013", [1489]="1553,7768", [1495]="59,295", [1497]="71,357",
+ [1498]="57,286", [1503]="109,547", [1506]="51,256", [1511]="194,970", [1513]="293,1466", [1514]="294,1471",
+ [1521]="19205,96028", [1557]="919,4595", [1560]="513,2569", [1561]="268,1344", [1604]="19464,97320", [1608]="18940,94704",
+ [1659]="2136,10683", [1664]="14695,73476", [1716]="5067,25336", [1717]="3108,15541", [1718]="8040,40203", [1726]="12183,60916",
+ [1728]="72936,364684", [1730]="48,244", [1733]="88,444", [1734]="39,198", [1742]="129,649", [1743]="299,1498",
+ [1744]="260,1303", [1749]="263,1316", [1750]="298,1492", [1754]="359,1797", [1756]="438,2191", [1757]="483,2418",
+ [1759]="732,3662", [1767]="101,506", [1768]="217,1086", [1769]="163,817", [1772]="247,1236", [1774]="281,1407",
+ [1782]="542,2710", [1785]="464,2323", [1787]="102,511", [1788]="177,885", [1789]="136,681", [1791]="90,451",
+ [1792]="208,1042", [1794]="277,1388", [1796]="400,2002", [1798]="223,1118", [1799]="211,1057", [1800]="479,2398",
+ [1806]="466,2331", [1807]="388,1940", [1811]="451,2256", [1812]="453,2265", [1813]="523,2615", [1816]="486,2433",
+ [1819]="768,3841", [1820]="963,4819", [1826]="1765,8829", [1828]="1609,8047", [1832]="362,1812", [1839]="37,185",
+ [1843]="145,726", [1846]="176,881", [1913]="148,743", [1925]="787,3939", [1928]="996,4980", [1929]="434,2172",
+ [1930]="327,1635", [1936]="1114,5570", [1937]="2040,10202", [1943]="713,3567", [1944]="259,1297", [1945]="267,1338",
+ [1951]="1258,6291", [1958]="975,4877", [1959]="1223,6118", [1978]="981,4905", [1979]="23274,116370", [1988]="2852,14261",
+ [1997]="2539,12695", [2011]="3840,19201", [2013]="3644,18223", [2014]="4869,24347", [2020]="1050,5250", [2024]="1215,6079",
+ [2025]="1061,5305", [2027]="763,3816", [2029]="884,4420", [2030]="1109,5545", [2033]="967,4837", [2036]="258,1292",
+ [2037]="469,2346", [2042]="3639,18196", [2044]="8829,44146", [2047]="26,130", [2048]="26,130", [2064]="191,959",
+ [2066]="81,408", [2067]="186,932", [2069]="122,610", [2073]="742,3714", [2074]="1054,5272", [2075]="386,1933",
+ [2077]="5059,25296", [2078]="1070,5351", [2079]="934,4670", [2084]="5709,28548", [2089]="1113,5568", [2092]="7,36",
+ [2098]="3021,15105", [2100]="24540,122700", [2109]="14,73", [2110]="6,32", [2114]="31,156", [2117]="7,37",
+ [2119]="5,25", [2123]="9,49", [2124]="6,33", [2125]="6,33", [2126]="12,60", [2133]="16,79",
+ [2137]="25,125", [2138]="38,193", [2141]="1044,5224", [2142]="524,2621", [2143]="789,3945", [2145]="529,2649",
+ [2148]="581,2908", [2149]="879,4398", [2153]="1185,5928", [2156]="615,3078", [2164]="27032,135160", [2166]="811,4055",
+ [2167]="339,1696", [2169]="1887,9435", [2172]="7,37", [2194]="3276,16384", [2203]="1492,7464", [2207]="478,2391",
+ [2208]="730,3651", [2209]="1423,7116", [2215]="81,406", [2217]="243,1217", [2218]="501,2506", [2219]="457,2289",
+ [2221]="910,4551", [2225]="183,917", [2226]="4118,20590", [2227]="4133,20668", [2230]="714,3571", [2232]="813,4065",
+ [2235]="1281,6407", [2237]="75,378", [2240]="121,607", [2241]="408,2043", [2243]="65783,328917", [2244]="51858,259290",
+ [2249]="91,458", [2257]="189,945", [2258]="83,417", [2264]="1957,9789", [2265]="477,2388", [2278]="2326,11634",
+ [2280]="4828,24141", [2282]="139,697", [2283]="140,701", [2292]="1334,6674", [2299]="8757,43785", [2303]="71,359",
+ [2307]="243,1217", [2308]="214,1071", [2310]="89,449", [2315]="307,1539", [2316]="326,1634", [2361]="9,46",
+ [2367]="44,224", [2370]="75,378", [2372]="68,344", [2375]="34,174", [2376]="89,448", [2379]="15,76",
+ [2380]="7,38", [2381]="15,76", [2383]="11,58", [2384]="7,38", [2385]="7,38", [2386]="15,78",
+ [2387]="7,39", [2388]="15,78", [2390]="7,39", [2391]="7,39", [2393]="41,207", [2395]="64,323",
+ [2397]="43,216", [2399]="43,218", [2401]="66,331", [2402]="44,220", [2403]="44,221", [2418]="3146,15732",
+ [2419]="1579,7895", [2420]="2387,11938", [2426]="6513,32569", [2429]="2027,10139", [2432]="1538,7691", [2434]="1033,5166",
+ [2437]="5578,27891", [2448]="3231,16159", [2464]="1374,6872", [2468]="1262,6311", [2469]="1267,6335", [2471]="3408,17041",
+ [2472]="6842,34212", [2479]="21,108", [2489]="68,343", [2492]="57,285", [2494]="80,402", [2495]="101,505",
+ [2499]="143,717", [2507]="350,1752", [2520]="4925,24629", [2523]="5657,28286", [2525]="5298,26490", [2529]="13006,65032",
+ [2530]="10444,52220", [2531]="11234,56170", [2533]="12221,61108", [2535]="12311,61557", [2545]="1797,8985", [2546]="55,277",
+ [2547]="7,37", [2568]="31,157", [2569]="87,438", [2570]="11,56", [2571]="17,85", [2572]="99,497",
+ [2582]="216,1083", [2583]="359,1797", [2585]="638,3194", [2586]="1,7", [2613]="121,608", [2614]="232,1162",
+ [2615]="1018,5092", [2616]="532,2660", [2617]="2198,10992", [2618]="5328,26640", [2621]="2357,11788", [2623]="3554,17773",
+ [2644]="7,37", [2645]="11,57", [2646]="32,160", [2648]="58,294", [2650]="3,17", [2651]="3,17",
+ [2652]="4,24", [2653]="3,16", [2656]="9,49", [2690]="7,39", [2694]="539,2698", [2764]="440,2203",
+ [2765]="811,4058", [2773]="39,196", [2777]="147,735", [2778]="147,738", [2780]="374,1873", [2781]="335,1677",
+ [2785]="1062,5312", [2786]="1173,5866", [2787]="10,54", [2801]="90978,454890", [2805]="1882,9410", [2815]="19778,98891",
+ [2816]="7324,36621", [2818]="363,1818", [2819]="3830,19153", [2821]="1118,5590", [2822]="1402,7013", [2845]="109,547",
+ [2849]="1269,6346", [2851]="56,283", [2852]="67,336", [2853]="17,86", [2854]="225,1128", [2864]="630,3151",
+ [2866]="753,3765", [2868]="807,4036", [2870]="2935,14678", [2903]="515,2579", [2905]="42,213", [2908]="1409,7049",
+ [2910]="1257,6287", [2912]="6731,33657", [2913]="1153,5767", [2916]="4405,22029", [2931]="250,1000", [2942]="3663,18317",
+ [2953]="1857,9286", [2957]="119,597", [2958]="94,474", [2960]="22,110", [2962]="120,601", [2966]="146,732",
+ [2967]="66,332", [2968]="34,170", [2971]="109,545", [2973]="484,2421", [2974]="392,1963", [2976]="172,860",
+ [2979]="157,786", [2981]="648,3243", [2982]="566,2830", [2983]="280,1401", [2984]="215,1078", [2985]="822,4114",
+ [2988]="314,1572", [3008]="34,174", [3011]="2847,14235", [3018]="625,3125", [3019]="423,2116", [3021]="2421,12106",
+ [3023]="754,3772", [3025]="3695,18479", [3034]="6056,30283", [3036]="515,2579", [3037]="4814,24072", [3040]="940,4702",
+ [3041]="3769,18847", [3042]="4577,22888", [3045]="1574,7870", [3047]="1052,5261", [3048]="1919,9599", [3049]="2119,10596",
+ [3053]="2140,10704", [3055]="1526,7632", [3067]="1275,6376", [3070]="7,37", [3072]="1207,6037", [3074]="476,2381",
+ [3075]="15073,75369", [3078]="2777,13888", [3079]="297,1487", [3151]="87,438", [3154]="1094,5471", [3158]="60,304",
+ [3160]="470,2352", [3161]="295,1475", [3187]="14870,74354", [3191]="4629,23147", [3193]="2072,10362", [3194]="2496,12480",
+ [3195]="1372,6863", [3196]="1377,6887", [3198]="2742,13710", [3200]="19,96", [3201]="4496,22484", [3205]="230,1150",
+ [3206]="4582,22911", [3208]="25378,126894", [3209]="6783,33918", [3210]="5627,28135", [3211]="373,1866", [3214]="34,170",
+ [3217]="135,675", [3228]="1098,5493", [3230]="922,4611", [3231]="1266,6333", [3260]="6,32", [3261]="7,36",
+ [3268]="25,129", [3270]="10,52", [3273]="15,78", [3274]="7,39", [3279]="105,526", [3281]="56,281",
+ [3283]="295,1477", [3285]="36,183", [3286]="59,298", [3287]="199,999", [3289]="57,289", [3290]="48,242",
+ [3292]="203,1017", [3302]="319,1596", [3303]="70,354", [3306]="654,3270", [3307]="215,1079", [3308]="144,722",
+ [3311]="152,762", [3312]="70,354", [3313]="519,2596", [3315]="455,2275", [3319]="110,551", [3321]="41,208",
+ [3322]="11,56", [3324]="1120,5600", [3325]="140,704", [3327]="141,709", [3330]="281,1406", [3331]="67,338",
+ [3334]="68,344", [3341]="1621,8109", [3344]="146,730", [3365]="3,17", [3374]="45,228", [3380]="365,1827",
+ [3392]="1663,8318", [3400]="2761,13807", [3413]="3229,16148", [3414]="4029,20145", [3415]="3598,17994", [3417]="4629,23147",
+ [3429]="586,2932", [3430]="11027,55135", [3435]="19,99", [3437]="24,120", [3439]="30,151", [3440]="640,3203",
+ [3442]="44,224", [3443]="138,692", [3450]="443,2218", [3453]="46,233", [3458]="334,1671", [3461]="1006,5030",
+ [3469]="49,246", [3471]="142,713", [3472]="71,358", [3473]="299,1499", [3475]="21810,109053", [3480]="532,2661",
+ [3481]="1284,6423", [3483]="965,4829", [3484]="1767,8838", [3489]="937,4689", [3490]="2731,13659", [3511]="214,1071",
+ [3530]="25,100", [3558]="1044,5221", [3559]="473,2369", [3562]="823,4118", [3563]="557,2788", [3565]="280,1404",
+ [3567]="922,4614", [3570]="839,4198", [3572]="972,4862", [3578]="340,1700", [3581]="1046,5231", [3582]="315,1575",
+ [3585]="953,4768", [3586]="1034,5172", [3588]="2873,14366", [3589]="115,577", [3590]="115,579", [3593]="1095,5478",
+ [3595]="4,24", [3596]="4,24", [3603]="29,146", [3641]="15,79", [3644]="47,238", [3647]="434,2170",
+ [3648]="123,617", [3649]="115,576", [3652]="364,1821", [3653]="438,2193", [3654]="367,1835", [3655]="1022,5112",
+ [3661]="9,46", [3719]="822,4112", [3732]="801,4007", [3740]="2452,12263", [3741]="923,4615", [3748]="1305,6525",
+ [3749]="1320,6604", [3751]="2661,13308", [3752]="746,3730", [3754]="1492,7462", [3755]="5447,27237", [3758]="1817,9087",
+ [3761]="3306,16534", [3763]="6761,33806", [3764]="3181,15906", [3779]="2835,14176", [3780]="1877,9389", [3782]="3451,17258",
+ [3786]="3957,19786", [3794]="775,3875", [3795]="982,4910", [3796]="493,2468", [3797]="1692,8461", [3798]="902,4511",
+ [3799]="1461,7305", [3800]="1068,5344", [3802]="627,3137", [3806]="1272,6360", [3807]="1162,5814", [3809]="962,4814",
+ [3812]="971,4857", [3813]="1772,8863", [3815]="1475,7378", [3816]="2102,10512", [3822]="6481,32406", [3833]="24,122",
+ [3834]="32,163", [3842]="2906,14532", [3844]="5658,28294", [3850]="7304,36524", [3852]="8361,41805", [3854]="14120,70604",
+ [3855]="11248,56244", [3856]="14221,71107", [3889]="1584,7923", [3891]="2457,12285", [3902]="1317,6589", [3937]="2018,10093",
+ [3939]="2256,11284", [3942]="2636,13184", [3943]="2244,11222", [3945]="3852,19264", [3946]="2432,12160", [3951]="5897,29488",
+ [3962]="3080,15400", [3963]="1402,7013", [3964]="2127,10639", [3967]="2904,14520", [3969]="3256,16284", [3970]="4296,21482",
+ [3973]="3657,18287", [3974]="5487,27435", [3975]="3896,19483", [3976]="6979,34895", [3994]="4404,22024", [3995]="4171,20856",
+ [3996]="4660,23300", [4000]="1797,8987", [4002]="2463,12316", [4003]="2714,13574", [4005]="3478,17390", [4006]="2434,12173",
+ [4007]="3696,18481", [4021]="7198,35992", [4023]="6216,31080", [4024]="9822,49110", [4025]="5070,25352", [4035]="1989,9945",
+ [4038]="3562,17811", [4042]="2107,10537", [4048]="1767,8838", [4050]="2375,11875", [4051]="1670,8350", [4054]="3626,18130",
+ [4055]="2481,12407", [4057]="4032,20164", [4059]="2234,11170", [4062]="8359,41796", [4068]="6918,34593", [4069]="11900,59504",
+ [4073]="2230,11152", [4074]="4785,23929", [4076]="3301,16509", [4079]="6753,33767", [4087]="8722,43612", [4088]="18523,92616",
+ [4090]="20736,103684", [4107]="2136,10683", [4114]="3866,19334", [4117]="3119,15597", [4120]="5031,25156", [4121]="1380,6903",
+ [4122]="8384,41923", [4124]="3991,19957", [4127]="8073,40369", [4128]="14588,72940", [4129]="9444,47222", [4134]="26994,134972",
+ [4136]="6022,30110", [4137]="4010,20054", [4140]="1875,9376", [4197]="2765,13829", [4237]="35,175", [4239]="71,358",
+ [4243]="461,2309", [4244]="723,3619", [4247]="1049,5249", [4251]="1200,6000", [4253]="962,4811", [4255]="2366,11831",
+ [4256]="3477,17388", [4257]="1311,6557", [4259]="1934,9673", [4261]="32,160", [4290]="715,3577", [4309]="226,1134",
+ [4310]="180,903", [4312]="237,1187", [4313]="416,2084", [4315]="425,2127", [4316]="743,3716", [4319]="815,4077",
+ [4320]="979,4898", [4321]="1120,5601", [4324]="1874,9374", [4327]="3788,18942", [4329]="2120,10604", [4331]="526,2631",
+ [4362]="187,939", [4368]="408,2044", [4383]="3183,15916", [4385]="1410,7053", [4434]="572,2862", [4437]="1855,9279",
+ [4438]="1693,8466", [4443]="3472,17361", [4446]="3594,17973", [4447]="902,4510", [4448]="1992,9960", [4454]="3800,19002",
+ [4455]="3096,15484", [4456]="1553,7769", [4464]="2380,11902", [4465]="1585,7929", [4478]="10176,50884", [4504]="1475,7375",
+ [4507]="9938,49693", [4508]="9351,46759", [4534]="1173,5869", [4545]="2202,11011", [4547]="8319,41597", [4560]="37,186",
+ [4562]="298,1492", [4563]="110,553", [4564]="610,3054", [4565]="38,194", [4566]="631,3158", [4567]="1049,5248",
+ [4568]="1695,8475", [4569]="612,3064", [4570]="922,4612", [4571]="979,4897", [4577]="357,1785", [4616]="3,18",
+ [4643]="1824,9121", [4658]="23,119", [4660]="324,1623", [4661]="929,4646", [4662]="24,124", [4663]="23,116",
+ [4666]="26,133", [4668]="32,161", [4669]="42,210", [4675]="35,179", [4684]="61,308", [4686]="67,337",
+ [4689]="85,426", [4690]="71,357", [4692]="69,345", [4694]="515,2577", [4695]="327,1636", [4698]="301,1509",
+ [4699]="221,1106", [4701]="252,1264", [4705]="1449,7249", [4708]="462,2310", [4710]="561,2809", [4711]="1112,5562",
+ [4712]="1228,6141", [4715]="1026,5131", [4718]="2223,11119", [4719]="1676,8384", [4721]="2809,14048", [4722]="1694,8473",
+ [4724]="1763,8816", [4725]="4736,23681", [4727]="2791,13956", [4736]="2616,13082", [4738]="3294,16472", [4744]="1986,9934",
+ [4745]="3230,16154", [4765]="575,2878", [4771]="211,1059", [4772]="56,283", [4778]="1470,7351", [4781]="547,2736",
+ [4782]="415,2077", [4786]="278,1394", [4788]="526,2634", [4789]="399,1999", [4790]="831,4159", [4792]="656,3280",
+ [4797]="852,4263", [4798]="774,3871", [4799]="608,3043", [4800]="1222,6110", [4810]="3352,16760", [4816]="1503,7519",
+ [4820]="1664,8321", [4827]="749,3749", [4829]="830,4154", [4830]="1895,9475", [4831]="1571,7859", [4832]="2099,10498",
+ [4835]="2110,10551", [4840]="142,714", [4861]="119,597", [4906]="22,110", [4909]="369,1845", [4910]="7,39",
+ [4913]="7,36", [4914]="6,30", [4915]="7,36", [4916]="9,49", [4917]="14,73", [4920]="7,38",
+ [4921]="12,64", [4922]="15,77", [4923]="25,129", [4925]="26,130", [4928]="20,103", [4931]="134,672",
+ [4933]="32,160", [4935]="23,118", [4936]="23,119", [4940]="36,183", [4944]="72,362", [4946]="67,338",
+ [4947]="325,1628", [4949]="1706,8533", [4954]="6,31", [4958]="23,119", [4961]="183,919", [4962]="20,101",
+ [4963]="24,122", [4968]="91,455", [4972]="64,321", [4975]="7773,38868", [4987]="15584,77921", [5016]="2955,14776",
+ [5024]="2,40", [5093]="247,1239", [5105]="5,100", [5111]="212,1063", [5181]="1778,8891", [5187]="2163,10815",
+ [5192]="2163,10818", [5193]="940,4701", [5195]="437,2188", [5196]="2196,10984", [5197]="1917,9588", [5199]="966,4830",
+ [5200]="2787,13938", [5202]="1147,5738", [5229]="28,143", [5254]="618,3090", [5256]="7227,36137", [5267]="53869,269347",
+ [5274]="1003,5019", [5275]="176,880", [5279]="1437,7185", [5299]="359,1796", [5302]="929,4648", [5309]="1038,5191",
+ [5310]="555,2779", [5312]="420,2100", [5314]="423,2115", [5315]="214,1070", [5319]="323,1616", [5320]="372,1863",
+ [5321]="1484,7424", [5324]="776,3882", [5325]="498,2494", [5327]="519,2596", [5340]="919,4597", [5341]="369,1845",
+ [5343]="306,1534", [5355]="947,4739", [5357]="2221,11108", [5394]="6,32", [5404]="938,4690", [5405]="7,37",
+ [5423]="2084,10422", [5425]="504,2520", [5444]="436,2182", [5458]="27,139", [5459]="472,2362", [5541]="3694,18470",
+ [5542]="370,1853", [5586]="26,131", [5590]="36,180", [5591]="54,271", [5592]="54,272", [5596]="141,709",
+ [5605]="150,751", [5606]="23,116", [5612]="72,364", [5616]="22738,113691", [5618]="57,285", [5624]="2927,14635",
+ [5626]="1717,8588", [5629]="347,1737", [5663]="0,800000", [5739]="2739,13695", [5749]="2664,13322", [5750]="641,3209",
+ [5751]="822,4112", [5757]="1363,6817", [5767]="44,222", [5770]="1807,9038", [5778]="30,152", [5781]="601,3009",
+ [5782]="3211,16056", [5783]="2316,11582", [5813]="7088,35440", [5814]="2351,11757", [5820]="1623,8115", [5874]="0,800000",
+ [5875]="0,800000", [5936]="20,100", [5939]="20,101", [5940]="154,770", [5941]="115,579", [5943]="1008,5044",
+ [5944]="331,1656", [5957]="40,201", [5958]="829,4146", [5962]="2794,13973", [5967]="209,1046", [5969]="625,3127",
+ [5970]="502,2511", [5971]="909,4545", [6040]="1649,8248", [6059]="13,66", [6076]="9,48", [6084]="291,1455",
+ [6087]="1728,8640", [6092]="421,2105", [6094]="1278,6394", [6122]="1,5", [6138]="1,5", [6177]="69,349",
+ [6179]="369,1847", [6185]="7,38", [6186]="1373,6865", [6187]="613,3067", [6188]="305,1526", [6191]="616,3080",
+ [6194]="5308,26544", [6200]="1223,6118", [6202]="37,189", [6203]="121,609", [6204]="2065,10328", [6205]="922,4614",
+ [6206]="555,2778", [6214]="595,2979", [6215]="602,3010", [6216]="1,25", [6223]="4797,23987", [6226]="1068,5344",
+ [6238]="98,492", [6241]="99,497", [6263]="589,2948", [6264]="884,4421", [6269]="193,967", [6282]="2244,11220",
+ [6314]="1217,6089", [6318]="4803,24015", [6319]="964,4820", [6323]="3134,15670", [6324]="1892,9464", [6327]="12823,64119",
+ [6331]="9466,47334", [6335]="1581,7906", [6336]="305,1527", [6340]="1260,6300", [6350]="295,1479", [6365]="180,902",
+ [6366]="1066,5331", [6374]="25,500", [6378]="292,1464", [6379]="244,1224", [6380]="654,3272", [6386]="2692,13463",
+ [6387]="1228,6142", [6388]="2043,10217", [6392]="1000,5004", [6393]="760,3804", [6394]="1041,5206", [6395]="1264,6322",
+ [6396]="2814,14074", [6397]="986,4930", [6398]="989,4949", [6399]="1639,8197", [6402]="4699,23497", [6403]="1772,8860",
+ [6405]="3168,15840", [6408]="1654,8272", [6410]="1515,7575", [6415]="4565,22826", [6419]="2299,11498", [6420]="3739,18699",
+ [6421]="2317,11586", [6425]="4478,22394", [6426]="4162,20812", [6427]="7016,35082", [6428]="2795,13976", [6430]="9098,45494",
+ [6431]="5436,27182", [6432]="3741,18709", [6447]="1124,5621", [6448]="2331,11657", [6450]="170,680", [6459]="1122,5610",
+ [6460]="844,4223", [6465]="922,4612", [6466]="330,1654", [6467]="420,2104", [6473]="1212,6064", [6477]="274,1373",
+ [6480]="713,3567", [6481]="642,3210", [6482]="728,3641", [6503]="763,3815", [6504]="2933,14668", [6509]="45,225",
+ [6510]="54,273", [6511]="121,609", [6512]="191,956", [6514]="42,213", [6518]="70,352", [6519]="36,181",
+ [6520]="33,167", [6521]="47,237", [6524]="574,2871", [6525]="1033,5168", [6527]="187,938", [6528]="358,1793",
+ [6531]="417,2086", [6536]="488,2444", [6537]="210,1052", [6538]="492,2462", [6539]="162,812", [6540]="431,2157",
+ [6541]="163,818", [6545]="676,3380", [6549]="102,510", [6551]="409,2049", [6554]="229,1146", [6555]="104,522",
+ [6557]="302,1512", [6558]="180,903", [6560]="616,3080", [6561]="675,3379", [6562]="508,2543", [6563]="295,1479",
+ [6564]="512,2561", [6565]="394,1970", [6568]="920,4604", [6569]="1044,5223", [6570]="363,1816", [6571]="1167,5835",
+ [6572]="1323,6619", [6573]="938,4692", [6574]="568,2841", [6575]="431,2156", [6576]="572,2862", [6578]="1303,6515",
+ [6585]="446,2234", [6592]="2448,12240", [6593]="923,4615", [6594]="1121,5605", [6595]="1125,5625", [6596]="2258,11291",
+ [6597]="1707,8537", [6598]="2426,12132", [6600]="867,4339", [6602]="874,4370", [6603]="2335,11675", [6604]="960,4801",
+ [6605]="971,4858", [6611]="812,4064", [6612]="1112,5563", [6614]="1120,5604", [6615]="824,4124", [6616]="2204,11020",
+ [6622]="49863,249316", [6628]="370,1852", [6629]="756,3781", [6632]="511,2558", [6633]="2558,12791", [6641]="4410,22052",
+ [6642]="1880,9403", [6659]="541,2706", [6660]="36157,180789", [6666]="830,4153", [6670]="1672,8364", [6675]="1049,5245",
+ [6676]="2246,11230", [6679]="5823,29118", [6681]="6249,31247", [6682]="2281,11406", [6685]="1573,7866", [6686]="3152,15762",
+ [6687]="9930,49653", [6688]="2471,12356", [6689]="8267,41337", [6690]="4015,20078", [6691]="8866,44333", [6692]="9788,48943",
+ [6713]="10,52", [6719]="1097,5486", [6720]="3219,16095", [6721]="1419,7095", [6725]="6105,30529", [6732]="2421,12109",
+ [6737]="2805,14028", [6738]="7040,35204", [6739]="2991,14959", [6740]="1001,5005", [6742]="2830,14151", [6745]="1791,8958",
+ [6746]="7076,35380", [6752]="1602,8010", [6773]="7366,36832", [6784]="2032,10160", [6789]="4012,20061", [6791]="3464,17322",
+ [6793]="3157,15787", [6804]="8060,40302", [6806]="10209,51048", [6829]="18714,93573", [6830]="23476,117382", [6831]="17522,87614",
+ [6832]="3770,18850", [6836]="1,5", [6901]="1523,7616", [6902]="1052,5264", [6903]="1859,9297", [6905]="4813,24065",
+ [6907]="1873,9365", [6908]="626,3133", [6909]="7155,35778", [6910]="2298,11493", [6969]="701,3507", [6971]="2221,11106",
+ [6973]="2465,12327", [7002]="3028,15142", [7004]="985,4925", [7026]="22,112", [7047]="825,4125", [7048]="745,3726",
+ [7054]="4701,23505", [7055]="1504,7520", [7058]="2052,10263", [7059]="2781,13906", [7061]="2017,10088", [7062]="2430,12151",
+ [7094]="174,872", [7106]="1234,6174", [7107]="1858,9294", [7110]="2070,10350", [7120]="896,4480", [7130]="2328,11643",
+ [7229]="285,1428", [7230]="3103,15516", [7277]="28,143", [7281]="85,427", [7282]="599,2999", [7283]="415,2077",
+ [7284]="586,2934", [7285]="589,2945", [7298]="469,2345", [7335]="1937,9686", [7336]="1509,7549", [7349]="861,4309",
+ [7351]="58,291", [7354]="1865,9325", [7355]="1031,5156", [7357]="1875,9379", [7358]="885,4429", [7366]="1098,5491",
+ [7367]="1818,9094", [7375]="3774,18870", [7378]="2146,10732", [7386]="2387,11938", [7390]="4237,21189", [7406]="1372,6862",
+ [7407]="3666,18334", [7409]="2289,11446", [7410]="1174,5874", [7411]="1415,7077", [7413]="2157,10786", [7414]="3176,15880",
+ [7418]="4256,21281", [7421]="1778,8892", [7422]="1622,8114", [7424]="2709,13546", [7431]="3899,19496", [7432]="2718,13590",
+ [7436]="2111,10559", [7441]="3514,17574", [7443]="2243,11218", [7444]="3377,16888", [7445]="3660,18304", [7446]="2474,12370",
+ [7447]="2068,10344", [7448]="2076,10381", [7459]="4317,21589", [7465]="6747,33736", [7468]="6763,33816", [7469]="6284,31422",
+ [7470]="3668,18342", [7471]="2455,12276", [7472]="3423,17116", [7475]="2371,11857", [7477]="8125,40625", [7482]="4926,24631",
+ [7483]="3390,16954", [7485]="3073,15368", [7486]="9325,46629", [7487]="8665,43329", [7489]="3740,18704", [7494]="3543,17718",
+ [7495]="9558,47793", [7496]="8882,44413", [7509]="553,2769", [7510]="556,2780", [7511]="1938,9691", [7512]="1945,9727",
+ [7513]="9805,49028", [7514]="9842,49212", [7517]="9372,46864", [7518]="9406,47032", [7519]="7635,38176", [7522]="4963,24815",
+ [7524]="4297,21487", [7526]="3367,16836", [7527]="11284,56424", [7533]="4446,22232", [7534]="4016,20081", [7537]="14012,70063",
+ [7538]="12322,61613", [7539]="12692,63462", [7542]="8284,41423", [7545]="4658,23291", [7606]="557,2789", [7683]="7916,39584",
+ [7684]="2621,13109", [7687]="8836,44181", [7689]="11124,55622", [7710]="12279,61399", [7711]="1405,7027", [7712]="1057,5289",
+ [7717]="18923,94617", [7718]="6867,34339", [7721]="17922,89612", [7723]="22567,112837", [7728]="3223,16119", [7730]="10146,50733",
+ [7736]="11971,59855", [7738]="211,1059", [7739]="318,1594", [7750]="1712,8563", [7751]="1614,8073", [7752]="6903,34515",
+ [7753]="7874,39372", [7754]="1959,9799", [7756]="1927,9636", [7757]="12875,64375", [7759]="6724,33620", [7761]="11290,56454",
+ [7913]="2500,12503", [7914]="3331,16655", [7916]="3700,18503", [7918]="6466,32330", [7919]="4359,21795", [7920]="8053,40266",
+ [7921]="9427,47139", [7922]="4152,20761", [7926]="10416,52084", [7927]="5257,26288", [7928]="8484,42422", [7929]="7739,38699",
+ [7930]="12330,61652", [7931]="7955,39779", [7932]="8662,43310", [7933]="10077,50387", [7934]="10114,50571", [7935]="14645,73225",
+ [7936]="11771,58857", [7937]="11813,59069", [7938]="7090,35453", [7939]="19074,95370", [7941]="12520,62602", [7943]="15892,79460",
+ [7944]="20092,100464", [7946]="21661,108305", [7947]="24892,124461", [7948]="1121,5609", [7949]="2252,11261", [7950]="2260,11302",
+ [7951]="1134,5671", [7952]="1606,8032", [7954]="23160,115800", [7956]="1944,9723", [7957]="2205,11029", [7958]="2435,12179",
+ [7959]="33858,169290", [7960]="38548,192744", [7963]="6488,32441", [8006]="12472,62361", [8080]="10477,52389", [8081]="4989,24945",
+ [8082]="5570,27852", [8083]="3980,19903", [8084]="4758,23792", [8085]="9194,45971", [8086]="6516,32580", [8088]="4694,23470",
+ [8089]="7015,35075", [8090]="4730,23653", [8091]="4748,23742", [8092]="7095,35479", [8093]="9515,47577", [8094]="9551,47759",
+ [8108]="3594,17973", [8109]="5012,25060", [8110]="3622,18111", [8111]="5890,29453", [8113]="9694,48474", [8114]="3677,18389",
+ [8115]="5980,29903", [8116]="4632,23161", [8119]="12726,63630", [8120]="4965,24829", [8123]="11276,56380", [8125]="6367,31838",
+ [8130]="9459,47295", [8133]="10517,52586", [8134]="15993,79967", [8137]="4940,24703", [8138]="13416,67080", [8139]="5375,26875",
+ [8140]="4994,24972", [8141]="8058,40294", [8142]="8087,40439", [8143]="12647,63238", [8144]="8796,43984", [8156]="3907,19536",
+ [8157]="9096,45482", [8158]="3936,19680", [8159]="3950,19750", [8160]="5901,29507", [8161]="5922,29614", [8162]="8575,42876",
+ [8163]="6442,32211", [8174]="4131,20658", [8176]="4495,22476", [8177]="71,359", [8178]="306,1532", [8180]="240,1204",
+ [8181]="79,398", [8188]="6414,32072", [8189]="7567,37839", [8191]="7780,38901", [8198]="4013,20069", [8204]="4676,23383",
+ [8207]="8978,44893", [8210]="5537,27686", [8211]="8002,40013", [8214]="6230,31152", [8215]="7213,36069", [8216]="6323,31618",
+ [8223]="10066,50334", [8224]="7655,38279", [8226]="5747,28738", [8245]="12923,64615", [8247]="4997,24989", [8248]="7032,35162",
+ [8250]="8034,40171", [8252]="13623,68115", [8254]="8640,43200", [8256]="10261,51307", [8258]="17396,86984", [8259]="7315,36578",
+ [8262]="14606,73030", [8263]="10373,51867", [8264]="7857,39288", [8265]="19914,99572", [8266]="7468,37342", [8267]="8928,44640",
+ [8268]="8960,44801", [8269]="14362,71814", [8270]="14351,71759", [8271]="20358,101791", [8273]="6290,31454", [8274]="17940,89704",
+ [8276]="6867,34337", [8277]="6381,31907", [8278]="9567,47837", [8279]="10371,51857", [8280]="14881,74407", [8281]="10450,52253",
+ [8283]="16550,82750", [8284]="10514,52571", [8285]="6637,33187", [8286]="9427,47138", [8288]="11876,59382", [8289]="16688,83442",
+ [8290]="16982,84910", [8291]="6784,33923", [8292]="11476,57383", [8293]="8542,42714", [8294]="12652,63260", [8295]="7988,39941",
+ [8296]="20145,100727", [8297]="9113,45566", [8299]="14354,71770", [8301]="14463,72318", [8302]="11060,55302", [8303]="25164,125823",
+ [8304]="10513,52566", [8305]="11743,58719", [8306]="11787,58938", [8307]="18717,93587", [8308]="18703,93518", [8309]="25377,126887",
+ [8310]="19420,97100", [8311]="10287,51435", [8312]="25918,129593", [8313]="28565,142829", [8314]="9405,47029", [8315]="8908,44540",
+ [8316]="14110,70554", [8317]="15013,75069", [8318]="22622,113111", [8319]="16037,80185", [8347]="5980,29900", [8349]="14478,72392",
+ [8426]="25,12", [8544]="340,1360", [8545]="800,3200", [8583]="0,800000", [8589]="0,800000", [8590]="0,800000",
+ [8627]="0,800000", [8628]="0,800000", [8630]="250000,1000000", [8633]="250000,1000000", [8746]="682,3412", [8748]="775,3875",
+ [8749]="1604,8020", [8751]="2618,13092", [8752]="5217,26087", [8755]="6512,32563", [8840]="3527,17638", [9285]="4204,21022",
+ [9286]="10571,52856", [9287]="4235,21177", [9288]="4250,21252", [9289]="6350,31752", [9290]="6883,34417", [9291]="9251,46257",
+ [9292]="6436,32183", [9359]="19577,97889", [9366]="3689,18447", [9375]="4220,21102", [9378]="11380,56902", [9379]="26383,131918",
+ [9382]="3608,18040", [9385]="12281,61405", [9387]="7208,36040", [9388]="3835,19178", [9389]="5198,25990", [9390]="2576,12882",
+ [9394]="2397,11988", [9398]="1493,7465", [9400]="3248,16243", [9403]="2662,13311", [9405]="2055,10278", [9407]="5094,25471",
+ [9408]="18639,93199", [9409]="4490,22451", [9410]="6662,33310", [9411]="8587,42936", [9413]="32249,161245", [9414]="10374,51873",
+ [9416]="28218,141093", [9418]="32851,164259", [9419]="21692,108461", [9420]="4083,20417", [9423]="25464,127320", [9424]="13594,67971",
+ [9425]="21489,107447", [9427]="14853,74266", [9428]="2096,10482", [9430]="8553,42769", [9431]="4885,24427", [9432]="5327,26638",
+ [9435]="2916,14584", [9445]="2260,11303", [9448]="1385,6929", [9449]="9564,47823", [9450]="2618,13091", [9452]="8210,41052",
+ [9453]="6592,32962", [9455]="1826,9130", [9457]="8902,44511", [9458]="6918,34590", [9459]="13560,67802", [9465]="18561,92805",
+ [9467]="22418,112092", [9469]="14634,73172", [9473]="13241,66208", [9476]="15010,75051", [9477]="35936,179683", [9480]="31725,158626",
+ [9481]="34067,170336", [9484]="10962,54812", [9485]="5288,26441", [9486]="5483,27418", [9487]="3632,18164", [9488]="4419,22097",
+ [9490]="6122,30610", [9508]="2352,11763", [9509]="2683,13417", [9512]="6341,31706", [9513]="620,3102", [9515]="2011,10056",
+ [9516]="2071,10355", [9517]="15737,78687", [9518]="1900,9500", [9531]="9195,45976", [9534]="8847,44237", [9598]="94,474",
+ [9599]="142,714", [9600]="93,466", [9607]="1762,8811", [9609]="1009,5047", [9625]="6344,31722", [9630]="5780,28904",
+ [9631]="3868,19342", [9632]="3883,19417", [9633]="5847,29238", [9634]="3381,16906", [9635]="4713,23568", [9637]="8296,41480",
+ [9639]="24111,120557", [9640]="8519,42595", [9643]="15988,79943", [9646]="11863,59315", [9648]="6392,31964", [9649]="15875,79376",
+ [9650]="21619,108098", [9651]="32193,160969", [9652]="16159,80796", [9653]="6745,33728", [9654]="16929,84645", [9656]="7482,37412",
+ [9658]="4086,20433", [9662]="7437,37189", [9663]="9969,49849", [9664]="8738,43691", [9665]="4827,24135", [9678]="17486,87430",
+ [9679]="17550,87751", [9682]="3832,19160", [9683]="38459,192298", [9684]="30875,154379", [9686]="31097,155489", [9687]="1554,7772",
+ [9698]="1505,7525", [9704]="3573,17866", [9742]="49,247", [9743]="67,336", [9744]="45,225", [9745]="54,271",
+ [9746]="56,283", [9748]="274,1372", [9749]="275,1377", [9750]="57,288", [9752]="58,290", [9754]="56,280",
+ [9756]="294,1472", [9757]="364,1820", [9758]="73,365", [9761]="59,295", [9763]="336,1682", [9766]="362,1810",
+ [9770]="417,2085", [9773]="1369,6848", [9775]="316,1580", [9776]="547,2736", [9779]="334,1672", [9780]="370,1850",
+ [9783]="812,4060", [9785]="269,1345", [9786]="234,1174", [9787]="358,1792", [9788]="312,1564", [9789]="742,3710",
+ [9792]="823,4116", [9793]="550,2754", [9794]="829,4146", [9796]="1038,5191", [9802]="1205,6025", [9806]="834,4170",
+ [9810]="1231,6156", [9811]="725,3629", [9812]="570,2852", [9813]="826,4130", [9816]="1781,8907", [9818]="1682,8411",
+ [9822]="1192,5964", [9823]="965,4829", [9829]="1020,5101", [9830]="3489,17446", [9832]="1248,6241", [9833]="3031,15158",
+ [9834]="2074,10372", [9835]="3053,15267", [9838]="1174,5873", [9843]="3739,18697", [9844]="3709,18547", [9846]="1429,7149",
+ [9847]="1779,8896", [9848]="1584,7923", [9852]="3820,19103", [9854]="4935,24678", [9856]="2839,14196", [9859]="2872,14360",
+ [9860]="1906,9531", [9861]="1753,8769", [9862]="4260,21303", [9864]="3527,17638", [9867]="1779,8895", [9876]="3146,15734",
+ [9878]="3425,17125", [9880]="2130,10651", [9881]="3464,17321", [9885]="4180,20900", [9888]="8411,42057", [9889]="4240,21204",
+ [9891]="2636,13182", [9893]="6689,33449", [9895]="5221,26106", [9897]="7368,36843", [9901]="3295,16475", [9903]="7743,38715",
+ [9905]="8251,41259", [9906]="3043,15217", [9909]="2848,14243", [9910]="3087,15438", [9911]="7228,36143", [9912]="5037,25189",
+ [9913]="8491,42455", [9918]="10212,51062", [9919]="4119,20597", [9920]="3721,18607", [9921]="6050,30253", [9923]="6095,30478",
+ [9925]="3790,18950", [9927]="3927,19639", [9932]="6995,34978", [9933]="9394,46971", [9934]="6577,32889", [9938]="6029,30148",
+ [9942]="9341,46709", [9943]="11271,56359", [9951]="5436,27181", [9954]="12126,60630", [9955]="8531,42655", [9957]="13753,68767",
+ [9958]="14724,73621", [9965]="9973,49867", [9966]="11800,59002", [9967]="5105,25527", [9968]="4744,23720", [9969]="6925,34627",
+ [9970]="10029,50147", [9971]="6978,34892", [9972]="4357,21786", [9973]="6510,32554", [9999]="4833,24165", [10002]="5276,26381",
+ [10003]="2859,14297", [10007]="5800,29000", [10008]="4365,21827", [10023]="3334,16673", [10026]="5459,27299", [10031]="6030,30151",
+ [10033]="6075,30378", [10035]="1735,8677", [10036]="1741,8705", [10040]="1767,8837", [10041]="8593,42968", [10043]="2033,10168",
+ [10044]="6765,33828", [10045]="23,118", [10047]="164,823", [10048]="935,4679", [10059]="4739,23698", [10060]="6668,33340",
+ [10062]="4758,23792", [10064]="10775,53875", [10065]="12153,60768", [10068]="9128,45641", [10070]="15482,77412", [10071]="6450,32252",
+ [10072]="6177,30887", [10073]="9858,49294", [10074]="13985,69929", [10075]="9369,46846", [10077]="16968,84842", [10079]="6370,31853",
+ [10080]="7319,36599", [10082]="10752,53764", [10085]="11529,57649", [10086]="14768,73841", [10087]="5973,29865", [10088]="5551,27759",
+ [10089]="8296,41480", [10090]="8992,44963", [10091]="13023,65115", [10092]="9785,48927", [10094]="5828,29142", [10095]="10295,51477",
+ [10097]="10992,54960", [10098]="8737,43685", [10099]="6568,32840", [10100]="11109,55545", [10101]="15756,78782", [10102]="15020,75102",
+ [10108]="8203,41017", [10110]="7948,39740", [10112]="19071,95357", [10113]="13541,67709", [10118]="23382,116910", [10119]="16676,83384",
+ [10120]="8797,43988", [10121]="10515,52577", [10122]="9007,45036", [10123]="15239,76199", [10127]="7656,38284", [10128]="20838,104191",
+ [10129]="8253,41265", [10130]="8283,41417", [10131]="12376,61881", [10132]="13289,66449", [10133]="18887,94437", [10134]="13386,66934",
+ [10135]="17950,89752", [10137]="13021,65108", [10138]="12274,61372", [10139]="13294,66472", [10140]="8773,43867", [10141]="18094,90473",
+ [10142]="12495,62477", [10143]="17176,85883", [10144]="8164,40821", [10146]="15638,78193", [10148]="11273,56368", [10149]="10541,52706",
+ [10150]="16087,80437", [10151]="22114,110571", [10152]="21901,109507", [10153]="16264,81324", [10154]="12880,64401", [10155]="19476,97383",
+ [10156]="12794,63974", [10157]="27117,135587", [10158]="26964,134822", [10159]="11444,57221", [10160]="18599,92996", [10161]="12277,61388",
+ [10162]="25325,126627", [10163]="18893,94469", [10164]="25915,129579", [10165]="10983,54915", [10166]="10399,51995", [10167]="16470,82352",
+ [10168]="17523,87617", [10169]="24903,124516", [10170]="17651,88257", [10171]="10591,52959", [10172]="9603,48019", [10174]="8121,40608",
+ [10175]="9011,45055", [10177]="12833,64166", [10181]="14640,73203", [10182]="18370,91851", [10187]="11785,58929", [10188]="16717,83588",
+ [10189]="11872,59361", [10193]="19776,98880", [10196]="7593,37968", [10201]="10411,52055", [10202]="7020,35101", [10203]="18195,90977",
+ [10205]="7596,37981", [10206]="7125,35629", [10207]="11694,58474", [10208]="16777,83885", [10209]="12604,63020", [10210]="12845,64229",
+ [10211]="12276,61384", [10213]="7850,39252", [10215]="16212,81061", [10216]="7180,35902", [10217]="16116,80581", [10218]="16399,81999",
+ [10219]="12011,60057", [10220]="20938,104691", [10223]="9466,47331", [10224]="10755,53779", [10226]="16046,80234", [10227]="21769,108847",
+ [10228]="15940,79703", [10229]="10331,51658", [10231]="9816,49080", [10236]="22616,113080", [10238]="13362,66811", [10239]="8733,43669",
+ [10240]="22009,110045", [10241]="14716,73580", [10242]="9360,46802", [10243]="8863,44316", [10244]="21069,105348", [10245]="14932,74662",
+ [10246]="18058,90292", [10247]="13238,66190", [10248]="8737,43688", [10249]="12974,64874", [10250]="13380,66902", [10251]="8952,44761",
+ [10252]="18207,91039", [10253]="13523,67615", [10254]="18580,92900", [10255]="8330,41651", [10256]="10309,51545", [10257]="15735,78679",
+ [10258]="12292,61462", [10259]="10569,52847", [10260]="10752,53760", [10261]="16187,80939", [10262]="21954,109772", [10263]="16306,81531",
+ [10264]="22406,112034", [10265]="12964,64823", [10266]="27085,135426", [10267]="12880,64401", [10268]="13283,66416", [10269]="13152,65762",
+ [10270]="20158,100790", [10271]="27321,136606", [10272]="18780,93901", [10273]="25473,127367", [10274]="19008,95041", [10275]="28357,141787",
+ [10276]="17200,86004", [10277]="12294,61471", [10278]="10981,54909", [10279]="19543,97718", [10280]="27515,137578", [10281]="19689,98447",
+ [10282]="11813,59069", [10289]="1557,7788", [10330]="9587,47939", [10331]="2729,13645", [10332]="3790,18951", [10358]="2421,12108",
+ [10359]="2430,12152", [10365]="26276,131382", [10366]="28849,144246", [10367]="27639,138196", [10368]="29156,145780", [10369]="12984,64921",
+ [10370]="12295,61477", [10371]="19474,97373", [10372]="20525,102625", [10373]="29298,146490", [10374]="20676,103380", [10375]="12525,62626",
+ [10376]="21868,109341", [10377]="14042,70210", [10378]="30662,153310", [10379]="22418,112092", [10380]="14904,74523", [10381]="14246,71231",
+ [10382]="30689,153446", [10383]="21121,105606", [10384]="29882,149413", [10385]="21575,107876", [10386]="14548,72744", [10387]="14405,72029",
+ [10388]="22117,110588", [10389]="30056,150280", [10390]="22285,111425", [10391]="14420,72101", [10399]="1467,7336", [10400]="563,2818",
+ [10401]="255,1279", [10403]="541,2706", [10407]="432,2160", [10411]="945,4728", [10412]="486,2434", [10413]="369,1847",
+ [10421]="32,162", [10423]="2842,14212", [10462]="3609,18045", [10508]="8959,44795", [10510]="11369,56846", [10518]="4696,23483",
+ [10544]="25,128", [10550]="48,244", [10553]="131,658", [10554]="119,598", [10573]="13754,68774", [10574]="3775,18879",
+ [10578]="3377,16886", [10584]="2905,14529", [10623]="24748,123741", [10625]="27366,136832", [10626]="36732,183662", [10628]="29245,146226",
+ [10629]="8066,40331", [10631]="6086,30434", [10633]="20447,102236", [10635]="14,74", [10636]="6,31", [10637]="139,699",
+ [10652]="36370,181853", [10653]="1639,8198", [10654]="965,4828", [10656]="14,74", [10686]="25395,126978", [10696]="41891,209455",
+ [10697]="42044,210222", [10698]="52747,263736", [10700]="4983,24919", [10701]="7536,37681", [10702]="5379,26898", [10703]="16792,83964",
+ [10704]="13649,68247", [10705]="3666,18334", [10707]="13576,67880", [10740]="18712,93564", [10742]="9589,47949", [10745]="8498,42493",
+ [10746]="8007,40039", [10747]="2327,11638", [10748]="4380,21904", [10749]="18436,92180", [10751]="10634,53171", [10760]="2914,14570",
+ [10763]="9079,45395", [10764]="10434,52174", [10765]="4041,20206", [10767]="9652,48261", [10771]="2910,14553", [10772]="14604,73023",
+ [10774]="5957,29788", [10775]="11161,55805", [10776]="4800,24000", [10777]="4014,20071", [10783]="11476,57382", [10785]="15840,79204",
+ [10786]="14373,71867", [10788]="11275,56376", [10797]="35069,175348", [10798]="11024,55123", [10799]="39288,196443", [10800]="7562,37813",
+ [10801]="11704,58521", [10802]="9397,46988", [10803]="35329,176649", [10804]="35462,177310", [10805]="35594,177971", [10806]="15146,75732",
+ [10807]="15202,76013", [10821]="208,1041", [10823]="17796,88982", [10828]="40427,202137", [10833]="8597,42987", [10836]="28989,144947",
+ [10843]="10595,52978", [10844]="44314,221571", [10845]="24908,124542", [10919]="215,1075", [11120]="30144,150721", [11121]="3529,17647",
+ [11123]="15037,75187", [11187]="5,26", [11191]="45,228", [11192]="4,24", [11194]="20405,102025", [11195]="23897,119488",
+ [11263]="10103,50517", [11265]="16485,82425", [11287]="508,2544", [11288]="1535,7675", [11303]="637,3185", [11304]="972,4862",
+ [11306]="3893,19468", [11308]="15765,78829", [11310]="6598,32991", [11311]="6132,30664", [11469]="3563,17816", [11475]="7,39",
+ [11502]="6510,32552", [11603]="30656,153284", [11604]="34000,170001", [11605]="18822,94113", [11606]="19256,96280", [11607]="51225,256126",
+ [11608]="45760,228804", [11623]="9999,49999", [11624]="9079,45399", [11626]="9698,48493", [11627]="14668,73344", [11628]="24433,122168",
+ [11631]="19893,99468", [11632]="16349,81748", [11633]="24633,123166", [11634]="7063,35319", [11662]="7462,37313", [11665]="8532,42661",
+ [11675]="14464,72320", [11677]="11655,58276", [11678]="27293,136469", [11679]="11738,58691", [11685]="13941,69706", [11686]="9329,46646",
+ [11702]="36752,183763", [11703]="12986,64931", [11735]="16670,83350", [11744]="39242,196214", [11745]="13865,69328", [11746]="20718,103594",
+ [11748]="25083,125417", [11764]="10398,51991", [11765]="12525,62626", [11767]="15202,76013", [11768]="8669,43346", [11783]="12767,63839",
+ [11786]="50740,253700", [11787]="23986,119933", [11802]="31459,157295", [11803]="50177,250889", [11805]="40439,202197", [11816]="48882,244414",
+ [11817]="39254,196274", [11820]="26761,133809", [11821]="22385,111925", [11822]="14153,70768", [11823]="23677,118385", [11841]="15032,75164",
+ [11842]="17050,85252", [11847]="7,39", [11849]="7,39", [11850]="7,36", [11852]="14,72", [11860]="12971,64855",
+ [11864]="34108,170543", [11865]="8708,43542", [11866]="9819,49099", [11867]="8769,43849", [11871]="10666,53332", [11872]="14962,74811",
+ [11873]="9662,48310", [11876]="16287,81438", [11882]="20520,102604", [11884]="1846,9232", [11888]="4879,24399", [11889]="12830,64153",
+ [11902]="34194,170974", [11906]="32723,163616", [11908]="9887,49435", [11909]="8267,41338", [11910]="21604,108023", [11911]="12392,61961",
+ [11913]="14045,70225", [11916]="11834,59172", [11917]="6335,31675", [11918]="9537,47688", [11919]="16720,83601", [11921]="54167,270837",
+ [11923]="43649,218245", [11925]="16484,82424", [11926]="24590,122953", [11927]="28799,143997", [11931]="58103,290517", [11936]="284,1422",
+ [11963]="10025,50129", [11964]="30156,150784", [12000]="41054,205270", [12021]="16291,81459", [12049]="16850,84252", [12051]="8996,44984",
+ [12061]="40212,201061", [12062]="40365,201828", [12064]="1,5", [12066]="11149,55748", [12083]="7348,36744", [12108]="23055,115275",
+ [12109]="11569,57846", [12111]="13672,68362", [12112]="10407,52035", [12113]="10444,52220", [12114]="8734,43672", [12115]="12341,61708",
+ [12225]="188,940", [12243]="45980,229902", [12247]="5674,28373", [12248]="6406,32030", [12250]="8068,40342", [12251]="10779,53897",
+ [12255]="6997,34988", [12257]="3886,19430", [12259]="8072,40364", [12282]="8,44", [12295]="282,1414", [12302]="0,1000000",
+ [12303]="0,1000000", [12330]="0,1000000", [12351]="0,1000000", [12353]="0,1000000", [12354]="0,1000000", [12405]="16170,80850",
+ [12406]="8160,40804", [12408]="8797,43986", [12409]="18054,90274", [12410]="18117,90589", [12414]="30408,152044", [12416]="7596,37980",
+ [12420]="24462,122310", [12422]="28357,141787", [12424]="9738,48691", [12425]="10638,53190", [12426]="21069,105345", [12427]="21145,105727",
+ [12428]="15103,75516", [12429]="30289,151448", [12446]="19,96", [12447]="19,97", [12449]="19,97", [12463]="42446,212232",
+ [12464]="8520,42602", [12466]="6865,34328", [12527]="35332,176663", [12531]="28883,144417", [12535]="34926,174630", [12549]="13670,68350",
+ [12550]="11378,56892", [12555]="19923,99616", [12557]="25096,125483", [12583]="66915,334578", [12587]="18929,94649", [12588]="22903,114518",
+ [12589]="9899,49499", [12590]="68066,340333", [12592]="85722,428613", [12602]="31693,158467", [12603]="24189,120948", [12605]="29106,145534",
+ [12606]="12233,61167", [12608]="13232,66160", [12609]="19795,98977", [12610]="21392,106963", [12611]="21473,107365", [12612]="21854,109273",
+ [12613]="29704,148524", [12614]="29815,149076", [12618]="37759,188797", [12619]="37893,189468", [12620]="28084,140423", [12621]="45085,225426",
+ [12625]="22847,114235", [12628]="29121,145606", [12631]="15698,78493", [12633]="25955,129776", [12636]="23452,117262", [12637]="18157,90785",
+ [12639]="25061,125306", [12640]="36930,184651", [12641]="39455,197276", [12709]="52195,260977", [12752]="21359,106795", [12756]="32687,163436",
+ [12757]="32813,164066", [12772]="38871,194358", [12773]="33080,165400", [12774]="36044,180221", [12775]="39949,199747", [12776]="48125,240625",
+ [12783]="52397,261988", [12784]="65736,328683", [12790]="67161,335809", [12793]="19846,99230", [12794]="50676,253384", [12796]="63825,319127",
+ [12797]="51252,256261", [12798]="51438,257194", [12895]="48071,240359", [12903]="42407,212035", [12905]="15798,78992", [12927]="18492,92460",
+ [12935]="36536,182684", [12936]="18440,92201", [12939]="54330,271653", [12940]="49334,246673", [12945]="39686,198434", [12952]="25957,129789",
+ [12953]="22374,111874", [12963]="24947,124735", [12964]="30051,150258", [12965]="20111,100555", [12966]="12617,63087", [12967]="15196,75984",
+ [12968]="15254,76271", [12969]="63799,318998", [12974]="6105,30526", [12975]="2205,11027", [12976]="1770,8853", [12977]="355,1777",
+ [12982]="851,4255", [12990]="2589,12947", [12994]="788,3940", [13000]="60815,304077", [13003]="49640,248204", [13004]="33591,167955",
+ [13006]="51132,255661", [13010]="2241,11208", [13013]="12355,61779", [13014]="34705,173528", [13015]="52106,260533", [13016]="4771,23856",
+ [13019]="4765,23829", [13020]="8985,44928", [13022]="27990,139953", [13023]="38435,192176", [13026]="19441,97209", [13027]="33832,169161",
+ [13028]="50800,254001", [13034]="14710,73552", [13035]="25141,125707", [13039]="17892,89462", [13041]="4516,22583", [13044]="52800,264001",
+ [13045]="10809,54049", [13046]="35042,175214", [13048]="5971,29859", [13049]="6191,30959", [13051]="22911,114558", [13052]="41677,208389",
+ [13055]="29367,146839", [13056]="48330,241654", [13058]="21833,109168", [13059]="38719,193599", [13066]="15716,78583", [13067]="25098,125493",
+ [13068]="8358,41794", [13070]="24606,123030", [13071]="7148,35743", [13072]="18351,91756", [13073]="15861,79306", [13074]="14043,70219",
+ [13075]="34795,173977", [13076]="8300,41500", [13077]="14478,72394", [13081]="7123,35618", [13082]="13235,66176", [13083]="32348,161741",
+ [13099]="1431,7156", [13103]="3453,17269", [13105]="2147,10738", [13106]="1216,6082", [13107]="10528,52640", [13110]="4968,24841",
+ [13111]="13993,69969", [13112]="9625,48125", [13113]="18492,92463", [13114]="2574,12871", [13115]="6991,34955", [13116]="18705,93529",
+ [13117]="3830,19153", [13120]="9505,47527", [13123]="31130,155651", [13126]="10374,51871", [13133]="22291,111457", [13136]="1456,7281",
+ [13142]="18442,92210", [13144]="6865,34328", [13145]="4760,23800", [13148]="60480,302402", [13161]="63494,317470", [13162]="17945,89728",
+ [13163]="64835,324179", [13166]="24811,124055", [13167]="59410,297053", [13168]="33398,166993", [13181]="8797,43989", [13182]="44142,220713",
+ [13184]="13170,65852", [13185]="15858,79294", [13199]="4399,21995", [13203]="15529,77649", [13204]="51945,259727", [13205]="33829,169146",
+ [13206]="19198,95992", [13208]="12091,60455", [13210]="18024,90123", [13211]="14474,72374", [13216]="12795,63979", [13218]="51556,257784",
+ [13243]="34046,170233", [13244]="14482,72411", [13246]="49997,249986", [13249]="63199,315997", [13252]="12434,62171", [13255]="14366,71834",
+ [13258]="12885,64427", [13259]="27105,135528", [13260]="21787,108938", [13284]="19785,98926", [13286]="44106,220534", [13314]="28178,140893",
+ [13340]="14850,74250", [13344]="15490,77453", [13346]="20807,104038", [13348]="65497,327485", [13349]="52589,262946", [13358]="18933,94669",
+ [13359]="22804,114023", [13360]="50868,254343", [13361]="51060,255302", [13368]="51689,258448", [13369]="15775,78876", [13378]="21972,109861",
+ [13380]="37124,185621", [13381]="26032,130163", [13384]="15819,79097", [13386]="15182,75912", [13387]="15238,76192", [13388]="20392,101963",
+ [13389]="21000,105000", [13390]="15806,79030", [13391]="15861,79309", [13393]="60240,301204", [13394]="31808,159041", [13396]="30853,154266",
+ [13397]="14680,73401", [13398]="18674,93370", [13400]="16361,81809", [13401]="49675,248377", [13404]="15895,79479", [13405]="22885,114427",
+ [13409]="8860,44300", [13474]="24725,123625", [13498]="34808,174044", [13502]="18989,94947", [13505]="82215,411078", [13517]="20000,80000",
+ [13525]="8110,40552", [13526]="10177,50887", [13527]="21414,107072", [13528]="12306,61531", [13529]="31195,155975", [13530]="12232,61161",
+ [13531]="20464,102324", [13532]="12324,61621", [13533]="21607,108039", [13534]="37728,188640", [13537]="10594,52970", [13538]="19223,96116",
+ [13539]="15022,75114", [13817]="18797,93985", [13818]="13431,67158", [13819]="19881,99405", [13822]="11442,57213", [13823]="13107,65537",
+ [13825]="10168,50842", [13860]="8741,43706", [13863]="6617,33086", [13864]="9553,47768", [13867]="12138,60694", [13868]="9665,48329",
+ [13869]="9702,48514", [13870]="5471,27359", [13871]="13436,67184", [13897]="595,2977", [13937]="81129,405649", [13938]="36646,183232",
+ [13944]="24996,124980", [13950]="15335,76675", [13951]="18059,90298", [13952]="52850,264251", [13953]="53034,265172", [13954]="19687,98437",
+ [13955]="27607,138039", [13956]="10574,52873", [13957]="12001,60007", [13959]="16794,83974", [13964]="49986,249934", [13967]="22537,112688",
+ [13969]="15470,77350", [13982]="62847,314236", [13983]="62240,311204", [13984]="52029,260148", [13986]="15723,78619", [14002]="33050,165250",
+ [14024]="50623,253118", [14025]="188,942", [14044]="9503,47517", [14045]="13481,67405", [14089]="30,152", [14090]="119,598",
+ [14091]="120,600", [14093]="21,107", [14094]="121,607", [14095]="36,183", [14098]="43,219", [14099]="47,238",
+ [14102]="60,301", [14103]="9716,48583", [14104]="15484,77421", [14106]="17434,87172", [14107]="13141,65705", [14108]="11112,55561",
+ [14112]="12596,62982", [14115]="70,352", [14121]="579,2898", [14122]="219,1099", [14124]="292,1464", [14126]="396,1984",
+ [14127]="1000,5000", [14130]="12330,61653", [14132]="12441,62207", [14137]="18113,90568", [14139]="15297,76487", [14140]="15565,77825",
+ [14141]="12859,64297", [14144]="14374,71872", [14145]="1238,6194", [14146]="13132,65660", [14147]="374,1872", [14148]="250,1253",
+ [14149]="377,1886", [14150]="504,2524", [14151]="1267,6336", [14152]="26866,134334", [14153]="26965,134825", [14154]="27066,135330",
+ [14157]="434,2170", [14159]="570,2853", [14161]="337,1686", [14162]="445,2229", [14165]="1041,5209", [14167]="358,1794",
+ [14168]="276,1380", [14169]="286,1434", [14172]="837,4189", [14173]="281,1406", [14174]="368,1841", [14175]="847,4236",
+ [14181]="775,3878", [14182]="1167,5837", [14183]="1710,8551", [14186]="1179,5898", [14187]="717,3588", [14190]="1932,9661",
+ [14192]="1946,9733", [14193]="2006,10032", [14194]="756,3782", [14196]="1673,8366", [14197]="925,4626", [14201]="2060,10304",
+ [14202]="3336,16682", [14205]="1042,5213", [14210]="1637,8185", [14211]="1325,6627", [14213]="3553,17769", [14214]="2009,10049",
+ [14221]="1511,7555", [14223]="2699,13495", [14228]="3560,17800", [14231]="1905,9525", [14234]="5240,26201", [14236]="2909,14547",
+ [14237]="7206,36031", [14240]="2294,11474", [14241]="2311,11559", [14242]="5413,27069", [14245]="2346,11734", [14248]="2373,11865",
+ [14250]="3873,19365", [14251]="3332,16662", [14252]="4914,24572", [14254]="7698,38494", [14255]="2629,13145", [14260]="2900,14504",
+ [14263]="5987,29937", [14264]="8013,40067", [14265]="9853,49269", [14267]="9926,49634", [14271]="6599,32996", [14272]="3821,19105",
+ [14273]="6375,31875", [14276]="3598,17992", [14279]="4206,21032", [14280]="5919,29597", [14281]="8178,40891", [14282]="4552,22761",
+ [14284]="13135,65679", [14286]="4620,23104", [14287]="13283,66415", [14291]="4830,24154", [14293]="9857,49288", [14295]="13237,66185",
+ [14296]="7568,37841", [14298]="9629,48145", [14299]="8602,43014", [14301]="5451,27258", [14302]="6517,32588", [14303]="16209,81046",
+ [14304]="6194,30974", [14305]="14349,71748", [14306]="16831,84155", [14307]="12064,60324", [14308]="17188,85944", [14309]="6867,34335",
+ [14310]="11615,58077", [14311]="6524,32622", [14312]="13077,65385", [14313]="9298,46494", [14315]="16550,82753", [14316]="11271,56356",
+ [14317]="16062,80312", [14318]="16569,82846", [14322]="12785,63928", [14323]="8322,41613", [14325]="12751,63758", [14326]="17533,87666",
+ [14327]="7659,38297", [14329]="13115,65577", [14330]="8655,43275", [14331]="11654,58274", [14332]="13616,68082", [14333]="8989,44947",
+ [14334]="18041,90205", [14335]="13578,67894", [14336]="16880,84403", [14337]="8253,41266", [14340]="20305,101528", [14364]="325,1625",
+ [14366]="189,949", [14367]="252,1260", [14369]="809,4049", [14370]="473,2365", [14371]="816,4080", [14373]="525,2625",
+ [14374]="699,3498", [14376]="552,2760", [14379]="1615,8076", [14400]="1215,6079", [14402]="838,4190", [14403]="1017,5089",
+ [14404]="2472,12360", [14405]="2480,12403", [14407]="4266,21332", [14409]="1707,8536", [14410]="2710,13550", [14411]="1387,6939",
+ [14413]="3947,19737", [14417]="5888,29441", [14419]="1919,9597", [14421]="3945,19726", [14422]="2263,11315", [14423]="3406,17034",
+ [14425]="6223,31119", [14426]="2125,10627", [14430]="3686,18433", [14431]="2877,14389", [14432]="4679,23398", [14435]="2778,13894",
+ [14438]="6192,30962", [14441]="7167,35835", [14446]="4248,21242", [14447]="8801,44009", [14449]="10125,50629", [14451]="5537,27685",
+ [14453]="15677,78387", [14454]="5598,27994", [14455]="15792,78963", [14456]="17574,87870", [14457]="7575,37879", [14460]="13196,65982",
+ [14461]="8711,43556", [14462]="17483,87419", [14463]="13160,65800", [14464]="18088,90444", [14465]="8596,42981", [14487]="49623,248119",
+ [14502]="12169,60847", [14503]="18323,91616", [14522]="29200,146003", [14525]="17330,86654", [14528]="31870,159352", [14529]="425,1700",
+ [14536]="31164,155820", [14537]="27688,138441", [14538]="15908,79544", [14539]="19956,99784", [14541]="66079,330395", [14543]="9770,48851",
+ [14545]="24612,123062", [14548]="23116,115582", [14549]="13637,68188", [14552]="26860,134304", [14553]="17125,85625", [14554]="48787,243938",
+ [14555]="70900,354500", [14559]="279,1399", [14560]="484,2422", [14564]="304,1524", [14565]="809,4046", [14569]="472,2361",
+ [14570]="1870,9351", [14572]="609,3048", [14576]="48770,243854", [14577]="20844,104223", [14578]="983,4917", [14580]="818,4094",
+ [14581]="2912,14563", [14582]="1089,5445", [14583]="1333,6669", [14585]="2687,13439", [14587]="2030,10154", [14589]="3294,16474",
+ [14591]="4180,20904", [14594]="2236,11183", [14595]="4500,22503", [14596]="3388,16943", [14602]="2995,14976", [14603]="4383,21917",
+ [14604]="5986,29931", [14608]="3162,15811", [14611]="31394,156970", [14612]="31503,157515", [14614]="15863,79317", [14615]="14404,72024",
+ [14616]="21785,108926", [14620]="17226,86132", [14621]="25741,128709", [14622]="17357,86789", [14623]="34649,173246", [14624]="34776,173882",
+ [14626]="20021,100107", [14629]="10389,51945", [14631]="15694,78470", [14632]="21000,105000", [14633]="15806,79030", [14636]="12048,60240",
+ [14637]="24189,120948", [14638]="24282,121414", [14640]="12233,61167", [14641]="18420,92101", [14652]="4216,21080", [14655]="10392,51963",
+ [14662]="9413,47066", [14663]="5141,25708", [14665]="6214,31073", [14666]="6367,31837", [14667]="10770,53853", [14668]="13597,67985",
+ [14669]="9654,48271", [14675]="8182,40911", [14677]="18524,92622", [14681]="15980,79902", [14685]="10810,54051", [14686]="16495,82478",
+ [14687]="21778,108890", [14688]="16168,80841", [14726]="337,1686", [14727]="778,3891", [14728]="485,2429", [14729]="870,4351",
+ [14743]="583,2917", [14744]="2310,11552", [14746]="589,2948", [14748]="1550,7753", [14750]="1068,5341", [14752]="978,4893",
+ [14755]="1118,5591", [14757]="3298,16492", [14758]="2267,11336", [14759]="2010,10050", [14761]="2024,10123", [14765]="4428,22140",
+ [14767]="4478,22394", [14773]="3052,15264", [14775]="8367,41837", [14779]="13347,66739", [14782]="5004,25024", [14787]="8323,41619",
+ [14791]="6056,30283", [14793]="6985,34927", [14794]="10563,52819", [14796]="16983,84918", [14798]="24037,120186", [14799]="17308,86543",
+ [14800]="25826,129133", [14801]="8156,40783", [14802]="9749,48748", [14807]="8211,41059", [14809]="18905,94527", [14810]="11669,58346",
+ [14811]="25972,129862", [14812]="27804,139024", [14814]="19435,97176", [14815]="12830,64151", [14816]="25752,128764", [14817]="19471,97358",
+ [14821]="9258,46291", [14826]="4068,20342", [14827]="4083,20418", [14828]="6590,32951", [14829]="8837,44186", [14830]="6640,33201",
+ [14831]="7197,35988", [14832]="4160,20804", [14833]="5260,26304", [14834]="4889,24446", [14835]="14337,71689", [14838]="5090,25451",
+ [14839]="8212,41064", [14840]="13869,69349", [14841]="7484,37420", [14842]="12483,62416", [14843]="8796,43982", [14844]="20075,100377",
+ [14846]="7981,39907", [14847]="7487,37439", [14848]="11972,59861", [14849]="14448,72240", [14850]="18275,91376", [14851]="12954,64772",
+ [14853]="7346,36732", [14854]="28358,141792", [14855]="11444,57220", [14856]="10835,54175", [14857]="16185,80928", [14858]="20507,102535",
+ [14859]="25936,129680", [14860]="18380,91904", [14861]="8880,44400", [14862]="28887,144436", [14863]="13995,69978", [14864]="13380,66903",
+ [14865]="20993,104965", [14866]="21662,108312", [14867]="29048,145243", [14868]="22112,110561", [14869]="13336,66681", [14895]="8583,42918",
+ [14896]="5970,29854", [14897]="4025,20126", [14898]="4039,20198", [14899]="6517,32586", [14900]="7521,37608", [14901]="6104,30520",
+ [14903]="3825,19125", [14904]="16179,80899", [14905]="5662,28312", [14906]="5262,26310", [14907]="10696,53483", [14908]="14342,71711",
+ [14909]="8554,42770", [14910]="5339,26698", [14911]="9305,46527", [14913]="11698,58491", [14914]="6318,31593", [14915]="20246,101234",
+ [14917]="6920,34601", [14918]="6432,32161", [14919]="13480,67401", [14920]="17053,85267", [14921]="11191,55956", [14922]="14451,72255",
+ [14923]="8104,40524", [14924]="24555,122778", [14925]="18448,92242", [14926]="9852,49264", [14927]="9329,46648", [14928]="22179,110896",
+ [14929]="15719,78595", [14931]="30265,151328", [14932]="20583,102919", [14933]="13876,69381", [14934]="11887,59436", [14935]="20760,103803",
+ [14936]="28227,141135", [14937]="19923,99615", [14938]="11387,56937", [14939]="11888,59441", [14940]="7090,35453", [14941]="4427,22135",
+ [14942]="4443,22219", [14943]="4460,22303", [14944]="8395,41976", [14945]="11257,56285", [14946]="7251,36257", [14948]="18028,90142",
+ [14949]="6876,34383", [14950]="6390,31950", [14951]="10309,51546", [14952]="12792,63963", [14953]="16028,80140", [14955]="9463,47317",
+ [14956]="5471,27356", [14957]="12617,63088", [14958]="22643,113216", [14959]="9052,45263", [14960]="8572,42864", [14961]="16172,80863",
+ [14962]="20458,102294", [14963]="14501,72505", [14965]="7833,39165", [14966]="30083,150418", [14967]="12087,60436", [14968]="11444,57220",
+ [14969]="21381,106907", [14970]="27297,136487", [14971]="19346,96731", [14972]="18316,91580", [14973]="27810,139052", [14974]="10576,52881",
+ [14975]="29662,148311", [14976]="14191,70956", [14977]="14049,70248", [14978]="21873,109365", [14979]="22251,111257", [14980]="30244,151224",
+ [14981]="22417,112085", [14983]="14054,70272", [15005]="28,142", [15006]="73,365", [15011]="184,920", [15014]="585,2928",
+ [15015]="86,434", [15016]="200,1002", [15019]="366,1834", [15047]="28812,144063", [15048]="24409,122047", [15051]="21736,108684",
+ [15052]="29774,148871", [15055]="15470,77350", [15057]="18728,93643", [15058]="17631,88158", [15063]="11701,58506", [15064]="19717,98586",
+ [15067]="12758,63791", [15068]="20359,101795", [15069]="17013,85065", [15072]="16234,81170", [15074]="6867,34336", [15075]="18449,92246",
+ [15076]="16604,83021", [15078]="9649,48246", [15081]="19566,97830", [15085]="21952,109763", [15087]="17892,89464", [15090]="20514,102573",
+ [15091]="7195,35979", [15094]="14155,70778", [15095]="20885,104427", [15096]="16161,80805", [15104]="3825,19129", [15109]="3344,16724",
+ [15110]="351,1759", [15112]="354,1772", [15114]="372,1863", [15115]="474,2370", [15116]="1163,5817", [15118]="1562,7813",
+ [15119]="13683,68416", [15120]="787,3935", [15124]="847,4238", [15125]="991,4955", [15126]="1989,9948", [15127]="1647,8238",
+ [15128]="2425,12127", [15130]="3252,16263", [15131]="2023,10118", [15132]="1017,5086", [15133]="3827,19135", [15134]="3295,16476",
+ [15136]="1249,6245", [15137]="1516,7584", [15140]="2530,12650", [15142]="2603,13017", [15143]="1439,7198", [15146]="3730,18653",
+ [15147]="1754,8770", [15148]="1614,8070", [15149]="1960,9801", [15150]="2951,14757", [15151]="3949,19748", [15152]="4449,22248",
+ [15154]="2372,11861", [15156]="5266,26333", [15157]="6200,31001", [15158]="4320,21603", [15159]="6743,33716", [15160]="2430,12152",
+ [15162]="5829,29147", [15165]="3744,18724", [15166]="3945,19729", [15168]="7951,39758", [15169]="5542,27714", [15170]="13104,65520",
+ [15171]="8697,43488", [15175]="9692,48463", [15176]="12121,60607", [15177]="8525,42629", [15178]="4936,24680", [15179]="18593,92966",
+ [15182]="5996,29983", [15185]="12906,64530", [15187]="10918,54594", [15189]="15723,78615", [15190]="9614,48071", [15191]="9035,45175",
+ [15192]="10596,52980", [15193]="16397,81987", [15194]="21643,108219", [15195]="22020,110104", [15202]="516,2580", [15203]="621,3108",
+ [15205]="1063,5318", [15207]="914,4571", [15210]="825,4129", [15211]="1917,9585", [15212]="3450,17253", [15215]="16744,83721",
+ [15216]="25932,129662", [15218]="37048,185240", [15219]="41376,206883", [15220]="40552,202761", [15221]="43545,217727", [15225]="5958,29794",
+ [15226]="8755,43779", [15227]="21925,109626", [15228]="28308,141544", [15229]="31924,159623", [15232]="6112,30562", [15233]="10476,52381",
+ [15235]="21091,105455", [15238]="36496,182481", [15239]="40954,204774", [15240]="42810,214051", [15244]="12769,63849", [15246]="42614,213072",
+ [15247]="43935,219676", [15249]="3877,19389", [15250]="6895,34475", [15252]="27906,139531", [15254]="35584,177923", [15255]="42545,212729",
+ [15257]="51499,257499", [15258]="53805,269027", [15259]="3306,16534", [15260]="11556,57784", [15261]="13530,67654", [15263]="28889,144449",
+ [15265]="46823,234117", [15266]="52538,262693", [15267]="54186,270933", [15273]="51401,257005", [15278]="50286,251430", [15283]="32459,162295",
+ [15287]="12516,62584", [15288]="32585,162927", [15289]="34505,172525", [15291]="19591,97959", [15295]="22712,113561", [15296]="31193,155968",
+ [15299]="42,212", [15301]="108,542", [15302]="47,238", [15303]="299,1496", [15304]="414,2072", [15306]="208,1043",
+ [15310]="279,1399", [15311]="982,4914", [15312]="745,3729", [15325]="31785,158925", [15329]="623,3115", [15333]="537,2686",
+ [15334]="828,4142", [15336]="1669,8346", [15337]="2027,10137", [15339]="2466,12334", [15340]="1016,5082", [15344]="2516,12583",
+ [15346]="2788,13942", [15347]="955,4778", [15348]="792,3963", [15349]="1550,7750", [15350]="2385,11925", [15353]="3467,17338",
+ [15354]="1600,8004", [15355]="1620,8101", [15358]="3604,18021", [15359]="5955,29777", [15360]="2372,11862", [15363]="4894,24474",
+ [15364]="2431,12158", [15365]="2415,12079", [15370]="5439,27199", [15371]="3467,17339", [15372]="3383,16918", [15373]="6930,34653",
+ [15374]="7363,36817", [15376]="8653,43267", [15380]="4391,21955", [15381]="12593,62968", [15382]="5043,25216", [15384]="9155,45779",
+ [15386]="7287,36438", [15387]="5584,27920", [15388]="6357,31786", [15390]="16175,80877", [15395]="10379,51899", [15396]="582,2914",
+ [15399]="151,756", [15400]="109,546", [15401]="73,365", [15402]="110,550", [15403]="280,1400", [15404]="337,1686",
+ [15405]="245,1226", [15413]="35470,177351", [15418]="66242,331210", [15421]="16070,80353", [15424]="1404,7024", [15425]="8273,41365",
+ [15429]="9049,45249", [15430]="15435,77177", [15433]="21099,105497", [15434]="10588,52943", [15435]="16380,81903", [15437]="12845,64225",
+ [15438]="11039,55196", [15439]="16841,84208", [15440]="22238,111191", [15441]="16737,83685", [15442]="22996,114983", [15443]="1119,5599",
+ [15445]="1127,5638", [15449]="425,2128", [15450]="534,2670", [15452]="215,1076", [15453]="270,1350", [15457]="1134,5672",
+ [15459]="1142,5713", [15461]="841,4208", [15463]="787,3938", [15466]="2324,11620", [15468]="1207,6036", [15469]="1009,5049",
+ [15470]="2432,12163", [15473]="65,329", [15474]="24,120", [15479]="179,898", [15482]="54,272", [15483]="42,210",
+ [15484]="68,343", [15485]="344,1723", [15489]="363,1818", [15493]="647,3239", [15494]="693,3468", [15496]="462,2310",
+ [15497]="387,1939", [15498]="674,3371", [15499]="307,1536", [15500]="1378,6890", [15503]="1091,5458", [15504]="1168,5844",
+ [15506]="723,3616", [15507]="364,1821", [15508]="365,1828", [15509]="485,2427", [15510]="423,2118", [15511]="1474,7372",
+ [15515]="845,4225", [15516]="1588,7940", [15519]="607,3036", [15520]="879,4398", [15521]="1942,9713", [15524]="2876,14384",
+ [15525]="1634,8172", [15527]="1020,5102", [15528]="931,4655", [15530]="3222,16111", [15535]="1270,6353", [15536]="4107,20538",
+ [15537]="1163,5817", [15543]="4179,20899", [15545]="1348,6741", [15546]="4794,23970", [15548]="1649,8246", [15549]="1504,7524",
+ [15552]="5226,26131", [15553]="3061,15307", [15554]="1853,9268", [15555]="2802,14014", [15556]="1697,8486", [15558]="4128,20644",
+ [15560]="1937,9687", [15561]="4705,23528", [15562]="3558,17791", [15565]="4274,21371", [15567]="6666,33334", [15568]="1814,9070",
+ [15569]="7162,35814", [15571]="2218,11094", [15574]="5150,25752", [15580]="4871,24358", [15581]="2794,13974", [15582]="6544,32722",
+ [15584]="7594,37974", [15585]="1447,7235", [15587]="1822,9111", [15590]="2674,13374", [15591]="8740,43700", [15593]="5532,27664",
+ [15598]="2763,13817", [15599]="6631,33157", [15602]="7211,36056", [15603]="3546,17732", [15606]="3585,17929", [15607]="9306,46530",
+ [15608]="7035,35178", [15609]="11806,59034", [15611]="4369,21848", [15613]="3688,18441", [15618]="11782,58911", [15619]="5987,29937",
+ [15622]="14834,74174", [15624]="4971,24856", [15627]="14493,72469", [15629]="6374,31872", [15634]="11441,57209", [15635]="5896,29484",
+ [15638]="9615,48075", [15644]="8130,40652", [15645]="14577,72888", [15646]="19507,97535", [15653]="8053,40267", [15655]="19862,99311",
+ [15656]="13366,66834", [15658]="17851,89255", [15659]="9508,47541", [15660]="25412,127063", [15663]="10226,51131", [15666]="18375,91878",
+ [15667]="27798,138991", [15668]="11697,58489", [15669]="26609,133046", [15670]="19753,98768", [15671]="9782,48913", [15672]="12164,60822",
+ [15673]="11075,55376", [15674]="18464,92322", [15675]="26976,134880", [15676]="25039,125197", [15677]="18933,94667", [15678]="19525,97627",
+ [15679]="12658,63292", [15681]="11406,57034", [15682]="13149,65749", [15683]="12666,63334", [15684]="20135,100676", [15685]="26587,132937",
+ [15686]="20099,100497", [15687]="27239,136195", [15691]="6909,34546", [15693]="14533,72666", [15695]="5984,29924", [15697]="2826,14130",
+ [15698]="4273,21369", [15703]="9645,48227", [15705]="33774,168871", [15706]="33905,169527", [15708]="9053,45267", [15709]="12796,63981",
+ [15784]="11541,57706", [15786]="19381,96908", [15787]="23343,116716", [15789]="9967,49836", [15791]="7521,37605", [15795]="13431,67158",
+ [15796]="12063,60318", [15797]="14206,71030", [15801]="36221,181109", [15804]="9781,48908", [15806]="49514,247570", [15808]="728,3641",
+ [15811]="5426,27133", [15812]="10076,50383", [15813]="10113,50569", [15815]="12619,63097", [15822]="11446,57230", [15823]="9191,45959",
+ [15824]="15385,76926", [15825]="19302,96513", [15827]="23338,116692", [15858]="7516,37582", [15859]="11317,56587", [15860]="13997,69985",
+ [15861]="14969,74846", [15864]="2043,10215", [15887]="27581,137907", [15890]="25831,129158", [15892]="3582,17912", [15893]="1082,5411",
+ [15894]="1802,9011", [15903]="1623,8118", [15943]="26800,134001", [15991]="26309,131545", [15995]="19739,98698", [15999]="9003,45015",
+ [16007]="39231,196156", [16008]="11739,58697", [16039]="53598,267991", [16369]="7575,37875", [16391]="5087,25436", [16392]="9574,47874",
+ [16393]="9609,48048", [16396]="6650,33250", [16397]="6673,33367", [16401]="12237,61188", [16403]="7401,37008", [16405]="13027,65137",
+ [16406]="8785,43925", [16409]="13227,66135", [16410]="8919,44595", [16413]="10524,52620", [16414]="10562,52812", [16415]="7950,39752",
+ [16416]="7978,39892", [16417]="13345,66727", [16418]="10045,50225", [16419]="13441,67207", [16420]="10116,50580", [16421]="13536,67680",
+ [16422]="13583,67919", [16423]="9251,46256", [16424]="9286,46430", [16425]="14915,74577", [16426]="14972,74864", [16427]="11632,58160",
+ [16428]="11623,58119", [16429]="13585,67927", [16430]="18215,91079", [16431]="18281,91405", [16432]="13734,68674", [16433]="18415,92076",
+ [16434]="13835,69177", [16435]="18547,92738", [16436]="13934,69672", [16485]="7660,38303", [16487]="5145,25727", [16489]="7774,38874",
+ [16490]="10404,52024", [16491]="10716,53584", [16492]="8066,40332", [16494]="10154,50774", [16496]="6168,30843", [16498]="9325,46625",
+ [16499]="6240,31200", [16501]="9431,47159", [16502]="12623,63119", [16503]="9502,47514", [16504]="12718,63592", [16505]="12766,63832",
+ [16506]="9609,48048", [16507]="9903,49516", [16508]="13252,66261", [16509]="13938,69693", [16513]="18886,94434", [16514]="14187,70935",
+ [16515]="19019,95096", [16516]="12928,64641", [16518]="11237,56187", [16519]="7487,37436", [16521]="11316,56580", [16522]="15145,75727",
+ [16523]="15615,78075", [16524]="11806,59033", [16525]="15728,78643", [16526]="11839,59198", [16527]="15843,79218", [16528]="11978,59894",
+ [16530]="8007,40036", [16531]="12107,60538", [16604]="17,87", [16607]="17,88", [16608]="213,1066", [16622]="27307,136536",
+ [16658]="1649,8247", [16661]="1035,5176", [16666]="32368,161841", [16667]="24035,120178", [16668]="29493,147468", [16674]="30993,154969",
+ [16677]="23186,115933", [16678]="30607,153036", [16686]="14836,74182", [16687]="19585,97928", [16688]="20202,101011", [16690]="20355,101778",
+ [16693]="15230,76153", [16694]="20106,100531", [16696]="9058,45293", [16697]="8577,42887", [16698]="15511,77557", [16699]="20475,102377",
+ [16700]="21665,108329", [16702]="8593,42965", [16706]="25058,125293", [16707]="18612,93064", [16709]="24666,123331", [16713]="11197,55985",
+ [16714]="10602,53013", [16716]="11621,58105", [16717]="12244,61224", [16718]="19354,96773", [16719]="26260,131300", [16720]="20037,100187",
+ [16721]="27173,135865", [16722]="14266,71331", [16723]="15180,75904", [16724]="16001,80008", [16725]="23910,119550", [16726]="35078,175392",
+ [16727]="26005,130028", [16728]="34398,171993", [16729]="25488,127443", [16730]="35611,178058", [16731]="26399,131997", [16732]="35849,179248",
+ [16733]="26562,132813", [16734]="25389,126948", [16735]="15379,76897", [16736]="16359,81796", [16737]="17239,86195", [16738]="4235,21176",
+ [16739]="7969,39848", [16740]="1032,5162", [16741]="1295,6476", [16791]="1912,9562", [16793]="4353,21766", [16794]="2899,14499",
+ [16795]="22128,110640", [16796]="27491,137456", [16797]="20698,103491", [16798]="27704,138520", [16799]="13905,69526", [16800]="20935,104677",
+ [16801]="14010,70050", [16802]="14063,70316", [16803]="21174,105874", [16804]="14168,70841", [16805]="14221,71107", [16806]="14274,71373",
+ [16807]="21491,107459", [16808]="21569,107847", [16809]="28865,144328", [16810]="28972,144860", [16811]="21806,109033", [16812]="14591,72955",
+ [16813]="22537,112688", [16814]="30156,150783", [16815]="27382,136910", [16816]="20616,103081", [16817]="13797,68987", [16818]="15636,78182",
+ [16819]="13902,69511", [16820]="34888,174444", [16821]="26266,131332", [16822]="35154,175774", [16823]="26463,132315", [16824]="26562,132814",
+ [16825]="17775,88875", [16826]="17839,89199", [16827]="17906,89531", [16828]="17972,89863", [16829]="27773,138866", [16830]="18580,92901",
+ [16831]="18646,93233", [16832]="31689,158445", [16833]="37559,187796", [16834]="28266,141332", [16835]="34223,171119", [16836]="25767,128838",
+ [16837]="31178,155894", [16838]="20771,103858", [16839]="20851,104256", [16840]="20931,104655", [16841]="42021,210109", [16842]="31632,158164",
+ [16843]="42336,211684", [16844]="32013,160069", [16845]="43794,218973", [16846]="32965,164828", [16847]="44113,220568", [16848]="33352,166762",
+ [16849]="33469,167347", [16850]="22294,111470", [16851]="22373,111869", [16852]="22453,112268", [16853]="52573,262865", [16854]="39494,197470",
+ [16855]="47908,239542", [16856]="36002,180011", [16857]="24275,121379", [16858]="24369,121847", [16859]="36416,182083", [16860]="24554,122770",
+ [16861]="25318,126591", [16862]="37829,189145", [16863]="25505,127527", [16864]="25596,127983", [16865]="51088,255443", [16866]="38382,191914",
+ [16867]="51461,257305", [16868]="38657,193289", [16873]="2469,12346", [16891]="1697,8486", [16897]="39996,199981", [16898]="30106,150533",
+ [16899]="20146,100731", [16900]="30331,151659", [16901]="40592,202963", [16902]="30554,152770", [16903]="20444,102222", [16904]="20519,102597",
+ [16905]="41189,205945", [16906]="31001,155007", [16907]="20742,103713", [16908]="31226,156133", [16909]="38795,193975", [16910]="19472,97363",
+ [16911]="19547,97738", [16912]="23547,117736", [16913]="15756,78783", [16914]="23725,118625", [16915]="31753,158767", [16916]="31873,159368",
+ [16917]="23992,119964", [16918]="16055,80276", [16919]="24173,120865", [16920]="16175,80876", [16921]="24350,121753", [16922]="32587,162938",
+ [16923]="32707,163539", [16924]="24618,123092", [16925]="16902,84512", [16926]="16962,84812", [16927]="25533,127669", [16928]="15456,77281",
+ [16929]="23274,116373", [16930]="31152,155764", [16931]="31273,156365", [16932]="23542,117712", [16933]="15755,78775", [16934]="15815,79075",
+ [16935]="23812,119063", [16936]="23900,119501", [16937]="36145,180727", [16938]="48160,240804", [16939]="36252,181261", [16940]="24258,121291",
+ [16941]="37656,188284", [16942]="50167,250835", [16943]="25171,125855", [16944]="25261,126306", [16945]="38196,190980", [16946]="50882,254414",
+ [16947]="38293,191468", [16948]="23182,115910", [16949]="35063,175317", [16950]="46724,233622", [16951]="27514,137572", [16952]="27620,138101",
+ [16953]="41273,206369", [16954]="55341,276707", [16955]="41584,207921", [16956]="28040,140201", [16957]="43025,215129", [16958]="57681,288409",
+ [16959]="29111,145557", [16960]="29217,146085", [16961]="43651,218255", [16962]="58516,292584", [16963]="43961,219807", [16964]="29637,148185",
+ [16965]="44276,221380", [16966]="59351,296759", [16977]="1536,7682", [16978]="1233,6168", [16979]="13894,69471", [16980]="20632,103164",
+ [16981]="292,1460", [16982]="24397,121986", [16984]="31533,157668", [16985]="847,4239", [16987]="884,4423", [16988]="29333,146667",
+ [16992]="30874,154371", [16993]="30989,154946", [16994]="10368,51840", [16995]="15609,78048", [16996]="38648,193241", [16997]="38790,193951",
+ [16998]="33222,166110", [17002]="43287,216438", [17003]="43439,217195", [17004]="54493,272465", [17007]="11697,58487", [17013]="46272,231363",
+ [17014]="22242,111213", [17015]="53430,267153", [17016]="53627,268138", [17024]="35,700", [17042]="5706,28530", [17043]="3055,15275",
+ [17054]="28788,143943", [17055]="28892,144461", [17066]="45228,226144", [17068]="78453,392265", [17069]="54968,274840", [17070]="76483,382417",
+ [17071]="75814,379072", [17072]="57776,288882", [17073]="91903,459518", [17074]="88668,443341", [17075]="81686,408430", [17076]="106067,530337",
+ [17077]="53771,268855", [17078]="24190,120954", [17102]="23363,116819", [17103]="75431,377159", [17104]="100375,501879", [17105]="74149,370747",
+ [17106]="51180,255901", [17107]="23523,117617", [17112]="73242,366213", [17113]="93061,465307", [17182]="160402,802010", [17183]="7,36",
+ [17184]="7,36", [17185]="52,260", [17186]="52,260", [17187]="232,1161", [17188]="489,2447", [17189]="2610,13054",
+ [17190]="7529,37647", [17192]="964,4820", [17193]="95427,477138", [17223]="87372,436862", [17508]="7880,39403", [17523]="11453,57265",
+ [17562]="7863,39317", [17564]="5280,26400", [17566]="7977,39889", [17567]="10675,53377", [17568]="9949,49749", [17569]="7491,37455",
+ [17570]="7519,37599", [17571]="10064,50324", [17572]="10102,50511", [17573]="7605,38027", [17576]="7690,38454", [17577]="5146,25732",
+ [17594]="7633,38167", [17596]="5126,25633", [17598]="7746,38734", [17599]="10367,51837", [17600]="10680,53403", [17601]="8039,40196",
+ [17610]="7517,37587", [17611]="10061,50308", [17612]="10100,50500", [17613]="7603,38015", [17616]="7895,39477", [17617]="5282,26411",
+ [17686]="10192,50963", [17687]="10231,51155", [17688]="5695,28479", [17704]="9178,45891", [17705]="32854,164273", [17711]="24928,124642",
+ [17714]="11086,55433", [17715]="11125,55626", [17717]="26426,132130", [17721]="2268,11341", [17730]="42952,214760", [17733]="34735,173679",
+ [17734]="18265,91326", [17736]="10532,52660", [17738]="33351,166759", [17739]="9085,45428", [17741]="11516,57580", [17743]="40748,203740",
+ [17745]="22520,112600", [17746]="10608,53042", [17749]="11425,57127", [17750]="6115,30578", [17751]="15344,76724", [17752]="28785,143929",
+ [17755]="5818,29094", [17766]="44863,224318", [17770]="6778,33894", [17775]="7841,39208", [17776]="7377,36889", [17777]="11011,55059",
+ [17778]="4605,23028", [17779]="9689,48446", [17922]="125,629", [17943]="35234,176174", [18043]="15495,77476", [18044]="41478,207391",
+ [18047]="22776,113883", [18048]="49204,246023", [18102]="15444,77220", [18104]="15557,77787", [18168]="47292,236463", [18202]="73256,366284",
+ [18203]="73522,367614", [18204]="22136,110683", [18208]="22741,113705", [18238]="3321,16609", [18256]="1000,20000", [18263]="14690,73454",
+ [18282]="55617,278089", [18305]="25157,125789", [18309]="11808,59044", [18312]="33429,167149", [18313]="23920,119602", [18322]="17677,88385",
+ [18325]="16617,83089", [18326]="16440,82201", [18347]="41589,207948", [18348]="75990,379952", [18349]="12568,62844", [18350]="12615,63077",
+ [18351]="14855,74277", [18352]="27109,135548", [18353]="53142,265714", [18366]="17257,86285", [18372]="52881,264405", [18373]="26535,132675",
+ [18374]="19970,99851", [18375]="13360,66804", [18376]="53632,268163", [18377]="12175,60879", [18378]="29332,146662", [18379]="22182,110913",
+ [18380]="34486,172431", [18382]="14891,74458", [18383]="17301,86505", [18384]="26209,131046", [18385]="20080,100403", [18386]="19882,99411",
+ [18387]="9840,49204", [18388]="39093,195466", [18389]="15692,78462", [18390]="25891,129459", [18391]="13171,65858", [18392]="52875,264379",
+ [18393]="15701,78507", [18394]="15974,79873", [18396]="53627,268138", [18405]="13747,68735", [18407]="10386,51930", [18408]="10422,52114",
+ [18409]="10460,52303", [18413]="15916,79582", [18420]="64117,320585", [18421]="23168,115842", [18424]="19520,97604", [18450]="17016,85083",
+ [18451]="10673,53369", [18459]="14383,71918", [18475]="7907,4024", [18476]="15149,7574", [18477]="19768,10138", [18478]="19768,10176",
+ [18479]="17791,9192", [18480]="11860,10744", [18481]="51451,25725", [18482]="30986,15493", [18483]="37362,189196", [18484]="53822,259877",
+ [18485]="34569,166918", [18486]="20939,104697", [18490]="18655,90077", [18493]="25113,125567", [18494]="21743,108718", [18495]="16770,7547",
+ [18496]="14542,72710", [18497]="9731,48657", [18498]="48836,244183", [18499]="34589,16125", [18500]="31340,12536", [18502]="65385,326927",
+ [18503]="36748,183741", [18504]="13171,65858", [18505]="13218,66094", [18506]="19897,99487", [18507]="15974,79873", [18508]="16031,80157",
+ [18509]="21451,107255", [18510]="19477,97386", [18511]="19553,97765", [18520]="73101,32897", [18521]="17606,13839", [18522]="36253,14501",
+ [18523]="34810,13924", [18524]="35596,16019", [18525]="13730,6698", [18526]="17924,8066", [18527]="17988,8095", [18528]="20465,9881",
+ [18529]="9963,9308", [18530]="31331,14606", [18531]="65383,30548", [18532]="21629,10083", [18533]="10984,9027", [18534]="71503,32178",
+ [18537]="66135,26454", [18538]="96748,43539", [18541]="23110,115553", [18542]="94273,471368", [18544]="19705,98527", [18545]="30875,154376",
+ [18546]="34859,174295", [18547]="28041,140207", [18582]="271161,6122369", [18583]="246242,5559741", [18584]="247199,5581336", [18602]="25000,100000",
+ [18610]="37,185", [18612]="35,177", [18671]="47747,238737", [18673]="30782,153914", [18676]="15529,77645", [18677]="12059,60297",
+ [18680]="36594,182973", [18681]="14693,73469", [18682]="24583,122915", [18683]="49347,246738", [18686]="22869,114345", [18689]="15347,76736",
+ [18690]="35939,179696", [18692]="25109,125545", [18693]="10652,53264", [18694]="24158,120793", [18696]="31173,155867", [18702]="17064,85322",
+ [18712]="10245,51225", [18716]="18015,90077", [18717]="61940,309701", [18718]="26065,130329", [18720]="15036,75183", [18721]="14689,73446",
+ [18722]="17539,87698", [18726]="12029,60146", [18734]="16031,80157", [18735]="16086,80433", [18736]="24346,121733", [18737]="48882,244412",
+ [18738]="36303,181517", [18739]="34010,170051", [18740]="9754,48772", [18741]="17704,88520", [18754]="18806,94033", [18755]="40213,201065",
+ [18756]="31160,155802", [18757]="15069,75348", [18758]="50416,252082", [18759]="63257,316285", [18761]="38238,191190", [18803]="94876,474384",
+ [18805]="76460,382304", [18806]="41261,206308", [18808]="15859,79295", [18809]="14578,72891", [18810]="27440,137202", [18811]="22035,110175",
+ [18812]="22119,110599", [18816]="80298,401493", [18817]="35861,179307", [18822]="94642,473212", [18823]="19235,96177", [18824]="40964,204823",
+ [18829]="32943,164717", [18832]="72832,364162", [18841]="250,1000", [18842]="97012,485061", [18861]="48152,240763", [18870]="30139,150697",
+ [18872]="27356,136783", [18875]="35039,175198", [18878]="71794,358972", [19019]="123140,615704", [19037]="10266,51333", [19040]="19817,99086",
+ [19048]="24376,121882", [19049]="13531,67655", [19050]="16295,81478", [19051]="16483,82416", [19057]="17744,88723", [19058]="18977,94885",
+ [19059]="15238,76192", [19106]="66021,330108", [19107]="39756,198784", [19108]="39896,199484", [19112]="17650,88251", [19113]="12583,62918",
+ [19114]="18282,91414", [19117]="16127,80637", [19121]="9007,45035", [19124]="14453,72268", [19126]="7833,39168", [19130]="54431,272157",
+ [19131]="21586,107931", [19132]="21400,107000", [19133]="29722,148614", [19134]="17969,89849", [19135]="14066,70331", [19136]="15029,75148",
+ [19137]="28803,144017", [19139]="28496,142482", [19143]="27183,135917", [19144]="34596,172980", [19145]="29952,149763", [19146]="18542,92714",
+ [19148]="35881,179408", [19149]="17185,85928", [19156]="28236,141180", [19157]="22350,111754", [19162]="19474,97371", [19163]="19544,97720",
+ [19164]="27616,138083", [19165]="31491,157457", [19166]="75133,375665", [19167]="94248,471244", [19168]="71993,359967", [19169]="90341,451706",
+ [19170]="72552,362763", [19334]="100551,502757", [19335]="80731,403656", [19346]="79053,395266", [19347]="82129,410645", [19348]="50969,254848",
+ [19349]="52946,264730", [19350]="60867,304337", [19351]="81453,407267", [19352]="85814,429072", [19353]="105206,526031", [19354]="91123,455619",
+ [19355]="95910,479550", [19356]="102955,514777", [19357]="96642,483211", [19358]="91409,457045", [19360]="83625,418127", [19361]="60230,301150",
+ [19362]="74238,371192", [19363]="84569,422845", [19364]="106097,530487", [19365]="79672,398362", [19367]="60199,300997", [19368]="62010,310053",
+ [19369]="16212,81060", [19370]="24405,122025", [19372]="43435,217175", [19373]="38038,190194", [19374]="15284,76423", [19375]="25143,125716",
+ [19378]="25432,127162", [19380]="25624,128122", [19381]="32152,160761", [19385]="33472,167360", [19386]="25195,125976", [19387]="44162,220812",
+ [19388]="16916,84583", [19389]="31832,159162", [19390]="21297,106488", [19391]="25645,128229", [19392]="30198,150990", [19393]="25828,129140",
+ [19394]="40037,200186", [19396]="19250,96251", [19398]="23275,116379", [19399]="31153,155766", [19400]="16061,80306", [19401]="48361,241809",
+ [19402]="56624,283121", [19405]="40891,204455", [19407]="16473,82368", [19430]="24972,124863", [19433]="46932,234661", [19435]="55695,278479",
+ [19436]="22359,111799", [19437]="22443,112219", [19438]="22804,114020", [19439]="38148,190741", [19682]="20986,104934", [19683]="21065,105328",
+ [19684]="15856,79283", [19685]="26526,132632", [19686]="13312,66562", [19687]="13361,66808", [19688]="26819,134095", [19689]="20188,100940",
+ [19690]="33265,166327", [19691]="25148,125744", [19692]="16749,83746", [19693]="35490,177452", [19694]="35628,178141", [19695]="26773,133867",
+ [19852]="73811,369057", [19853]="55563,277816", [19854]="92937,464686", [19855]="52235,261179", [19857]="22550,112752", [19859]="75706,378532",
+ [19861]="57183,285918", [19862]="48971,244856", [19864]="77063,385316", [19865]="77328,386644", [19866]="70360,351800", [19867]="70626,353130",
+ [19869]="14200,71004", [19870]="17104,85523", [19874]="90591,452959", [19875]="26132,130661", [19877]="29245,146226", [19878]="30760,153801",
+ [19884]="87276,436380", [19886]="16849,84249", [19887]="33827,169136", [19888]="16975,84878", [19889]="28398,141994", [19890]="71409,357047",
+ [19892]="21535,107679", [19894]="20364,101822", [19895]="23224,116120", [19896]="72049,360249", [19897]="21693,108468", [19899]="21077,105386",
+ [19900]="66122,330610", [19901]="53102,265511", [19903]="68651,343255", [19904]="41348,206740", [19906]="20294,101474", [19907]="16295,81478",
+ [19908]="52467,262337", [19909]="87773,438869", [19910]="70474,352373", [19913]="29103,145517", [19915]="36742,183713", [19918]="93051,465256",
+ [19919]="23814,119073", [19921]="51094,255472", [19927]="52265,261326", [19928]="20444,102221", [19929]="11356,56780", [19944]="86115,430576",
+ [19945]="25933,129665", [19946]="67629,338145", [19961]="53080,265400", [19962]="66605,333029", [19963]="68686,343433", [19964]="55154,275770",
+ [19965]="55358,276793", [19967]="41821,209108", [19968]="55966,279834", [19990]="25000,100000", [19991]="10000,40000", [19992]="10000,40000",
+ [19993]="42730,213650", [19998]="19457,97288", [19999]="15625,78126", [20006]="8375,33500", [20032]="27040,135201", [20037]="15003,60012",
+ [20038]="52549,262745", [20039]="38754,193772", [20130]="10000,40000", [20134]="30246,151234", [20213]="20119,100599", [20215]="17271,86358",
+ [20216]="14445,72227", [20217]="11598,57991", [20257]="23207,116037", [20258]="63375,316878", [20259]="12724,63621", [20260]="31854,159273",
+ [20261]="12821,64107", [20262]="24182,120911", [20263]="27080,135401", [20264]="25299,126495", [20265]="28353,141765", [20266]="38019,190096",
+ [20380]="43614,218072", [20475]="6250,25000", [20476]="15292,76460", [20477]="15755,78777", [20478]="31624,158121", [20479]="31734,158673",
+ [20480]="15924,79620", [20481]="15980,79904", [20503]="10000,40000", [20512]="10000,40000", [20517]="17113,85565", [20521]="17358,86790",
+ [20534]="3975,15903", [20537]="15963,79816", [20538]="21361,106806", [20539]="10717,53589", [20549]="18192,90961", [20550]="36308,181541",
+ [20551]="27279,136399", [20577]="72906,364533", [20578]="73189,365949", [20579]="22041,110209", [20580]="73748,368742", [20581]="92539,462697",
+ [20599]="55093,275466", [20615]="19996,99980", [20616]="28254,141271", [20617]="44264,221323", [20618]="14810,74053", [20619]="38954,194770",
+ [20621]="33455,167276", [20623]="29073,145369", [20625]="15433,77168", [20626]="15488,77444", [20627]="38863,194318", [20628]="29608,148041",
+ [20629]="35813,179069", [20630]="27991,139956", [20631]="23655,118278", [20633]="30139,150698", [20634]="30247,151236", [20635]="31990,159954",
+ [20637]="38649,193248", [20638]="45658,228293", [20639]="53469,267345", [20640]="8405,42027", [20646]="35956,179781", [20647]="48117,240585",
+ [20648]="52827,264138", [20650]="14980,74902", [20653]="15141,75705", [20657]="48687,243437", [20662]="21659,108299", [20664]="8909,44547",
+ [20665]="25775,128879", [20666]="51740,258704", [20667]="11258,56294", [20668]="31268,156342", [20669]="65379,326895", [20670]="12679,63395",
+ [20671]="34239,171196", [20672]="36826,184133", [20673]="15048,75242", [20674]="19792,98961", [20675]="49664,248324", [20680]="24739,123698",
+ [20681]="13734,68672", [20683]="28999,144996", [20684]="16664,83320", [20686]="17224,86123", [20687]="20282,101412", [20688]="47483,237416",
+ [20689]="21761,108805", [20690]="10538,52693", [20691]="20361,101805", [20693]="11985,59926", [20696]="63158,315791", [20697]="15213,76069",
+ [20698]="67873,339366", [20699]="35767,178838", [20700]="35901,179509", [20701]="30885,154425", [20702]="31824,159120", [20703]="26616,133080",
+ [20704]="26711,133559", [20705]="21444,107220", [20706]="21520,107604", [20707]="21597,107987", [20710]="25873,129365", [20711]="25973,129867",
+ [20712]="14926,74631", [20713]="14983,74919", [20714]="18801,94008", [20715]="18873,94368", [20716]="10103,50516", [20717]="10141,50708",
+ [20720]="54064,270320", [20722]="40843,204216", [20723]="43760,218803", [20724]="54892,274463", [20812]="5,20", [20813]="4,16",
+ [20815]="200,800", [20816]="20,80", [20817]="100,400", [20818]="625,2500", [20820]="1064,4258", [20821]="1064,4258",
+ [20823]="837,3350", [20824]="6250,25000", [20826]="2207,8830", [20827]="875,3500", [20828]="677,2710", [20830]="1535,6140",
+ [20831]="1535,6140", [20832]="1800,9003", [20833]="1540,6160", [20835]="25,129", [20836]="25,129", [20837]="26,130",
+ [20838]="19,98", [20839]="32,164", [20840]="26,131", [20841]="16,84", [20842]="5,20", [20843]="6,24",
+ [20845]="4,16", [20846]="5,20", [20847]="6,24", [20848]="5,20", [20849]="16,84", [20850]="16,84",
+ [20851]="17,85", [20852]="17,85", [20853]="21,107", [20854]="450,1800", [20855]="375,1500", [20856]="375,1500",
+ [20857]="1,25", [20891]="1,5", [20892]="1,5", [20893]="1,5", [20894]="1,5", [20895]="1,5",
+ [20896]="1,4", [20897]="1,4", [20898]="1,3", [20899]="1,4", [20900]="1,3", [20901]="1,4",
+ [20906]="250,1000", [20907]="300,1200", [20909]="1010,4040", [20910]="12,63", [20911]="7,37", [20912]="16,84",
+ [20914]="7,39", [20915]="12,60", [20916]="7,36", [20917]="7,36", [20918]="14,72", [20919]="14,73",
+ [20920]="6,30", [20921]="9,46", [20922]="6,30", [20923]="6,30", [20924]="12,62", [20925]="12,62",
+ [20950]="1535,6140", [20954]="5681,28409", [20955]="665,2660", [20957]="875,3500", [20958]="1130,4520", [20959]="1720,6880",
+ [20960]="1720,6880", [20961]="1720,6880", [20963]="900,3600", [20964]="6646,26584", [20966]="3482,13930", [20967]="3482,13930",
+ [20969]="5989,29947", [20970]="375,1500", [20971]="375,1500", [20973]="500,2000", [20974]="625,2500", [20975]="625,2500",
+ [20976]="0,3500", [20978]="9,47", [20980]="5,27", [20981]="7,37", [20982]="7,37", [20983]="7,37",
+ [20985]="7,38", [20986]="10,51", [20987]="5,25", [20988]="5,25", [20989]="5,25", [20990]="10,52",
+ [20991]="7,36", [20992]="4,24", [20993]="6,30", [20994]="14,73", [20995]="4,24", [20996]="6,30",
+ [20997]="11,56", [20998]="4,24", [20999]="7,37", [21000]="6,31", [21001]="10,50", [21002]="1,7",
+ [21003]="3,16", [21004]="5,25", [21005]="1,7", [21006]="2,10", [21007]="4,22", [21008]="3,17",
+ [21009]="4,20", [21010]="2,13", [21011]="2,13", [21012]="2,13", [21013]="2,12", [21014]="8,40",
+ [21015]="1,7", [21016]="9,49", [21017]="2,14", [21018]="3,16", [21019]="3,16", [21020]="3,16",
+ [21021]="7,35", [21022]="3,16", [21126]="85698,428491", [21128]="97775,488877", [21134]="110377,551889", [21178]="13268,66344",
+ [21183]="20620,103103", [21184]="23671,118358", [21186]="13550,67753", [21187]="15299,76499", [21188]="89953,449769", [21242]="82145,410728",
+ [21244]="82758,413792", [21268]="86208,431040", [21269]="55371,276859", [21272]="65581,327907", [21273]="109680,548400", [21275]="99954,499771",
+ [21278]="9126,45632", [21316]="21713,108565", [21322]="26439,132197", [21329]="43010,215053", [21330]="41773,208865", [21331]="62274,311370",
+ [21332]="58117,290587", [21333]="42255,211279", [21334]="35991,179955", [21335]="24374,121870", [21336]="33714,168572", [21337]="25378,126892",
+ [21338]="24648,123240", [21343]="37212,186064", [21344]="25198,125991", [21345]="25947,129739", [21346]="35883,179415", [21347]="27007,135037",
+ [21348]="24526,122632", [21349]="23821,119106", [21350]="23913,119566", [21351]="35581,177907", [21352]="33203,166015", [21353]="31246,156234",
+ [21354]="30349,151746", [21355]="30464,152322", [21356]="42134,210672", [21357]="45491,227459", [21359]="30922,154610", [21360]="32073,160368",
+ [21361]="31974,159870", [21362]="44219,221095", [21364]="47900,239501", [21365]="39091,195455", [21366]="40364,201823", [21367]="40683,203418",
+ [21368]="49042,245214", [21370]="53161,265808", [21372]="37349,186748", [21373]="36438,182192", [21374]="53975,269878", [21375]="50365,251828",
+ [21376]="36851,184255", [21387]="47159,235798", [21388]="41438,207190", [21389]="61776,308883", [21390]="57649,288245", [21391]="41916,209583",
+ [21452]="96177,480887", [21453]="40467,202338", [21454]="35033,175166", [21455]="22403,112016", [21456]="23424,117120", [21457]="27585,137925",
+ [21458]="20174,100872", [21459]="60738,303692", [21460]="42586,212930", [21461]="29522,147610", [21462]="14816,74084", [21463]="22311,111556",
+ [21464]="14931,74657", [21466]="72521,362608", [21467]="36399,181995", [21468]="17462,87311", [21469]="14605,73027", [21470]="17592,87962",
+ [21472]="22251,111257", [21474]="22909,114547", [21475]="42918,214592", [21476]="36919,184596", [21478]="57620,288102", [21479]="27139,135696",
+ [21480]="18501,92506", [21481]="29346,146732", [21482]="25412,127062", [21484]="21244,106221", [21485]="45658,228292", [21486]="25208,126040",
+ [21487]="21566,107830", [21489]="17319,86599", [21490]="31182,155911", [21491]="14931,74656", [21492]="91625,458125", [21493]="27587,137936",
+ [21494]="14736,73680", [21495]="41405,207027", [21496]="11872,59363", [21497]="26928,134640", [21498]="74888,374443", [21499]="30059,150295",
+ [21500]="12041,60206", [21501]="13668,68342", [21502]="16466,82330", [21503]="19392,96964", [21517]="24982,124911", [21520]="85129,425646",
+ [21521]="77306,386531", [21523]="80049,400246", [21527]="32868,164340", [21530]="49843,249218", [21532]="31380,156900", [21581]="31789,158945",
+ [21582]="18128,90642", [21583]="27295,136475", [21585]="18333,91666", [21586]="23611,118055", [21598]="29215,146078", [21599]="24994,124974",
+ [21600]="25090,125451", [21602]="21633,108167", [21603]="63026,315134", [21604]="17433,87168", [21605]="21869,109346", [21606]="30903,154518",
+ [21607]="26433,132168", [21609]="22184,110923", [21610]="56995,284978", [21611]="17874,89373", [21615]="24614,123070", [21616]="59764,298824",
+ [21617]="19998,99991", [21618]="29040,145200", [21619]="16561,82807", [21621]="25024,125120", [21622]="83720,418602", [21623]="29577,147888",
+ [21624]="25297,126489", [21626]="50964,254822", [21627]="25286,126431", [21635]="100824,504123", [21639]="42897,214489", [21645]="31380,156900",
+ [21648]="25088,125442", [21650]="79141,395706", [21651]="47667,238335", [21652]="55824,279120", [21663]="33225,166129", [21665]="31373,156869",
+ [21667]="54142,270713", [21668]="46588,232941", [21669]="29227,146136", [21671]="31415,157079", [21672]="19707,98539", [21673]="79132,395660",
+ [21674]="27960,139801", [21675]="19933,99665", [21676]="32009,160049", [21679]="106933,534669", [21680]="41536,207682", [21682]="20921,104609",
+ [21683]="44157,220785", [21684]="38221,191108", [21686]="25548,127742", [21688]="40213,201069", [21689]="19260,96301", [21691]="27324,136622",
+ [21692]="27429,137145", [21693]="29332,146663", [21694]="23555,117775", [21696]="31641,158205", [21697]="23819,119099", [21698]="38927,194637",
+ [21699]="36256,181283", [21701]="24238,121190", [21703]="101707,508537", [21704]="42787,213938", [21705]="37039,185197", [21706]="43087,215437",
+ [21708]="18740,93703", [21710]="26680,133402", [21715]="78119,390595", [21748]="1500,6000", [21752]="1250,5000", [21753]="5000,20000",
+ [21754]="4307,17230", [21755]="4307,17230", [21756]="1500,6000", [21758]="1500,6000", [21760]="1500,6000", [21763]="1500,6000",
+ [21764]="6420,25680", [21765]="2542,10170", [21766]="7500,30000", [21767]="8375,33500", [21768]="12500,50000", [21769]="1500,6000",
+ [21774]="11416,57083", [21775]="8375,33500", [21777]="3750,15000", [21778]="18662,74651", [21779]="21305,85220", [21784]="15000,60000",
+ [21789]="15000,60000", [21790]="7767,31068", [21791]="12503,50012", [21792]="25218,100872", [21800]="39523,197619", [21801]="39677,198386",
+ [21802]="53107,265538", [21803]="27935,139678", [21804]="24080,120400", [21805]="28147,140736", [21806]="69942,349713", [21810]="17039,85196",
+ [21814]="56555,282778", [21835]="125,500", [21837]="79716,398584", [21838]="31996,159984", [21839]="92916,464583", [21840]="4000,16000",
+ [21841]="10000,40000", [21842]="8000,32000", [21843]="10000,40000", [21844]="8000,32000", [21845]="4000,16000", [21846]="21632,108162",
+ [21847]="21712,108562", [21848]="43584,217923", [21849]="12261,61307", [21850]="12306,61531", [21851]="13059,65299", [21852]="26926,134630",
+ [21853]="21336,106682", [21854]="29267,146337", [21855]="30091,150457", [21856]="99282,496413", [21858]="20000,80000", [21859]="31883,159418",
+ [21860]="24616,123080", [21861]="34308,171542", [21862]="34437,172187", [21863]="20474,102374", [21864]="30824,154120", [21865]="41251,206258",
+ [21866]="17197,85985", [21867]="26309,131549", [21868]="35486,177430", [21869]="32801,164009", [21870]="32921,164609", [21871]="44055,220278",
+ [21872]="40000,160000", [21873]="24089,120445", [21874]="33398,166991", [21875]="46852,234263", [21876]="50000,200000", [21877]="800,3200",
+ [21878]="10000,40000", [21881]="5000,20000", [21882]="2500,10000", [21884]="4000,16000", [21885]="4000,16000", [21886]="4000,16000",
+ [21887]="1250,5000", [21888]="15430,77153", [21889]="28578,142892", [21890]="24445,122228", [21892]="10000,40000", [21893]="10000,40000",
+ [21894]="10000,40000", [21895]="10000,40000", [21896]="10000,40000", [21897]="10000,40000", [21898]="15000,60000", [21899]="15000,60000",
+ [21900]="15000,60000", [21901]="15000,60000", [21902]="20000,80000", [21903]="15000,60000", [21904]="15000,60000", [21905]="15000,60000",
+ [21906]="15000,60000", [21907]="20000,80000", [21908]="15000,60000", [21909]="15000,60000", [21910]="15000,60000", [21911]="15000,60000",
+ [21912]="15000,60000", [21913]="15000,60000", [21914]="15000,60000", [21915]="0,60000", [21916]="15000,60000", [21917]="15000,60000",
+ [21918]="15000,60000", [21919]="15000,60000", [21927]="125,500", [21929]="2500,10000", [21931]="250,1000", [21932]="250,1000",
+ [21933]="750,3000", [21934]="1500,6000", [21940]="1250,5000", [21941]="1250,5000", [21942]="1500,6000", [21943]="1500,6000",
+ [21944]="1875,7500", [21945]="1875,7500", [21947]="1875,7500", [21948]="1875,7500", [21949]="2500,10000", [21952]="2500,10000",
+ [21953]="3125,12500", [21954]="2500,10000", [21955]="0,12500", [21956]="0,12500", [21957]="3375,13500", [21990]="1275,5100",
+ [21991]="3000,12000", [21992]="5000,20000", [21993]="10000,40000", [21994]="18406,92033", [21995]="34276,171384", [21996]="18543,92717",
+ [21997]="46128,230643", [21998]="17731,88655", [21999]="34787,173939", [22000]="37912,189563", [22001]="28117,140588", [22002]="13464,67320",
+ [22004]="13913,69569", [22007]="25791,128959", [22008]="19166,95832", [22010]="15451,77256", [22011]="15508,77543", [22012]="12500,50000",
+ [22016]="23809,119045", [22017]="32137,160687", [22053]="150,600", [22054]="150,600", [22055]="175,700", [22062]="11049,55245",
+ [22063]="11088,55442", [22067]="20624,103124", [22068]="15749,78749", [22070]="10578,52893", [22071]="10618,53090", [22072]="21591,107955",
+ [22073]="16043,80217", [22078]="10891,54457", [22079]="10929,54649", [22082]="16572,82860", [22085]="21034,105173", [22086]="18341,91705",
+ [22087]="34151,170759", [22088]="18477,92389", [22089]="45966,229831", [22090]="17667,88335", [22091]="34662,173313", [22092]="37780,188903",
+ [22093]="28020,140100", [22095]="16158,80792", [22098]="16334,81670", [22100]="30953,154768", [22101]="23106,115533", [22106]="13023,65118",
+ [22108]="13122,65610", [22111]="26883,134418", [22112]="19976,99883", [22146]="100000,400000", [22147]="1250,5000", [22148]="375,1500",
+ [22153]="100000,400000", [22179]="13500,54000", [22180]="6500,26000", [22181]="9000,36000", [22182]="16750,67000", [22183]="8000,32000",
+ [22184]="11000,44000", [22185]="9000,36000", [22186]="13500,54000", [22187]="16750,67000", [22188]="7250,29000", [22189]="16750,67000",
+ [22190]="9000,36000", [22191]="47549,237749", [22194]="23455,117276", [22195]="17221,86107", [22196]="56466,282334", [22197]="18915,94579",
+ [22198]="47188,235942", [22205]="14998,74994", [22207]="15047,75239", [22212]="18636,93180", [22223]="19722,98614", [22231]="15880,79400",
+ [22232]="14421,72107", [22242]="11923,59617", [22247]="16087,80438", [22267]="16084,80423", [22269]="16199,80998", [22270]="20755,103775",
+ [22301]="20983,104919", [22302]="15795,78977", [22303]="20853,104269", [22304]="10322,51612", [22305]="15538,77690", [22306]="10396,51980",
+ [22311]="14758,73794", [22313]="9912,49564", [22314]="62189,310945", [22315]="49937,249689", [22317]="50306,251530", [22318]="37869,189347",
+ [22322]="51234,256170", [22325]="12019,60095", [22328]="34980,174902", [22330]="14701,73507", [22332]="50053,250267", [22333]="62803,314016",
+ [22335]="64130,320650", [22336]="32957,164786", [22337]="15506,77531", [22342]="21605,108029", [22343]="16260,81301", [22345]="14620,73101",
+ [22347]="38332,191664", [22348]="64134,320670", [22377]="54468,272342", [22378]="54665,273326", [22379]="54862,274311", [22380]="55053,275269",
+ [22383]="73223,366118", [22384]="72503,362516", [22385]="44234,221172", [22394]="64707,323539", [22396]="25392,126962", [22398]="15755,78777",
+ [22399]="25666,128332", [22401]="15924,79620", [22402]="25942,129714", [22404]="52913,264568", [22405]="14415,72077", [22406]="61968,309841",
+ [22407]="18658,93293", [22408]="38489,192448", [22409]="25755,128778", [22410]="15509,77546", [22411]="27190,135951", [22412]="15624,78122",
+ [22416]="68505,342525", [22417]="66097,330489", [22418]="49653,248265", [22419]="48830,244154", [22420]="49006,245030", [22421]="33715,168576",
+ [22422]="31441,157208", [22423]="31561,157808", [22424]="31681,158409", [22425]="65783,328919", [22426]="31919,159595", [22427]="63714,318572",
+ [22428]="47873,239368", [22429]="47082,235412", [22430]="47257,236289", [22431]="32516,162583", [22436]="58712,293564", [22437]="56644,283221",
+ [22438]="39580,197903", [22439]="39109,195545", [22440]="39260,196301", [22441]="26691,133458", [22442]="26794,133970", [22443]="26896,134482",
+ [22445]="0,24000", [22446]="0,120000", [22447]="0,40000", [22448]="0,72000", [22449]="0,72000", [22450]="0,120000",
+ [22451]="4000,16000", [22452]="4000,16000", [22456]="4000,16000", [22457]="4000,16000", [22459]="0,120000", [22460]="0,72000",
+ [22461]="1250,5000", [22462]="32000,128000", [22463]="40000,160000", [22464]="56155,280779", [22465]="54191,270957", [22466]="40797,203986",
+ [22467]="40302,201512", [22468]="40453,202268", [22469]="27502,137513", [22470]="28338,141693", [22471]="28438,142192", [22476]="50184,250923",
+ [22477]="48416,242084", [22478]="32973,164867", [22479]="32436,162182", [22480]="32562,162810", [22481]="22238,111192", [22482]="22321,111607",
+ [22483]="22406,112034", [22488]="48769,243845", [22489]="47055,235279", [22490]="35416,177082", [22491]="34830,174152", [22492]="34955,174779",
+ [22493]="23864,119323", [22494]="23950,119750", [22495]="24035,120177", [22496]="40143,200719", [22497]="38726,193631", [22498]="26376,131880",
+ [22499]="25946,129732", [22500]="26046,130234", [22501]="17787,88935", [22502]="18344,91721", [22503]="18412,92063", [22504]="38446,192234",
+ [22505]="37094,185473", [22506]="27923,139617", [22507]="27462,137314", [22508]="27560,137802", [22509]="18818,94093", [22510]="18886,94434",
+ [22511]="18955,94776", [22512]="39571,197859", [22513]="38179,190899", [22514]="28737,143686", [22515]="28260,141302", [22516]="28358,141790",
+ [22517]="19361,96806", [22518]="18071,90356", [22519]="18139,90697", [22521]="1500,6000", [22522]="1500,6000", [22525]="200,800",
+ [22526]="200,800", [22527]="200,800", [22528]="200,800", [22529]="200,800", [22530]="15000,60000", [22531]="15000,60000",
+ [22532]="15000,60000", [22533]="15000,60000", [22534]="20000,80000", [22535]="25000,100000", [22536]="25000,100000", [22537]="25000,100000",
+ [22538]="50000,200000", [22539]="15000,60000", [22540]="15000,60000", [22541]="20000,80000", [22542]="10000,40000", [22543]="15000,60000",
+ [22544]="15000,60000", [22545]="15000,60000", [22547]="15000,60000", [22548]="15000,60000", [22551]="15000,60000", [22552]="15000,60000",
+ [22553]="20000,80000", [22554]="15000,60000", [22555]="20000,80000", [22556]="15000,60000", [22557]="25000,100000", [22558]="25000,100000",
+ [22559]="15000,60000", [22560]="15000,60000", [22561]="15000,60000", [22562]="12500,50000", [22563]="17500,70000", [22565]="15000,60000",
+ [22571]="62,250", [22572]="400,1600", [22573]="400,1600", [22574]="400,1600", [22575]="400,1600", [22576]="400,1600",
+ [22577]="400,1600", [22578]="400,1600", [22579]="0,325", [22589]="184558,922791", [22630]="185158,925791", [22631]="172821,864107",
+ [22632]="173474,867372", [22641]="146,585", [22642]="146,585", [22644]="12,48", [22645]="25,100", [22647]="100,400",
+ [22652]="33356,166784", [22654]="16804,84020", [22655]="16865,84325", [22656]="49612,248063", [22658]="25580,127901", [22660]="17213,86069",
+ [22661]="43100,215503", [22662]="21628,108144", [22663]="22267,111336", [22664]="48533,242666", [22665]="24360,121804", [22666]="24455,122275",
+ [22669]="57715,288576", [22670]="29130,145650", [22671]="29240,146203", [22688]="52177,260885", [22689]="19639,98195", [22690]="31542,157711",
+ [22691]="110631,553155", [22699]="61463,307317", [22700]="35244,176221", [22701]="44212,221061", [22702]="53243,266215", [22710]="30,120",
+ [22712]="16737,83685", [22713]="55994,279973", [22714]="19782,98910", [22715]="16919,84597", [22716]="11320,56602", [22718]="21379,106897",
+ [22720]="17224,86123", [22730]="18480,92404", [22731]="27821,139105", [22756]="23205,116029", [22757]="17465,87328", [22758]="17528,87642",
+ [22759]="20424,102123", [22760]="20503,102516", [22761]="13719,68599", [22762]="38562,192812", [22763]="19465,97326", [22764]="19537,97685",
+ [22775]="75,300", [22776]="25,100", [22777]="37,150", [22778]="700,2800", [22779]="700,2800", [22783]="1387,6938",
+ [22784]="802,3210", [22785]="500,2000", [22786]="500,2000", [22787]="600,2400", [22788]="750,3000", [22789]="500,2000",
+ [22790]="750,3000", [22791]="1000,4000", [22792]="1250,5000", [22793]="2500,10000", [22794]="10000,40000", [22797]="1250,5000",
+ [22798]="111458,557292", [22799]="111889,559447", [22800]="105618,528092", [22801]="106023,530119", [22802]="90536,452684", [22803]="83651,418256",
+ [22804]="85783,428915", [22806]="84594,422974", [22807]="86747,433735", [22808]="89393,446969", [22809]="112147,560738", [22810]="66096,330484",
+ [22811]="67768,338842", [22812]="72327,361637", [22813]="111341,556706", [22815]="112134,560673", [22816]="91970,459852", [22818]="53656,268280",
+ [22819]="58990,294952", [22820]="63364,316822", [22821]="69654,348274", [22823]="2500,10000", [22824]="2500,10000", [22825]="2500,10000",
+ [22826]="2500,10000", [22827]="2500,10000", [22828]="2500,10000", [22829]="5000,20000", [22830]="4000,16000", [22831]="4000,16000",
+ [22832]="5000,20000", [22833]="2500,10000", [22834]="4000,16000", [22835]="6000,24000", [22836]="5000,20000", [22837]="5000,20000",
+ [22838]="5000,20000", [22839]="5000,20000", [22840]="6000,24000", [22841]="6000,24000", [22842]="6000,24000", [22844]="6000,24000",
+ [22845]="6000,24000", [22846]="6000,24000", [22847]="6000,24000", [22848]="7000,28000", [22849]="7000,28000", [22850]="7000,28000",
+ [22851]="20000,80000", [22853]="20000,80000", [22854]="20000,80000", [22861]="20000,80000", [22866]="20000,80000", [22871]="5000,20000",
+ [22900]="7500,30000", [22901]="7500,30000", [22902]="10000,40000", [22903]="10000,40000", [22904]="10000,40000", [22905]="12500,50000",
+ [22907]="12500,50000", [22908]="15000,60000", [22909]="12500,50000", [22910]="20000,80000", [22911]="12500,50000", [22912]="20000,80000",
+ [22913]="20000,80000", [22914]="20000,80000", [22915]="20000,80000", [22917]="20000,80000", [22918]="20000,80000", [22919]="25000,100000",
+ [22920]="15000,60000", [22921]="15000,60000", [22922]="25000,100000", [22923]="25000,100000", [22924]="25000,100000", [22925]="25000,100000",
+ [22926]="25000,100000", [22927]="15000,60000", [22936]="30895,154479", [22938]="26523,132618", [22940]="46667,233339", [22941]="33516,167580",
+ [22942]="87803,439016", [22951]="27,136", [22952]="16,84", [22953]="33,169", [22956]="57,285", [22957]="57,286",
+ [22958]="182,914", [22959]="183,918", [22960]="26713,133565", [22963]="149,745", [22964]="24,123", [22965]="20,103",
+ [22966]="16,82", [22967]="41269,206348", [22968]="25550,127754", [22969]="230,1150", [22971]="231,1158", [22976]="250,1000",
+ [22979]="403,1615", [22980]="2493,12467", [22982]="1507,7535", [22983]="26999,134997", [22984]="1879,9395", [22985]="407,2038",
+ [22986]="272,1364", [22987]="342,1712", [22988]="85160,425804", [22990]="576,2883", [22991]="208,1042", [22992]="261,1308",
+ [22993]="316,1582", [22995]="2448,12240", [22996]="911,4558", [22997]="1072,5361", [22998]="717,3587", [23000]="63636,318181",
+ [23004]="25159,125795", [23005]="25253,126268", [23006]="25351,126755", [23009]="64100,320503", [23014]="85238,426191", [23017]="27110,135550",
+ [23019]="47692,238460", [23020]="34249,171245", [23021]="18331,91655", [23030]="25734,128674", [23032]="25926,129634", [23033]="40081,200406",
+ [23035]="26915,134577", [23039]="113747,568736", [23043]="57405,287026", [23044]="83837,419187", [23045]="27117,135588", [23050]="28385,141928",
+ [23054]="95047,475239", [23056]="95737,478687", [23068]="61207,306038", [23069]="35844,179222", [23070]="35976,179884", [23071]="44201,221008",
+ [23072]="33544,167721", [23073]="33391,166956", [23075]="57402,287014", [23077]="2500,10000", [23078]="18870,94354", [23079]="2500,10000",
+ [23081]="12591,62957", [23082]="15167,75836", [23084]="10187,50936", [23085]="20451,102255", [23087]="36057,180289", [23088]="31018,155093",
+ [23089]="25944,129724", [23090]="18332,91663", [23091]="10454,52273", [23092]="15737,78689", [23093]="13162,65814", [23094]="2500,10000",
+ [23095]="2500,10000", [23096]="2500,10000", [23097]="2500,10000", [23098]="2500,10000", [23099]="2500,10000", [23100]="2500,10000",
+ [23101]="2500,10000", [23103]="2500,10000", [23104]="2500,10000", [23105]="2500,10000", [23106]="2500,10000", [23107]="2500,10000",
+ [23108]="2500,10000", [23109]="2500,10000", [23110]="2500,10000", [23111]="2500,10000", [23112]="2500,10000", [23113]="2500,10000",
+ [23114]="2500,10000", [23115]="2500,10000", [23116]="2500,10000", [23117]="2500,10000", [23118]="2500,10000", [23119]="2500,10000",
+ [23120]="2500,10000", [23121]="2500,10000", [23124]="61095,305478", [23126]="9847,49239", [23127]="15448,77243", [23128]="10198,50994",
+ [23130]="10000,40000", [23131]="12500,50000", [23132]="53100,265504", [23133]="15000,60000", [23134]="15000,60000", [23135]="10000,40000",
+ [23136]="12500,50000", [23137]="15000,60000", [23138]="15000,60000", [23139]="31549,157749", [23140]="10000,40000", [23141]="12500,50000",
+ [23142]="15000,60000", [23143]="15000,60000", [23144]="10000,40000", [23145]="12500,50000", [23146]="15000,60000", [23147]="15000,60000",
+ [23148]="10000,40000", [23149]="12500,50000", [23150]="15000,60000", [23151]="15000,60000", [23152]="10000,40000", [23153]="12500,50000",
+ [23154]="15000,60000", [23155]="15000,60000", [23173]="1357,6789", [23178]="4230,21152", [23197]="15690,78453", [23198]="15749,78749",
+ [23199]="15808,79044", [23200]="15867,79339", [23201]="15925,79627", [23203]="16043,80217", [23219]="31190,155951", [23220]="35572,177862",
+ [23221]="87413,437066", [23226]="45674,228370", [23238]="55321,276609", [23242]="94813,474065", [23265]="58,293", [23266]="98,491",
+ [23267]="59,295", [23321]="1,5", [23322]="1,4", [23329]="5,12", [23331]="4,16", [23332]="3,12",
+ [23333]="5,20", [23334]="10,40", [23344]="1,4", [23345]="1,4", [23346]="9,45", [23347]="5,27",
+ [23348]="1,5", [23353]="3,12", [23354]="6,25", [23355]="200,800", [23367]="9,49", [23370]="38,191",
+ [23371]="48,240", [23372]="72,361", [23373]="58,290", [23375]="19,97", [23376]="11,58", [23377]="15,78",
+ [23380]="25,100", [23381]="10,40", [23383]="15,60", [23384]="15,60", [23385]="15,60", [23386]="17,70",
+ [23389]="15,60", [23390]="31,159", [23391]="25,128", [23392]="25,128", [23393]="25,129", [23395]="73,366",
+ [23396]="115,575", [23397]="23,115", [23398]="86,434", [23399]="100,503", [23400]="255,1275", [23401]="802,3210",
+ [23402]="577,2886", [23403]="347,1738", [23404]="218,1090", [23405]="194,973", [23406]="368,1844", [23407]="246,1234",
+ [23408]="309,1548", [23409]="1072,5362", [23410]="1435,7176", [23411]="1800,9003", [23412]="429,2148", [23413]="286,1431",
+ [23414]="359,1795", [23415]="726,3633", [23423]="297,1485", [23424]="1000,4000", [23425]="1500,6000", [23426]="2500,10000",
+ [23427]="1250,5000", [23429]="303,1519", [23430]="243,1219", [23431]="244,1224", [23436]="30000,120000", [23437]="30000,120000",
+ [23438]="30000,120000", [23439]="30000,120000", [23440]="30000,120000", [23441]="30000,120000", [23444]="110,440", [23445]="2000,8000",
+ [23446]="3000,12000", [23447]="2500,10000", [23448]="22500,90000", [23449]="12500,50000", [23473]="1,1", [23474]="1,5",
+ [23475]="1,5", [23476]="1,7", [23477]="1,4", [23478]="1,4", [23479]="1,4", [23482]="20269,101347",
+ [23484]="20969,104846", [23487]="33419,167096", [23488]="44805,224026", [23489]="47475,237376", [23490]="39760,198800", [23491]="18866,94332",
+ [23493]="27683,138418", [23494]="19615,98076", [23497]="58164,290820", [23498]="60063,300318", [23499]="79583,397916", [23502]="82647,413237",
+ [23503]="85143,425716", [23504]="68364,341822", [23505]="70380,351901", [23506]="28586,142931", [23507]="58548,292740", [23508]="28793,143968",
+ [23509]="62984,314922", [23510]="31529,157648", [23511]="47104,235520", [23512]="64163,320818", [23513]="64391,321957", [23514]="32234,161172",
+ [23515]="29607,148038", [23516]="44599,222998", [23517]="30311,151556", [23518]="60504,302520", [23519]="45822,229114", [23520]="30896,154481",
+ [23521]="46159,230797", [23522]="61891,309456", [23523]="61628,308141", [23524]="31103,155519", [23525]="46837,234185", [23526]="26912,134563",
+ [23527]="54020,270104", [23528]="750,3000", [23529]="1000,4000", [23530]="12000,48000", [23531]="31259,156296", [23532]="36818,184091",
+ [23533]="36955,184775", [23534]="47423,237118", [23535]="55431,277158", [23536]="55635,278177", [23537]="37514,187570", [23538]="37654,188274",
+ [23539]="37795,188977", [23540]="107762,538812", [23541]="135202,676014", [23542]="108562,542810", [23543]="136202,681010", [23544]="109350,546753",
+ [23546]="137687,688438", [23553]="176,881", [23554]="105375,526875", [23555]="105763,528819", [23556]="106163,530818", [23557]="63465,317327",
+ [23559]="750,3000", [23560]="0,1", [23561]="0,1", [23562]="0,1", [23563]="68232,341164", [23564]="80028,400144",
+ [23565]="91327,456637", [23571]="16000,64000", [23572]="16000,0", [23573]="30000,120000", [23574]="20000,80000", [23575]="1500,6000",
+ [23576]="1250,5000", [23577]="91925,459627", [23585]="200,4000", [23586]="85,340", [23587]="18522,92614", [23590]="10000,40000",
+ [23591]="10000,40000", [23592]="10000,40000", [23593]="10000,40000", [23594]="15000,60000", [23595]="15000,60000", [23596]="15000,60000",
+ [23597]="15000,60000", [23598]="15000,60000", [23599]="15000,60000", [23600]="20000,80000", [23601]="15000,60000", [23602]="15000,60000",
+ [23603]="15000,60000", [23604]="20000,80000", [23605]="15000,60000", [23606]="15000,60000", [23607]="15000,60000", [23608]="60000,240000",
+ [23609]="60000,240000", [23610]="60000,240000", [23611]="20000,80000", [23612]="20000,80000", [23613]="25000,100000", [23615]="15000,60000",
+ [23617]="15000,60000", [23618]="15000,60000", [23619]="15000,60000", [23620]="120000,480000", [23621]="120000,480000", [23622]="120000,480000",
+ [23623]="120000,480000", [23624]="120000,480000", [23625]="120000,480000", [23626]="120000,480000", [23627]="120000,480000", [23628]="120000,480000",
+ [23629]="120000,480000", [23630]="120000,480000", [23631]="120000,480000", [23632]="120000,480000", [23633]="120000,480000", [23634]="120000,480000",
+ [23635]="120000,480000", [23636]="120000,480000", [23637]="120000,480000", [23638]="15000,60000", [23639]="75000,300000", [23663]="25793,128966",
+ [23664]="39007,195037", [23665]="51978,259893", [23666]="30610,153053", [23667]="45741,228708", [23668]="61330,306654", [23676]="5,20",
+ [23711]="4500,18000", [23730]="6500,26000", [23731]="15000,60000", [23734]="3750,15000", [23736]="2500,10000", [23737]="2500,10000",
+ [23742]="47216,236084", [23745]="3750,15000", [23746]="55725,278627", [23747]="62413,312067", [23748]="66312,331560", [23755]="15000,60000",
+ [23756]="10,40", [23758]="29667,148336", [23761]="20534,102671", [23762]="25324,126620", [23763]="31774,158870", [23764]="2500,10000",
+ [23765]="2500,10000", [23766]="20000,80000", [23767]="5000,20000", [23768]="250,1000", [23769]="250,1000", [23771]="250,1000",
+ [23772]="20,8000", [23773]="2,1000", [23774]="30000,120000", [23781]="500,2000", [23782]="8000,32000", [23783]="1500,6000",
+ [23784]="10000,40000", [23785]="30000,120000", [23786]="12000,48000", [23787]="12000,48000", [23793]="6250,25000", [23799]="20000,80000",
+ [23800]="25000,100000", [23802]="37500,150000", [23803]="15000,60000", [23804]="20000,80000", [23805]="20000,80000", [23806]="40000,160000",
+ [23807]="15000,60000", [23808]="40000,160000", [23809]="15000,60000", [23810]="20000,80000", [23811]="15000,60000", [23814]="15000,60000",
+ [23815]="15000,60000", [23816]="10000,40000", [23819]="6000,24000", [23821]="15000,60000", [23822]="100000,400000", [23823]="100000,400000",
+ [23824]="32734,163670", [23825]="17096,85481", [23826]="3000,12000", [23827]="4000,16000", [23828]="30547,152738", [23829]="38321,191607",
+ [23831]="5000,20000", [23832]="5000,20000", [23835]="22500,90000", [23836]="22500,90000", [23838]="29454,147271", [23839]="44345,221729",
+ [23840]="10000,40000", [23841]="3000,12000", [23844]="666,2665", [23848]="500,2000", [23852]="875,3500", [23854]="4000,16000",
+ [23855]="4000,16000", [23858]="1500,6000", [23866]="1500,6000", [23867]="1500,6000", [23868]="1500,6000", [23874]="20000,80000",
+ [23883]="17500,70000", [23884]="20000,80000", [23887]="15000,60000", [23888]="6000,24000", [23909]="7,36", [23920]="3,15",
+ [23922]="27,110", [23923]="582,2914", [23924]="17,87", [23931]="16,81", [23938]="1325,5300", [23939]="1185,4740",
+ [23944]="7,7", [23945]="8,8", [23946]="9,9", [23947]="14,14", [23948]="17,17", [23949]="22,22",
+ [23965]="870,3480", [23976]="705,2820", [23977]="498,1992", [23978]="605,2420", [23979]="990,3960", [23987]="25,25",
+ [23988]="30,30", [23999]="2500,10000", [24000]="15000,60000", [24001]="12500,50000", [24002]="15000,60000", [24003]="15000,60000",
+ [24004]="2500,10000", [24006]="100,2000", [24007]="100,2000", [24008]="225,4500", [24009]="225,4500", [24020]="63979,319899",
+ [24021]="44959,224798", [24022]="38681,193409", [24023]="16179,80897", [24024]="19489,97449", [24027]="30000,120000", [24028]="30000,120000",
+ [24029]="30000,120000", [24030]="30000,120000", [24031]="30000,120000", [24032]="30000,120000", [24033]="30000,120000", [24035]="30000,120000",
+ [24036]="30000,120000", [24037]="30000,120000", [24039]="30000,120000", [24044]="81199,405999", [24045]="13782,55130", [24046]="40337,201685",
+ [24047]="30000,120000", [24048]="30000,120000", [24050]="30000,120000", [24051]="30000,120000", [24052]="30000,120000", [24053]="30000,120000",
+ [24054]="30000,120000", [24055]="30000,120000", [24056]="30000,120000", [24057]="30000,120000", [24058]="30000,120000", [24059]="30000,120000",
+ [24060]="30000,120000", [24061]="30000,120000", [24062]="30000,120000", [24063]="16619,83096", [24064]="34963,174819", [24065]="30000,120000",
+ [24066]="30000,120000", [24067]="30000,120000", [24069]="84950,424751", [24072]="6,125", [24073]="10283,41135", [24074]="24491,97964",
+ [24075]="24491,97964", [24076]="25650,102600", [24077]="27388,109552", [24078]="27388,109552", [24079]="38775,155100", [24080]="39122,156488",
+ [24082]="39122,156488", [24083]="26588,132940", [24085]="39470,157880", [24086]="39818,159272", [24087]="37037,148148", [24088]="39122,156488",
+ [24089]="39818,159272", [24090]="20458,102292", [24091]="24092,120460", [24092]="39470,157880", [24093]="39470,157880", [24094]="80302,401510",
+ [24095]="39470,157880", [24096]="44030,176121", [24097]="39470,157880", [24098]="39470,157880", [24103]="29,148", [24104]="33,166",
+ [24105]="6,24", [24106]="39122,156488", [24107]="145,729", [24108]="121,609", [24109]="48,244", [24110]="39122,156488",
+ [24111]="126,632", [24112]="76,380", [24113]="46,230", [24114]="39470,157880", [24116]="39470,157880", [24117]="39818,159272",
+ [24118]="1500,6000", [24119]="1500,6000", [24120]="1500,6000", [24121]="39818,159272", [24122]="30597,152988", [24123]="30712,153561",
+ [24124]="12000,48000", [24125]="15000,60000", [24126]="15000,60000", [24127]="15000,60000", [24128]="15000,60000", [24129]="6,32",
+ [24130]="7,39", [24131]="7,39", [24133]="14,72", [24134]="12,60", [24135]="9,48", [24136]="284,1421",
+ [24138]="286,1431", [24141]="23,117", [24142]="20,100", [24143]="1,5", [24144]="16,81", [24145]="1,5",
+ [24146]="1,3", [24150]="20984,104920", [24151]="75303,301215", [24154]="13782,55130", [24155]="80578,402894", [24158]="30000,120000",
+ [24159]="15000,60000", [24160]="15000,60000", [24161]="35000,140000", [24162]="35000,140000", [24163]="30000,120000", [24164]="30000,120000",
+ [24165]="35000,140000", [24166]="30000,120000", [24167]="30000,120000", [24168]="30000,120000", [24169]="30000,120000", [24170]="35000,140000",
+ [24171]="35000,140000", [24172]="15000,60000", [24173]="15000,60000", [24174]="30000,120000", [24175]="30000,120000", [24176]="30000,120000",
+ [24177]="30000,120000", [24178]="30000,120000", [24179]="30000,120000", [24180]="30000,120000", [24181]="30000,120000", [24182]="30000,120000",
+ [24183]="30000,120000", [24186]="50,200", [24188]="125,500", [24189]="1500,6000", [24190]="400,1600", [24192]="30000,120000",
+ [24193]="30000,120000", [24194]="30000,120000", [24195]="30000,120000", [24196]="30000,120000", [24197]="30000,120000", [24198]="30000,120000",
+ [24199]="30000,120000", [24200]="30000,120000", [24201]="30000,120000", [24202]="30000,120000", [24203]="30000,120000", [24204]="30000,120000",
+ [24205]="30000,120000", [24206]="30000,120000", [24207]="30000,120000", [24208]="30000,120000", [24209]="30000,120000", [24210]="30000,120000",
+ [24211]="30000,120000", [24212]="30000,120000", [24213]="30000,120000", [24214]="30000,120000", [24215]="30000,120000", [24216]="30000,120000",
+ [24217]="30000,120000", [24218]="30000,120000", [24219]="30000,120000", [24220]="30000,120000", [24234]="500,2000", [24235]="800,3200",
+ [24241]="7,39", [24242]="1500,6000", [24243]="2250,9000", [24245]="146,585", [24246]="400,1600", [24249]="16563,82815",
+ [24250]="16626,83133", [24251]="16690,83451", [24252]="25128,125640", [24253]="25223,126117", [24254]="26001,130008", [24255]="21880,109404",
+ [24256]="21960,109804", [24257]="22040,110204", [24258]="33181,165905", [24259]="33297,166489", [24260]="33417,167088", [24261]="44716,223584",
+ [24262]="44876,224383", [24263]="45032,225161", [24264]="33894,169470", [24266]="30889,154448", [24267]="31006,155032", [24268]="100,400",
+ [24269]="100,400", [24270]="30000,120000", [24271]="4000,16000", [24272]="4000,16000", [24273]="20000,80000", [24274]="50000,200000",
+ [24275]="20000,80000", [24276]="50000,200000", [24285]="375000,1500000", [24286]="125000,500000", [24288]="15000,60000", [24291]="500,2000",
+ [24292]="15000,60000", [24293]="15000,60000", [24294]="90000,360000", [24295]="90000,360000", [24296]="20000,80000", [24297]="20000,80000",
+ [24298]="20000,80000", [24299]="20000,80000", [24300]="20000,80000", [24301]="20000,80000", [24302]="30000,120000", [24303]="30000,120000",
+ [24304]="30000,120000", [24305]="30000,120000", [24306]="30000,120000", [24307]="30000,120000", [24308]="15000,60000", [24309]="15000,60000",
+ [24310]="15000,60000", [24311]="15000,60000", [24312]="15000,60000", [24313]="15000,60000", [24314]="10000,40000", [24316]="10000,40000",
+ [24334]="798,3993", [24338]="200,4000", [24339]="299,1498", [24340]="120,601", [24341]="90,453", [24342]="355,1776",
+ [24343]="475,2377", [24345]="100000,400000", [24346]="421,2106", [24347]="528,2643", [24348]="636,3183", [24349]="412,1650",
+ [24350]="412,1650", [24351]="1456,7284", [24352]="1827,9138", [24353]="1100,5502", [24354]="1840,9203", [24356]="74307,371539",
+ [24357]="44738,223693", [24359]="27182,135911", [24360]="20465,102329", [24361]="68476,342380", [24362]="20621,103109", [24363]="48302,241512",
+ [24364]="48487,242436", [24365]="17381,86905", [24366]="31544,157720", [24368]="500,2000", [24376]="1807,7230", [24378]="74821,374105",
+ [24379]="20384,101922", [24380]="51153,255769", [24381]="51351,256758", [24384]="69061,345306", [24385]="19646,78585", [24386]="20872,104360",
+ [24387]="24577,122887", [24388]="21023,105118", [24389]="52751,263755", [24390]="20737,82948", [24391]="35419,177099", [24392]="14219,71096",
+ [24393]="14270,71352", [24394]="89510,447550", [24395]="14371,71857", [24396]="36056,180283", [24397]="28947,144738", [24398]="27234,136172",
+ [24401]="750,3000", [24402]="12,50", [24403]="1000,4000", [24404]="500,2000", [24405]="500,2000", [24406]="750,3000",
+ [24407]="1000,4000", [24408]="1000,4000", [24412]="6,5000", [24413]="22693,113467", [24417]="2,2000", [24423]="15,75",
+ [24424]="12,63", [24425]="10,50", [24429]="2000,8000", [24430]="184,924", [24431]="152,761", [24432]="172,864",
+ [24433]="104,520", [24434]="174,871", [24435]="24,124", [24436]="13,68", [24437]="11,55", [24438]="122,613",
+ [24439]="153,769", [24440]="185,927", [24441]="18,93", [24442]="43,215", [24444]="57,289", [24445]="43,217",
+ [24446]="36,182", [24447]="67,339", [24448]="150,753", [24449]="146,585", [24450]="15352,76760", [24451]="23107,115536",
+ [24452]="17487,87438", [24453]="70222,351112", [24454]="21148,105740", [24455]="35379,176895", [24456]="49720,248603", [24457]="37361,186808",
+ [24458]="25193,125967", [24459]="21551,107755", [24460]="32466,129865", [24461]="90474,452373", [24462]="10283,41135", [24463]="39226,196132",
+ [24464]="75131,375656", [24465]="45241,226208", [24466]="37833,189167", [24476]="100,400", [24477]="100,400", [24478]="1000,4000",
+ [24479]="1000,4000", [24481]="29723,148619", [24490]="0,1", [24507]="870,3480", [24508]="1185,4740", [24510]="990,3960",
+ [24511]="1325,5300", [24516]="870,3480", [24517]="990,3960", [24519]="1185,4740", [24521]="1325,5300", [24540]="1000,4000",
+ [24575]="10617,53086", [24576]="3666,18334", [24577]="5520,27600", [24578]="3693,18467", [24580]="5579,27897", [24582]="16765,83827",
+ [24583]="22431,112156", [24584]="11255,56276", [24585]="15332,76661", [24586]="20522,102612", [24587]="15449,77248", [24588]="10339,51697",
+ [24589]="10715,53578", [24590]="16134,80674", [24591]="21592,107964", [24592]="11130,55653", [24593]="16757,83788", [24594]="22423,112116",
+ [24595]="16878,84394", [24596]="11293,56467", [24597]="11690,58451", [24598]="17597,87985", [24599]="23547,117737", [24600]="11815,59079",
+ [24601]="17787,88936", [24602]="23798,118993", [24603]="17912,89561", [24604]="11983,59919", [24605]="11214,56071", [24606]="16885,84425",
+ [24607]="22600,113002", [24608]="11655,58277", [24609]="17546,87734", [24610]="23482,117414", [24611]="17677,88387", [24612]="11828,59142",
+ [24613]="12221,61107", [24614]="18399,91997", [24615]="24622,123112", [24616]="12356,61780", [24617]="18599,92997", [24618]="24888,124444",
+ [24619]="18733,93669", [24620]="12534,62670", [24621]="12938,64693", [24622]="19477,97385", [24623]="26061,130308", [24624]="12158,60792",
+ [24625]="18306,91534", [24626]="24501,122507", [24627]="18445,92226", [24628]="12341,61708", [24629]="12733,63666", [24630]="19171,95855",
+ [24631]="25656,128281", [24632]="12874,64371", [24633]="19382,96912", [24634]="25938,129690", [24635]="19524,97623", [24636]="13062,65312",
+ [24637]="13465,67328", [24638]="20271,101357", [24639]="27126,135630", [24640]="12642,63210", [24641]="19036,95180", [24642]="25478,127394",
+ [24643]="19180,95901", [24644]="12835,64177", [24645]="13224,66122", [24646]="19911,99558", [24647]="26646,133231", [24648]="13373,66865",
+ [24649]="20134,100672", [24650]="26946,134730", [24651]="20282,101412", [24652]="13571,67858", [24653]="13972,69860", [24654]="21035,105175",
+ [24655]="28146,140732", [24656]="14491,72458", [24657]="21814,109071", [24658]="26412,132061", [24659]="19886,99430", [24660]="13308,66543",
+ [24661]="13695,68475", [24662]="20619,103097", [24663]="27597,137988", [24664]="13851,69256", [24665]="20855,104279", [24666]="27910,139550",
+ [24667]="21011,105056", [24668]="14060,70300", [24669]="14458,72290", [24670]="21765,108828", [24671]="29128,145642", [24672]="15003,75018",
+ [24673]="22583,112919", [24674]="30219,151097", [24675]="22745,113727", [24676]="15217,76087", [24677]="15634,78173", [24678]="21298,106491",
+ [24679]="28507,142539", [24680]="14309,71545", [24681]="21544,107720", [24682]="28835,144177", [24683]="21709,108546", [24684]="14528,72640",
+ [24685]="14921,74609", [24686]="22467,112337", [24687]="30069,150347", [24688]="15495,77475", [24689]="23324,116624", [24690]="31212,156062",
+ [24691]="23494,117470", [24692]="15717,78587", [24693]="13872,69360", [24694]="20882,104412", [24695]="27942,139712", [24696]="14019,70097",
+ [24697]="21103,105518", [24698]="25553,127769", [24699]="19239,96199", [24700]="12874,64374", [24701]="13343,66716", [24702]="20091,100458",
+ [24703]="26891,134457", [24704]="13862,69311", [24705]="20870,104351", [24706]="27929,139646", [24707]="21021,105108", [24708]="14065,70328",
+ [24709]="14560,72800", [24710]="21919,109596", [24711]="29328,146643", [24712]="14717,73585", [24713]="22154,110774", [24714]="29645,148227",
+ [24715]="22311,111555", [24716]="14926,74634", [24717]="15435,77178", [24718]="21026,105134", [24719]="28141,140708", [24720]="14515,72575",
+ [24721]="21854,109270", [24722]="29244,146224", [24723]="22015,110076", [24724]="14731,73656", [24725]="15222,76112", [24726]="22915,114577",
+ [24727]="30665,153329", [24728]="15389,76945", [24729]="23167,115837", [24730]="30999,154995", [24731]="23333,116666", [24732]="15611,78057",
+ [24733]="16117,80585", [24734]="24259,121299", [24735]="32461,162308", [24736]="15142,75710", [24737]="22797,113986", [24738]="30511,152557",
+ [24739]="22970,114850", [24740]="15371,76855", [24741]="15857,79287", [24742]="23875,119375", [24743]="31951,159759", [24744]="16035,80175",
+ [24745]="24139,120696", [24746]="32304,161520", [24747]="24316,121584", [24748]="16270,81352", [24749]="16771,83856", [24750]="25248,126240",
+ [24751]="33785,168929", [24752]="15743,78716", [24753]="23703,118519", [24754]="31726,158634", [24755]="23886,119432", [24756]="15983,79917",
+ [24757]="16468,82341", [24758]="24796,123980", [24759]="33186,165931", [24760]="16653,83269", [24761]="25074,125372", [24762]="33557,167788",
+ [24763]="25261,126309", [24764]="16902,84510", [24765]="17401,87005", [24766]="26197,130989", [24767]="35058,175292", [24768]="17591,87958",
+ [24769]="27171,135858", [24770]="36357,181785", [24771]="24761,123807", [24772]="16571,82858", [24773]="17053,85266", [24774]="25678,128392",
+ [24775]="34365,171828", [24776]="17248,86242", [24777]="25971,129856", [24778]="34759,173798", [24779]="26165,130828", [24780]="17509,87547",
+ [24781]="18005,90026", [24782]="3572,17861", [24783]="27207,136035", [24784]="36410,182053", [24785]="18754,93772", [24786]="28229,141149",
+ [24787]="37774,188872", [24788]="28431,142158", [24789]="19021,95108", [24790]="19543,97716", [24791]="26622,133114", [24792]="35634,178174",
+ [24793]="17886,89431", [24794]="26930,134650", [24795]="36044,180222", [24796]="27136,135683", [24797]="18160,90800", [24798]="18652,93261",
+ [24799]="28084,140421", [24800]="37586,187933", [24801]="19366,96834", [24802]="29156,145780", [24803]="39015,195078", [24804]="29367,146837",
+ [24805]="19646,98234", [24806]="16646,83232", [24807]="25170,125851", [24808]="33531,167655", [24809]="16823,84117", [24810]="25324,126622",
+ [24811]="30664,153323", [24812]="23190,115951", [24813]="15449,77248", [24814]="16011,80059", [24815]="24217,121086", [24816]="32269,161348",
+ [24817]="16634,83173", [24818]="25044,125221", [24819]="33515,167576", [24820]="25338,126691", [24821]="16878,84394", [24822]="17472,87360",
+ [24823]="26420,132100", [24824]="35194,175971", [24825]="17660,88302", [24826]="26585,132929", [24827]="35574,177872", [24828]="26892,134462",
+ [24829]="17912,89561", [24830]="18522,92614", [24831]="25344,126721", [24832]="33770,168850", [24833]="17418,87090", [24834]="26225,131125",
+ [24835]="35093,175468", [24836]="26535,132678", [24837]="17677,88387", [24838]="18266,91334", [24839]="27620,138103", [24840]="36799,183995",
+ [24841]="18466,92334", [24842]="27801,139005", [24843]="37198,185994", [24844]="28124,140622", [24845]="18733,93669", [24846]="19340,96703",
+ [24847]="29241,146206", [24848]="38954,194770", [24849]="18170,90852", [24850]="27356,136783", [24851]="36613,183069", [24852]="27686,138433",
+ [24853]="18445,92226", [24854]="19028,95144", [24855]="28777,143886", [24856]="38342,191711", [24857]="19242,96210", [24858]="28967,144835",
+ [24859]="38764,193824", [24860]="29310,146550", [24861]="19524,97623", [24862]="20125,100627", [24863]="30432,152162", [24864]="40543,202715",
+ [24865]="18890,94450", [24866]="28444,142223", [24867]="38072,190361", [24868]="28791,143955", [24869]="19180,95901", [24870]="19761,98809",
+ [24871]="29887,149437", [24872]="39823,199117", [24873]="19984,99923", [24874]="30089,150447", [24875]="40269,201345", [24876]="30449,152245",
+ [24877]="20282,101412", [24878]="20881,104406", [24879]="31577,157885", [24880]="42070,210351", [24881]="21660,108302", [24882]="32606,163030",
+ [24883]="43628,218142", [24884]="29845,149229", [24885]="19886,99430", [24886]="20463,102319", [24887]="30951,154755", [24888]="41238,206194",
+ [24889]="20698,103491", [24890]="31165,155827", [24891]="41711,208558", [24892]="31538,157691", [24893]="21011,105056", [24894]="21606,108032",
+ [24895]="32675,163376", [24896]="43531,217656", [24897]="22424,112123", [24898]="33758,168790", [24899]="45167,225839", [24900]="34148,170740",
+ [24901]="22745,113727", [24902]="23371,116857", [24903]="35334,176671", [24904]="42596,212982", [24905]="21380,106904", [24906]="32195,160976",
+ [24907]="43088,215440", [24908]="32584,162921", [24909]="21709,108546", [24910]="22300,111502", [24911]="33723,168617", [24912]="44934,224674",
+ [24913]="23157,115789", [24914]="34860,174301", [24915]="46649,233248", [24916]="35270,176350", [24917]="23494,117470", [24918]="19462,97310",
+ [24919]="29075,145379", [24920]="38980,194903", [24921]="19671,98357", [24922]="29384,146924", [24923]="39393,196967", [24924]="26780,133902",
+ [24925]="18059,90298", [24926]="18715,93576", [24927]="27967,139838", [24928]="37504,187523", [24929]="19445,97229", [24930]="29055,145276",
+ [24931]="38957,194788", [24932]="29269,146349", [24933]="19732,98662", [24934]="20426,102131", [24935]="30518,152590", [24936]="40916,204581",
+ [24937]="20647,103236", [24938]="30847,154235", [24939]="41355,206779", [24940]="31068,155342", [24941]="20942,104713", [24942]="21656,108284",
+ [24943]="32353,161766", [24944]="39250,196250", [24945]="20360,101802", [24946]="30423,152117", [24947]="40794,203972", [24948]="30648,153242",
+ [24949]="20664,103324", [24950]="21354,106771", [24951]="31906,159531", [24952]="42775,213877", [24953]="21588,107944", [24954]="32255,161276",
+ [24955]="43246,216230", [24956]="32487,162435", [24957]="21902,109511", [24958]="22611,113059", [24959]="33781,168908", [24960]="45285,226425",
+ [24961]="21238,106194", [24962]="31737,158688", [24963]="42554,212774", [24964]="31976,159880", [24965]="21561,107806", [24966]="22246,111230",
+ [24967]="33237,166185", [24968]="44566,222833", [24969]="22494,112470", [24970]="33609,168048", [24971]="45059,225299", [24972]="33854,169273",
+ [24973]="22825,114127", [24974]="23530,117652", [24975]="35152,175762", [24976]="47129,235649", [24977]="22081,110405", [24978]="32994,164973",
+ [24979]="44247,221236", [24980]="33249,166248", [24981]="22421,112107", [24982]="23099,115496", [24983]="34517,172587", [24984]="46285,231429",
+ [24985]="23363,116815", [24986]="34906,174532", [24987]="46805,234029", [24988]="35168,175842", [24989]="23712,118562", [24990]="24410,122053",
+ [24991]="36472,182364", [24992]="48902,244513", [24993]="24678,123393", [24994]="37833,189168", [24995]="50720,253603", [24996]="38102,190511",
+ [24997]="23242,116214", [24998]="23918,119592", [24999]="35743,178718", [25000]="47933,239665", [25001]="24193,120967", [25002]="36152,180764",
+ [25003]="48479,242398", [25004]="36428,182141", [25005]="24560,122804", [25006]="25256,126283", [25007]="37739,188695", [25008]="50603,253016",
+ [25009]="25538,127692", [25010]="39168,195842", [25011]="52512,262563", [25012]="39446,197233", [25013]="26593,132966", [25014]="27325,136628",
+ [25015]="40822,204111", [25016]="54721,273606", [25017]="24989,124949", [25018]="37345,186726", [25019]="50081,250408", [25020]="37630,188151",
+ [25021]="25375,126876", [25022]="26066,130333", [25023]="38951,194758", [25024]="52226,261133", [25025]="26361,131809", [25026]="40449,202245",
+ [25027]="54227,271136", [25028]="40740,203703", [25029]="27467,137335", [25030]="16529,82645", [25031]="17124,85623", [25032]="17725,88628",
+ [25033]="18330,91652", [25034]="18939,94696", [25035]="19549,97749", [25036]="20166,100831", [25037]="18811,94055", [25038]="19383,96915",
+ [25039]="19956,99783", [25040]="20536,102681", [25041]="21119,105599", [25042]="22296,111484", [25043]="22901,114509", [25044]="26809,107236",
+ [25045]="27678,110712", [25046]="28546,114184", [25047]="29415,117660", [25048]="30284,121136", [25049]="31154,124616", [25050]="32023,128092",
+ [25051]="32891,131564", [25052]="33760,135040", [25053]="34629,138516", [25054]="35498,141992", [25055]="36368,145472", [25056]="37236,148944",
+ [25057]="38105,152420", [25058]="26809,107236", [25059]="27678,110712", [25060]="28546,114184", [25061]="29415,117660", [25062]="30284,121136",
+ [25063]="31154,124616", [25064]="32023,128092", [25065]="32891,131564", [25066]="33760,135040", [25067]="34629,138516", [25068]="35498,141992",
+ [25069]="36368,145472", [25070]="37236,148944", [25071]="38105,152420", [25072]="35505,177528", [25073]="36784,183920", [25074]="35384,176924",
+ [25075]="36601,183006", [25076]="37822,189110", [25077]="39054,195274", [25078]="40295,201479", [25079]="41545,207725", [25080]="42798,213991",
+ [25081]="44063,220319", [25082]="45337,226688", [25083]="46619,233098", [25084]="47905,239526", [25085]="49203,246018", [25086]="26809,107236",
+ [25087]="27678,110712", [25088]="28546,114184", [25089]="29415,117660", [25090]="30284,121136", [25091]="31154,124616", [25092]="32023,128092",
+ [25093]="32891,131564", [25094]="33760,135040", [25095]="34629,138516", [25096]="35498,141992", [25097]="36368,145472", [25098]="37236,148944",
+ [25099]="38105,152420", [25100]="53097,265485", [25101]="55022,275114", [25102]="56961,284808", [25103]="58907,294536", [25104]="60871,304357",
+ [25105]="62848,314243", [25106]="66529,332647", [25107]="68578,342891", [25108]="70639,353199", [25109]="72714,363571", [25110]="67687,338439",
+ [25111]="69613,348069", [25112]="71552,357763", [25113]="73504,367522", [25114]="51906,259533", [25115]="53793,268969", [25116]="55694,278470",
+ [25117]="57607,288035", [25118]="59526,297634", [25119]="61465,307327", [25120]="63416,317084", [25121]="65381,326906", [25122]="69140,345704",
+ [25123]="71176,355883", [25124]="73225,366127", [25125]="75279,376399", [25126]="77354,386770", [25127]="79441,397206", [25128]="70111,350555",
+ [25129]="72632,363163", [25130]="68033,340166", [25131]="70376,351881", [25132]="72735,363677", [25133]="75102,375514", [25134]="77493,387469",
+ [25135]="79901,399505", [25136]="82324,411621", [25137]="84754,423774", [25138]="89561,447808", [25139]="92090,460452", [25140]="94626,473130",
+ [25141]="97186,485933", [25142]="54898,274492", [25143]="56882,284413", [25144]="58874,294371", [25146]="62906,314533", [25147]="64942,324711",
+ [25148]="66984,334921", [25149]="69045,345226", [25150]="64360,321802", [25151]="66273,331366", [25152]="68191,340959", [25153]="70130,350651",
+ [25154]="74055,370275", [25155]="76057,380287", [25156]="67135,335676", [25157]="69567,347836", [25158]="72015,360077", [25160]="76952,384762",
+ [25161]="79448,397243", [25162]="81961,409805", [25163]="84481,422405", [25164]="87025,435126", [25165]="89585,447928", [25166]="92161,460809",
+ [25167]="94745,473726", [25168]="97353,486768", [25169]="99977,499889", [25170]="65647,328237", [25171]="68031,340156", [25172]="70431,352156",
+ [25174]="75271,376359", [25175]="77719,388598", [25176]="80183,400919", [25177]="82663,413319", [25178]="85151,425758", [25179]="87663,438318",
+ [25180]="90191,450959", [25181]="92736,463680", [25182]="95287,476435", [25183]="97863,489315", [25184]="55279,276396", [25185]="57275,286379",
+ [25186]="55077,275387", [25187]="56971,284858", [25188]="58878,294394", [25189]="60792,303963", [25190]="62725,313626", [25191]="64670,323353",
+ [25192]="66629,333145", [25193]="68593,342967", [25194]="70577,352886", [25195]="72574,362870", [25196]="74583,372918", [25197]="76598,382993",
+ [25198]="54088,270444", [25199]="56046,280234", [25200]="58017,290089", [25201]="59995,299978", [25202]="61992,309960", [25203]="59415,297078",
+ [25204]="61303,306517", [25205]="63210,316051", [25206]="65130,325650", [25207]="67062,335314", [25208]="69001,345006", [25209]="70959,354797",
+ [25210]="72930,364652", [25211]="74914,374572", [25212]="66123,330616", [25213]="68522,342612", [25214]="70937,354689", [25215]="73369,366847",
+ [25216]="75809,379046", [25217]="78272,391363", [25218]="80752,403761", [25219]="85418,427092", [25220]="87987,439937", [25221]="90572,452862",
+ [25222]="93173,465868", [25223]="86680,433404", [25224]="89096,445482", [25225]="91528,457640", [25226]="64642,323210", [25227]="66986,334932",
+ [25228]="69353,346768", [25229]="71736,358684", [25230]="74136,370680", [25231]="76543,382718", [25232]="78974,394874", [25233]="81422,407111",
+ [25234]="83877,419386", [25235]="88650,443253", [25236]="91203,456017", [25237]="93772,468862", [25238]="96348,481741", [25239]="98949,494745",
+ [25240]="41917,209589", [25241]="43430,217150", [25242]="44947,224739", [25243]="42062,210312", [25244]="43473,217366", [25245]="44893,224467",
+ [25246]="46318,231593", [25247]="47758,238790", [25248]="49207,246035", [25249]="50665,253329", [25250]="52128,260644", [25251]="55052,275262",
+ [25252]="56574,282872", [25253]="58100,290502", [25254]="41025,205125", [25255]="42508,212542", [25256]="44001,220007", [25257]="45499,227498",
+ [25258]="47011,235059", [25259]="48533,242668", [25260]="50065,250326", [25261]="51601,258007", [25262]="53152,265760", [25263]="49512,247563",
+ [25264]="50952,254761", [25265]="52395,261979", [25266]="53854,269272", [25267]="56837,284187", [25268]="40132,200661", [25269]="41586,207934",
+ [25270]="43050,215254", [25271]="44524,222623", [25272]="46003,230017", [25273]="47496,237481", [25274]="48998,244994", [25275]="50511,252555",
+ [25276]="52027,260139", [25277]="53559,267795", [25278]="55100,275500", [25279]="56650,283254", [25280]="58205,291027", [25281]="59775,298876",
+ [25282]="42203,211016", [25283]="40665,203325", [25284]="42100,210501", [25286]="44999,224997", [25287]="46458,232294", [25288]="47932,239662",
+ [25289]="49415,247079", [25290]="50908,254543", [25291]="52406,262030", [25292]="53918,269590", [25293]="55439,277198", [25294]="56971,284855",
+ [25295]="58506,292532", [25296]="55080,275404", [25297]="57071,285355", [25298]="59068,295341", [25299]="56754,283770", [25300]="58654,293273",
+ [25301]="60568,302841", [25302]="62488,312441", [25303]="64427,322136", [25304]="66379,331896", [25305]="68344,341720", [25306]="70314,351573",
+ [25307]="72305,361525", [25308]="74308,371541", [25309]="76324,381621", [25310]="53890,269452", [25311]="55842,279210", [25312]="57806,289032",
+ [25313]="59783,298919", [25314]="61768,308840", [25315]="65421,327109", [25316]="61072,305364", [25317]="62967,314835", [25318]="64880,324401",
+ [25319]="66806,334032", [25320]="68745,343728", [25321]="70690,353451", [25322]="72654,363274", [25323]="74632,373162", [25324]="65881,329409",
+ [25325]="68266,341332", [25326]="70673,353369", [25327]="73097,365486", [25328]="75536,377684", [25329]="77984,389922", [25330]="80456,402280",
+ [25331]="85122,425612", [25332]="87675,438376", [25333]="90252,451261", [25334]="92845,464226", [25335]="95454,477272", [25336]="88752,443760",
+ [25337]="91175,455878", [25338]="6906,34533", [25339]="5199,25999", [25340]="6959,34795", [25341]="3763,18815", [25342]="5666,28330",
+ [25343]="3791,18958", [25344]="3805,19028", [25345]="5729,28649", [25346]="7668,38343", [25347]="5926,29631", [25348]="7930,39652",
+ [25349]="9234,46171", [25350]="4633,23169", [25351]="6974,34874", [25352]="4666,23333", [25353]="4683,23416", [25354]="7049,35248",
+ [25355]="9432,47160", [25356]="6424,32122", [25357]="9264,46321", [25358]="4650,23250", [25359]="7001,35006", [25360]="4685,23427",
+ [25361]="4703,23516", [25362]="7081,35405", [25363]="9733,48669", [25364]="7327,36636", [25365]="10921,54608", [25366]="5480,27401",
+ [25367]="8286,41434", [25368]="5520,27600", [25369]="8310,41550", [25370]="5559,27797", [25371]="11158,55794", [25372]="8436,42182",
+ [25373]="12108,60540", [25374]="6075,30375", [25375]="9185,45926", [25376]="5536,27682", [25377]="8337,41685", [25378]="5578,27894",
+ [25379]="11508,57543", [25380]="8702,43511", [25381]="6313,31565", [25382]="9432,47164", [25383]="6359,31799", [25384]="12694,63470",
+ [25385]="6406,32030", [25386]="9571,47856", [25387]="12832,64162", [25388]="9640,48204", [25389]="7001,35009", [25390]="10460,52304",
+ [25391]="7052,35261", [25392]="14074,70373", [25393]="7102,35510", [25394]="10609,53049", [25395]="13226,66131", [25396]="9937,49686",
+ [25397]="18352,91762", [25398]="23027,115135", [25399]="18490,92453", [25400]="23197,115986", [25401]="18626,93134", [25402]="23370,116850",
+ [25403]="18765,93825", [25404]="23540,117701", [25405]="14176,70880", [25406]="14227,71139", [25408]="870,3480", [25409]="1185,4740",
+ [25410]="990,3960", [25411]="1325,5300", [25412]="870,3480", [25413]="1185,4740", [25414]="990,3960", [25415]="1325,5300",
+ [25416]="200,800", [25417]="870,3480", [25418]="1185,4740", [25419]="12,50", [25420]="990,3960", [25421]="1325,5300",
+ [25422]="12,50", [25423]="12,50", [25424]="12,50", [25425]="870,3480", [25426]="1185,4740", [25427]="990,3960",
+ [25428]="1325,5300", [25429]="870,3480", [25430]="1185,4740", [25431]="990,3960", [25432]="1325,5300", [25433]="200,800",
+ [25434]="870,3480", [25435]="1185,4740", [25436]="990,3960", [25437]="1325,5300", [25438]="750,3000", [25439]="250,1000",
+ [25440]="870,3480", [25441]="1185,4740", [25442]="990,3960", [25443]="1325,5300", [25444]="870,3480", [25445]="1185,4740",
+ [25446]="990,3960", [25447]="1325,5300", [25450]="870,3480", [25451]="1185,4740", [25452]="990,3960", [25453]="1325,5300",
+ [25454]="990,3960", [25455]="1325,5300", [25456]="870,3480", [25457]="1185,4740", [25463]="500,2000", [25464]="3301,16506",
+ [25466]="4,16", [25467]="4,16", [25469]="6500,26000", [25470]="0,1000000", [25471]="0,1000000", [25472]="0,1000000",
+ [25473]="0,2000000", [25474]="0,1000000", [25475]="0,1000000", [25476]="0,1000000", [25477]="0,2000000", [25478]="21595,107976",
+ [25479]="27828,139143", [25480]="12358,61792", [25481]="21829,109148", [25482]="28132,140663", [25483]="12491,62458", [25484]="12536,62682",
+ [25485]="22143,110715", [25486]="15782,78913", [25487]="30284,121136", [25488]="30284,121136", [25489]="17320,86601", [25492]="60005,300027",
+ [25494]="75559,377797", [25495]="60671,303358", [25496]="45671,228359", [25498]="25,100", [25499]="30284,121136", [25500]="30284,121136",
+ [25501]="18603,93015", [25502]="21275,106379", [25503]="12132,60660", [25504]="15219,76097", [25505]="29415,117660", [25506]="28403,142017",
+ [25507]="31671,158356", [25508]="29554,147772", [25510]="23820,119102", [25511]="41842,209213", [25512]="35999,179998", [25513]="22581,112907",
+ [25514]="25751,128759", [25515]="21444,107220", [25516]="17218,86093", [25517]="30284,121136", [25518]="30665,153329", [25519]="61556,307780",
+ [25521]="3000,12000", [25522]="32604,163022", [25523]="18733,93669", [25524]="21827,109137", [25525]="18032,90160", [25526]="15000,60000",
+ [25527]="0,2000000", [25528]="0,2000000", [25529]="0,2000000", [25530]="32096,160484", [25531]="0,2000000", [25532]="0,2000000",
+ [25533]="0,2000000", [25534]="18650,93254", [25536]="73751,368759", [25537]="92529,462646", [25538]="74294,371474", [25540]="23032,115162",
+ [25541]="36689,146756", [25542]="36689,146756", [25543]="64630,323152", [25544]="48660,243301", [25545]="65130,325650", [25553]="30,150",
+ [25556]="40712,203563", [25557]="35683,178416", [25558]="20500,102502", [25559]="27343,136719", [25560]="24806,124033", [25561]="28859,144299",
+ [25562]="38775,155100", [25563]="38775,155100", [25564]="38775,155100", [25565]="24421,122106", [25566]="23009,115045", [25567]="19684,98424",
+ [25568]="39519,197598", [25569]="46281,231405", [25570]="24884,124423", [25573]="48223,241118", [25574]="27656,138281", [25575]="31225,156129",
+ [25576]="17410,87050", [25577]="27953,139767", [25578]="17533,87666", [25579]="31672,158362", [25580]="49443,247215", [25581]="21262,106314",
+ [25583]="16154,80771", [25584]="19460,97300", [25585]="45576,227884", [25589]="35575,177876", [25591]="17097,85489", [25592]="20590,102951",
+ [25593]="36095,180476", [25594]="31248,156243", [25595]="27753,138767", [25597]="21431,107155", [25598]="18330,91652", [25599]="15329,76649",
+ [25600]="15382,76913", [25601]="18524,92623", [25602]="19739,98696", [25603]="90253,451269", [25605]="18690,93451", [25606]="32891,131564",
+ [25607]="32891,131564", [25608]="94489,472446", [25609]="18967,94838", [25610]="28044,140223", [25611]="10742,53711", [25612]="33757,168788",
+ [25613]="12711,63559", [25614]="40408,202044", [25615]="33543,167716", [25616]="24091,120458", [25617]="24178,120890", [25618]="19411,97058",
+ [25619]="7000,28000", [25620]="7000,28000", [25621]="18241,91207", [25622]="80542,402712", [25623]="22766,113832", [25624]="41549,207746",
+ [25627]="42012,210061", [25628]="7000,28000", [25629]="49598,247991", [25630]="19910,99551", [25631]="19983,99917", [25632]="50141,250705",
+ [25633]="7000,28000", [25634]="7000,28000", [25636]="19393,96966", [25637]="12977,64887", [25639]="57838,289191", [25640]="58059,290296",
+ [25641]="11,47", [25643]="23486,117432", [25644]="23574,117874", [25645]="23660,118304", [25649]="250,1000", [25650]="7500,30000",
+ [25651]="22500,90000", [25652]="22500,90000", [25653]="17500,70000", [25654]="17436,87184", [25655]="26106,130533", [25656]="36782,183910",
+ [25657]="39930,199650", [25659]="30312,151562", [25660]="38360,191802", [25661]="17727,88636", [25662]="32525,162627", [25668]="24047,120239",
+ [25669]="14274,71373", [25670]="32249,161249", [25671]="35070,175350", [25673]="21717,108585", [25674]="15897,79488", [25675]="30530,152650",
+ [25676]="32311,161559", [25679]="250,1000", [25680]="31300,156503", [25681]="37703,188519", [25682]="31539,157695", [25683]="37986,189930",
+ [25685]="20771,103855", [25686]="32862,164314", [25687]="43976,219880", [25689]="45010,225054", [25690]="44808,224040", [25691]="33726,168631",
+ [25692]="51110,255553", [25693]="36667,183339", [25694]="25734,128671", [25695]="24563,122819", [25696]="50116,250583", [25697]="25155,125776",
+ [25699]="1250,5000", [25700]="1250,5000", [25701]="48531,242659", [25702]="41752,208761", [25703]="100,400", [25707]="6250,25000",
+ [25708]="750,3000", [25710]="26858,134291", [25711]="28751,143756", [25712]="21640,108201", [25713]="34604,138416", [25714]="28836,115344",
+ [25715]="33525,167627", [25716]="19266,96332", [25717]="24843,124216", [25718]="19949,99745", [25719]="868,0", [25720]="12500,50000",
+ [25721]="12500,50000", [25722]="12500,50000", [25723]="20,80", [25724]="22,90", [25725]="12500,50000", [25726]="2500,10000",
+ [25728]="15000,60000", [25729]="15000,60000", [25730]="15000,60000", [25731]="15000,60000", [25732]="30000,120000", [25733]="35000,140000",
+ [25734]="35000,140000", [25735]="40000,160000", [25736]="35000,140000", [25737]="35000,140000", [25738]="30000,120000", [25739]="40000,160000",
+ [25740]="40000,160000", [25741]="30000,120000", [25742]="30000,120000", [25743]="30000,120000", [25744]="676,2705", [25759]="79164,395821",
+ [25760]="99323,496618", [25761]="99692,498460", [25762]="100050,500251", [25763]="80334,401674", [25764]="80629,403147", [25772]="75090,375451",
+ [25773]="75369,376847", [25774]="75656,378282", [25775]="38775,155100", [25776]="38775,155100", [25777]="22952,114764", [25778]="13373,66865",
+ [25779]="16778,83894", [25780]="20207,101037", [25781]="43576,217883", [25782]="37485,187429", [25783]="18810,94051", [25784]="28546,114184",
+ [25785]="28546,114184", [25786]="7464,29857", [25787]="8910,35640", [25788]="29291,146456", [25789]="25060,125304", [25790]="31447,157236",
+ [25791]="21045,105228", [25792]="25349,126745", [25802]="1500,6000", [25803]="41903,167612", [25804]="41903,167612", [25805]="26207,131037",
+ [25806]="65751,328757", [25808]="59918,299592", [25809]="41903,167612", [25810]="24153,120767", [25811]="41903,167612", [25813]="1020,4080",
+ [25819]="56869,284349", [25820]="36691,183459", [25821]="40916,204580", [25822]="32847,164237", [25823]="69463,347318", [25824]="28695,114780",
+ [25825]="69960,349801", [25826]="28695,114780", [25835]="89596,447982", [25836]="71940,359704", [25838]="36230,181153", [25843]="8000,32000",
+ [25844]="32000,128000", [25845]="40000,160000", [25846]="10000,40000", [25847]="30000,120000", [25848]="25000,100000", [25849]="30000,120000",
+ [25861]="3,15", [25867]="30000,120000", [25868]="30000,120000", [25869]="20000,80000", [25870]="20000,80000", [25872]="7,30",
+ [25873]="18,75", [25874]="0,1", [25875]="50,200", [25876]="200,800", [25878]="13253,53012", [25880]="150,600",
+ [25881]="600,2400", [25882]="1000,4000", [25883]="1000,4000", [25886]="250,1000", [25887]="15000,60000", [25890]="30000,120000",
+ [25893]="30000,120000", [25894]="30000,120000", [25895]="30000,120000", [25896]="30000,120000", [25897]="30000,120000", [25898]="30000,120000",
+ [25899]="30000,120000", [25900]="5500,22000", [25901]="30000,120000", [25902]="30000,120000", [25903]="30000,120000", [25904]="30000,120000",
+ [25905]="30000,120000", [25906]="30000,120000", [25907]="30000,120000", [25908]="30000,120000", [25909]="30000,120000", [25910]="30000,120000",
+ [25913]="30284,121136", [25914]="30284,121136", [25915]="62470,312353", [25916]="64487,322436", [25917]="80897,404487", [25918]="64948,324742",
+ [25919]="30284,121136", [25920]="63579,317895", [25921]="30284,121136", [25922]="21574,107871", [25923]="27810,139052", [25924]="23159,115796",
+ [25925]="18598,92992", [25926]="32023,128092", [25927]="19247,96239", [25928]="32023,128092", [25929]="42788,213940", [25930]="27607,138037",
+ [25931]="18470,92352", [25932]="30896,154480", [25933]="65575,327876", [25934]="82265,411326", [25935]="82553,412767", [25936]="66290,265161",
+ [25937]="66290,265161", [25939]="59195,295975", [25940]="23761,118809", [25941]="32513,162565", [25942]="26119,130597", [25943]="74482,372410",
+ [25944]="93451,467258", [25945]="22512,112560", [25946]="28242,141210", [25947]="34167,170836", [25948]="22665,113327", [25949]="16156,80784",
+ [25950]="95526,477634", [25951]="29422,147114", [25952]="76979,384899", [25953]="57944,289721", [25954]="8377,33510", [25955]="35014,175072",
+ [25956]="27487,137437", [25957]="23508,117541", [25958]="21241,106205", [25959]="18172,90861", [25960]="15201,76006", [25961]="12205,61029",
+ [25962]="83797,335188", [25963]="31154,124616", [25964]="76819,384098", [25965]="18583,92917", [25966]="18652,93263", [25967]="37416,187084",
+ [25968]="32394,161974", [25969]="17981,89908", [25970]="21657,108285", [25971]="40426,202133", [25972]="40569,202849", [25973]="40717,203585",
+ [25974]="17826,89132", [25975]="22369,111848", [25976]="26944,134722", [25977]="31496,157480", [25978]="50177,250886", [25979]="38850,194250",
+ [25980]="33423,167116", [25981]="20968,104844", [25982]="11225,56128", [25983]="16901,84508", [25984]="21204,106021", [25985]="75264,376321",
+ [25986]="75544,377721", [25987]="75824,379122", [25988]="28546,114184", [25989]="28546,114184", [25990]="28546,114184", [25991]="28546,114184",
+ [25992]="28546,114184", [25993]="28546,114184", [25994]="21612,86450", [25995]="21612,86450", [25996]="21612,86450", [26004]="124,622",
+ [26005]="323,1617", [26006]="160,804", [26007]="384,1923", [26008]="101,506", [26009]="294,1473", [26010]="183,918",
+ [26011]="386,1934", [26012]="148,740", [26013]="298,1493", [26014]="93,468", [26016]="169,849", [26017]="358,1790",
+ [26018]="152,760", [26019]="395,1976", [26020]="191,958", [26021]="458,2290", [26022]="123,619", [26023]="360,1801",
+ [26024]="224,1123", [26025]="473,2367", [26026]="364,1821", [26027]="181,908", [26028]="126,633", [26030]="507,2535",
+ [26031]="196,983", [26032]="246,1233", [26033]="589,2946", [26034]="140,702", [26035]="408,2042", [26036]="255,1279",
+ [26037]="539,2696", [26038]="424,2122", [26039]="211,1059", [26040]="147,738", [26049]="325,1626", [26050]="844,4224",
+ [26051]="409,2048", [26052]="1063,5318", [26053]="330,1650", [26054]="797,3985", [26055]="92386,369545", [26128]="13257,66287",
+ [26129]="19963,99815", [26130]="26719,133599", [26131]="13409,67048", [26132]="20191,100957", [26133]="27024,135122", [26134]="20343,101716",
+ [26135]="13980,69902", [26513]="20889,104448", [26765]="49538,247693", [26779]="71446,357234", [27388]="2000,40000", [27389]="383,1918",
+ [27390]="996,4982", [27398]="425,1700", [27399]="254,1273", [27400]="608,3043", [27401]="300,1503", [27402]="718,3592",
+ [27403]="302,1514", [27404]="671,3359", [27408]="39509,197549", [27409]="28382,141914", [27410]="22792,113961", [27411]="22876,114380",
+ [27412]="95675,478378", [27413]="18750,75000", [27414]="34701,173507", [27415]="29022,145112", [27416]="10307,41230", [27417]="30024,150120",
+ [27418]="32140,160701", [27420]="42412,212063", [27422]="8,160", [27423]="22786,113932", [27424]="76249,381248", [27425]="8,160",
+ [27426]="76831,384155", [27427]="53987,269939", [27428]="23226,116130", [27429]="8,160", [27430]="46800,234004", [27431]="78296,391481",
+ [27432]="36645,146580", [27433]="23663,118316", [27434]="29689,148448", [27435]="8,160", [27436]="4308,17235", [27437]="8,160",
+ [27438]="8,160", [27439]="8,160", [27440]="12377,49510", [27441]="8,160", [27442]="60000,1200000", [27443]="5000,20000",
+ [27445]="2500,10000", [27446]="1,4", [27447]="29989,149945", [27448]="25656,128282", [27449]="54936,274682", [27450]="38946,194730",
+ [27451]="25946,129734", [27452]="17361,86806", [27453]="7102,28410", [27454]="40584,202921", [27455]="47219,236098", [27456]="45215,226076",
+ [27457]="31946,159730", [27458]="54649,273245", [27459]="32175,160876", [27460]="55035,220141", [27461]="46024,230123", [27462]="18474,92374",
+ [27463]="83894,419470", [27464]="22464,89857", [27465]="16907,84536", [27466]="25458,127292", [27467]="31941,159709", [27468]="21376,106880",
+ [27474]="26933,134669", [27475]="31713,158569", [27476]="90421,452109", [27477]="34450,137801", [27478]="27321,136609", [27481]="1,4",
+ [27483]="20969,104845", [27484]="25260,126302", [27485]="26057,130288", [27487]="61250,306253", [27488]="26347,131739", [27489]="31029,155147",
+ [27490]="88468,442344", [27491]="30866,123465", [27492]="44559,222799", [27493]="17889,89445", [27494]="26928,134643", [27495]="41953,167814",
+ [27497]="31936,159684", [27498]="125,500", [27499]="112,600", [27500]="100,550", [27501]="100,550", [27502]="112,600",
+ [27503]="125,500", [27505]="45504,227524", [27506]="34866,174333", [27507]="65619,328096", [27508]="17563,87817", [27509]="22033,110168",
+ [27510]="26538,132690", [27511]="25,100", [27512]="89111,445555", [27513]="20,80", [27514]="44876,224383", [27515]="500,2000",
+ [27516]="500,2000", [27517]="16449,82248", [27518]="24770,123850", [27519]="24865,124326", [27520]="43593,217967", [27521]="25661,128308",
+ [27522]="25759,128797", [27523]="14846,59387", [27524]="105570,527851", [27525]="25432,127161", [27526]="63818,319094", [27527]="61238,306192",
+ [27528]="26340,131700", [27529]="66290,265161", [27531]="22191,110959", [27532]="12500,50000", [27533]="91750,458751", [27534]="22045,88181",
+ [27535]="29422,147111", [27536]="16782,83911", [27537]="16847,84237", [27538]="84562,422813", [27539]="44476,222384", [27540]="63903,319518",
+ [27541]="25659,128295", [27542]="17171,85855", [27543]="86172,430863", [27544]="25949,129747", [27545]="43411,217059", [27546]="8788,35155",
+ [27547]="17493,87465", [27548]="30902,154512", [27549]="40882,204413", [27550]="27229,136147", [27551]="10283,41135", [27552]="12,60",
+ [27553]="30,120", [27631]="36689,146756", [27635]="6,24", [27636]="25,100", [27640]="606,3033", [27641]="1014,5074",
+ [27651]="150,600", [27655]="150,600", [27656]="150,600", [27657]="150,600", [27658]="150,600", [27659]="150,600",
+ [27660]="150,600", [27661]="150,600", [27662]="150,600", [27663]="150,600", [27664]="150,600", [27665]="150,600",
+ [27666]="150,600", [27667]="150,600", [27668]="5,20", [27669]="5,20", [27671]="200,800", [27672]="29874,149372",
+ [27673]="85196,425980", [27674]="200,800", [27676]="200,800", [27677]="200,800", [27678]="200,800", [27681]="200,800",
+ [27682]="200,800", [27683]="10000,40000", [27684]="5000,20000", [27685]="10,40", [27686]="10,40", [27687]="100,400",
+ [27688]="5000,20000", [27690]="7500,30000", [27691]="7500,30000", [27692]="7500,30000", [27693]="7500,30000", [27694]="5000,20000",
+ [27695]="5000,20000", [27696]="5000,20000", [27697]="7500,30000", [27698]="7500,30000", [27699]="7500,30000", [27700]="7500,30000",
+ [27712]="21793,108969", [27713]="39550,197752", [27714]="34450,137801", [27715]="30889,154445", [27716]="40188,200944", [27717]="35626,178133",
+ [27718]="45414,227070", [27719]="32557,162785", [27720]="26137,130689", [27721]="32499,162498", [27722]="18673,93369", [27723]="15616,78080",
+ [27724]="23508,117541", [27725]="32966,164831", [27726]="17603,88018", [27727]="22086,110431", [27728]="17736,88681", [27729]="667,2669",
+ [27730]="17870,89354", [27731]="17421,87107", [27732]="17486,87434", [27733]="30284,121136", [27734]="30284,121136", [27735]="30284,121136",
+ [27736]="5000,20000", [27737]="33294,166472", [27738]="26730,133653", [27739]="46860,234300", [27740]="10709,42837", [27741]="90078,450393",
+ [27742]="16784,83920", [27743]="25273,126368", [27744]="25371,126857", [27745]="25469,127345", [27746]="17042,85213", [27747]="85539,427696",
+ [27748]="60105,300526", [27749]="78430,392152", [27750]="78718,393593", [27751]="79015,395075", [27752]="79311,396556", [27753]="60223,301117",
+ [27754]="60447,302238", [27755]="31020,155101", [27756]="60895,304479", [27757]="110959,554799", [27758]="22464,89857", [27759]="41287,206438",
+ [27760]="23018,115094", [27761]="10709,42837", [27762]="10709,42837", [27763]="31588,157944", [27764]="16912,84562", [27765]="21219,106099",
+ [27766]="39470,157880", [27767]="85530,427652", [27768]="17171,85855", [27769]="107715,538579", [27770]="21612,86450", [27771]="45495,227477",
+ [27772]="55769,278849", [27773]="52479,262397", [27775]="27134,135672", [27776]="34036,170184", [27778]="27424,137124", [27779]="50287,201151",
+ [27780]="83797,335188", [27781]="25073,125366", [27783]="20557,102789", [27784]="41903,167612", [27787]="41742,208714", [27788]="43913,219565",
+ [27789]="25236,126181", [27790]="45438,227193", [27791]="108780,543902", [27792]="8788,35155", [27793]="26298,131490", [27794]="65983,329916",
+ [27795]="18086,90430", [27796]="27226,136134", [27797]="34155,170778", [27798]="32175,160876", [27799]="36689,183447", [27800]="46024,230123",
+ [27801]="41753,208767", [27802]="37916,189580", [27803]="44126,220632", [27804]="25360,126804", [27805]="10709,42837", [27806]="26252,131264",
+ [27813]="47044,235222", [27814]="90096,450481", [27815]="27126,135632", [27816]="27224,136121", [27817]="68304,341523", [27818]="45694,228474",
+ [27821]="27707,138536", [27822]="55035,220141", [27823]="51920,259600", [27824]="34743,173717", [27825]="21793,108969", [27826]="39550,197752",
+ [27827]="21956,109783", [27828]="10000,40000", [27829]="110586,552930", [27831]="33419,167099", [27835]="27123,135619", [27837]="45527,227638",
+ [27838]="33962,169811", [27839]="59661,298309", [27840]="106935,534675", [27842]="107748,538743", [27843]="17304,86524", [27844]="45504,227524",
+ [27845]="39399,196996", [27846]="87492,437461", [27847]="46016,230082", [27848]="26440,132201", [27854]="280,5600", [27855]="280,5600",
+ [27856]="280,5600", [27857]="280,5600", [27858]="280,5600", [27859]="280,5600", [27860]="320,6400", [27865]="26147,130736",
+ [27866]="26242,131212", [27867]="32925,164625", [27868]="86036,430183", [27869]="41903,167612", [27870]="62137,310687", [27871]="8788,35155",
+ [27872]="91750,458751", [27873]="46037,230189", [27874]="50151,250758", [27875]="33564,167823", [27876]="84237,421185", [27877]="105703,528516",
+ [27878]="25463,127319", [27884]="44417,222085", [27885]="63806,319030", [27886]="25617,128088", [27887]="56311,281556", [27888]="39736,198684",
+ [27889]="17722,88613", [27890]="66698,333491", [27891]="66290,265161", [27892]="26870,134350", [27893]="62913,314565", [27895]="30866,123465",
+ [27896]="10000,40000", [27897]="57778,288893", [27898]="62144,310720", [27899]="85196,425980", [27900]="21612,86450", [27901]="83803,419017",
+ [27902]="25849,129245", [27903]="111025,555129", [27904]="10709,42837", [27905]="89462,447314", [27906]="62851,314259", [27907]="36045,180227",
+ [27908]="45215,226076", [27909]="54453,272268", [27910]="58292,291461", [27911]="22851,114259", [27912]="55034,275171", [27913]="92049,460247",
+ [27914]="33819,169097", [27915]="37017,185086", [27916]="43988,175952", [27917]="24759,123798", [27918]="29163,145816", [27919]="25630,128153",
+ [27925]="7102,28410", [27932]="870,3480", [27933]="990,3960", [27934]="1185,4740", [27935]="1325,5300", [27936]="51920,259600",
+ [27937]="86858,434294", [27938]="32690,163454", [27940]="100000,400000", [27941]="50000,200000", [27944]="87500,350000", [27945]="37500,150000",
+ [27946]="26928,134643", [27948]="36165,180826", [27976]="62500,250000", [27977]="60782,303913", [27978]="2500,10000", [27979]="25000,100000",
+ [27980]="87800,439001", [27981]="26437,132188", [27982]="75000,300000", [27985]="32296,161480", [27986]="115094,575474", [27987]="61203,306017",
+ [27988]="24576,122883", [27992]="12500,50000", [27993]="37576,187881", [27994]="25143,125718", [27995]="31548,157743", [27996]="30866,123465",
+ [28026]="19557,97787", [28027]="22457,112285", [28028]="14852,74261", [28029]="14047,70237", [28030]="21753,108768", [28031]="22437,112187",
+ [28032]="22518,112594", [28033]="107191,535957", [28034]="10000,40000", [28040]="66290,265161", [28041]="66290,265161", [28042]="66290,265161",
+ [28043]="29415,117660", [28044]="29415,117660", [28045]="18399,91996", [28050]="33134,165671", [28051]="33255,166275", [28052]="26703,133517",
+ [28053]="2,1600", [28054]="47078,235393", [28055]="47247,236239", [28056]="3,3000", [28057]="40796,203981", [28058]="870,3480",
+ [28059]="990,3960", [28060]="2,1600", [28061]="3,3000", [28062]="46848,234242", [28063]="43673,218365", [28064]="17536,87682",
+ [28065]="17603,88018", [28066]="17669,88345", [28068]="15000,60000", [28069]="36740,183703", [28070]="21111,105558", [28071]="3750,15000",
+ [28072]="6500,26000", [28073]="16750,67000", [28074]="26782,133913", [28075]="21505,107526", [28100]="1000,4000", [28101]="1500,6000",
+ [28102]="2500,10000", [28103]="2500,10000", [28104]="2500,10000", [28108]="10307,41230", [28109]="10307,41230", [28121]="10000,40000",
+ [28124]="21217,106088", [28134]="22464,89857", [28141]="134,674", [28142]="169,846", [28143]="203,1019", [28144]="77,389",
+ [28146]="48,241", [28147]="60,302", [28148]="72,364", [28149]="158,793", [28150]="149,746", [28151]="449,2247",
+ [28152]="240,1203", [28153]="257,1287", [28154]="334,1672", [28155]="193,965", [28156]="193,968", [28157]="422,2112",
+ [28158]="243,1219", [28159]="244,1223", [28160]="476,2382", [28161]="478,2391", [28162]="276,1380", [28163]="277,1385",
+ [28164]="876,4381", [28166]="46065,230325", [28167]="31029,155147", [28168]="39818,159272", [28169]="24112,120562", [28170]="26735,133679",
+ [28171]="22359,111795", [28172]="40625,203126", [28173]="48927,244636", [28174]="18082,90413", [28175]="57488,287443", [28176]="44320,221600",
+ [28177]="38377,191887", [28178]="31961,159808", [28179]="25664,128322", [28180]="44997,224988", [28181]="38789,193947", [28182]="32446,162233",
+ [28183]="26052,130261", [28184]="85100,425502", [28185]="34167,170836", [28186]="51441,257208", [28187]="22045,88181", [28188]="110575,552875",
+ [28189]="88785,443927", [28190]="10000,40000", [28191]="35771,178855", [28192]="41438,207190", [28193]="25081,125405", [28194]="25176,125880",
+ [28202]="43253,216267", [28203]="60782,303913", [28204]="43578,217894", [28205]="61232,306161", [28206]="32925,164625", [28207]="46177,230889",
+ [28210]="91424,457124", [28211]="55035,220141", [28212]="36830,184151", [28213]="34450,137801", [28214]="20977,104889", [28215]="37906,189533",
+ [28216]="84562,422813", [28217]="41953,167814", [28218]="34081,170409", [28219]="51318,256591", [28220]="32192,160963", [28221]="45154,225772",
+ [28222]="108122,540613", [28223]="10000,40000", [28224]="33551,167759", [28225]="47053,235268", [28226]="90122,450613", [28227]="83797,335188",
+ [28228]="54458,272294", [28229]="36436,182181", [28230]="36566,182832", [28231]="55044,275224", [28232]="36823,184116", [28233]="22464,89857",
+ [28248]="27226,136134", [28249]="27324,136622", [28250]="27422,137110", [28251]="34396,171982", [28252]="36819,184098", [28253]="115468,577343",
+ [28254]="22464,89857", [28255]="31579,157895", [28256]="26060,130301", [28257]="87193,435965", [28258]="43988,175952", [28259]="30866,123465",
+ [28260]="22045,88181", [28262]="62162,310810", [28263]="89128,445643", [28264]="44727,223635", [28265]="55035,220141", [28266]="54057,270289",
+ [28267]="90421,452109", [28268]="22686,113434", [28269]="27319,136596", [28270]="15000,60000", [28271]="20000,80000", [28272]="20000,80000",
+ [28273]="15000,60000", [28274]="10000,40000", [28275]="38940,194700", [28276]="15000,60000", [28277]="15000,60000", [28278]="26250,131251",
+ [28279]="30000,120000", [28280]="30000,120000", [28281]="15000,60000", [28282]="10000,40000", [28284]="75,300", [28285]="47035,235176",
+ [28286]="67565,337828", [28288]="10000,40000", [28290]="2500,10000", [28291]="15000,60000", [28296]="26052,130261", [28301]="26538,132690",
+ [28303]="403,1615", [28304]="17885,89427", [28306]="37788,188944", [28311]="85213,426068", [28315]="86506,432534", [28316]="55572,277863",
+ [28317]="17431,87157", [28318]="45836,229183", [28321]="8788,35155", [28322]="91099,455496", [28323]="7102,28410", [28324]="32296,161480",
+ [28325]="115094,575474", [28327]="14846,59387", [28328]="25271,126355", [28337]="62630,313151", [28338]="35918,179594", [28339]="33796,168980",
+ [28340]="33918,169590", [28341]="113456,567281", [28342]="36436,182181", [28343]="10283,41135", [28344]="41467,207335", [28345]="92058,460291",
+ [28347]="41951,209757", [28348]="31582,157911", [28349]="38045,190226", [28350]="44472,222360", [28367]="104856,524282", [28370]="10000,40000",
+ [28371]="26252,131264", [28372]="26350,131753", [28373]="26448,132241", [28374]="26545,132729", [28375]="31258,156293", [28384]="41455,207276",
+ [28386]="64411,322058", [28387]="22045,88181", [28390]="30685,153429", [28391]="52500,262503", [28392]="87826,439132", [28393]="110190,550950",
+ [28394]="41903,167612", [28396]="22279,111399", [28397]="67077,335387", [28398]="22440,112202", [28399]="280,5600", [28400]="90413,452065",
+ [28401]="50552,252764", [28403]="59434,297170", [28406]="25762,128810", [28407]="55035,220141", [28408]="9,37", [28412]="22045,88181",
+ [28413]="26440,132201", [28414]="33172,165862", [28415]="26635,133178", [28416]="89102,445511", [28418]="10000,40000", [28419]="39470,157880",
+ [28420]="750,3000", [28421]="1000,4000", [28425]="106842,534212", [28426]="121723,608617", [28427]="133976,669880", [28428]="135064,675320",
+ [28429]="153869,769345", [28430]="169367,846839", [28431]="109260,546300", [28432]="124467,622336", [28433]="140623,703115", [28434]="141739,708698",
+ [28435]="161430,807150", [28436]="177659,888296", [28437]="114600,573002", [28438]="130528,652642", [28439]="129941,649707", [28440]="131012,655060",
+ [28441]="149270,746351", [28442]="164324,821622", [28452]="175,700", [28453]="30149,150747", [28454]="36305,181529", [28458]="5000,20000",
+ [28459]="5000,20000", [28460]="5000,20000", [28461]="5000,20000", [28462]="5000,20000", [28463]="5000,20000", [28464]="5000,20000",
+ [28465]="5000,20000", [28466]="5000,20000", [28467]="5000,20000", [28468]="5000,20000", [28469]="5000,20000", [28470]="5000,20000",
+ [28477]="24459,122298", [28481]="0,100000", [28483]="76235,381179", [28484]="89420,447102", [28485]="102060,510304", [28486]="280,5600",
+ [28491]="22464,112322", [28492]="28179,140898", [28493]="34088,170443", [28494]="39661,198305", [28495]="13258,66292", [28496]="16632,83161",
+ [28497]="18615,93079", [28498]="21925,109629", [28501]="25,100", [28502]="40765,203828", [28503]="34870,174351", [28504]="87501,437505",
+ [28505]="41219,206099", [28506]="29384,146920", [28507]="23591,117958", [28508]="23678,118392", [28509]="128862,515451", [28510]="60256,241024",
+ [28511]="23936,119682", [28512]="42281,211405", [28514]="28084,140424", [28515]="22554,112773", [28516]="86443,345774", [28517]="34092,170462",
+ [28518]="40150,200752", [28519]="34349,171747", [28520]="34479,172398", [28521]="28841,144207", [28522]="115788,578941", [28523]="34866,174333",
+ [28524]="116656,583281", [28525]="203059,1015299", [28528]="91160,364641", [28529]="35640,178204", [28530]="88355,353421", [28531]="26809,107236",
+ [28532]="27678,110712", [28533]="28546,114184", [28534]="29415,117660", [28535]="30284,121136", [28536]="31154,124616", [28537]="32023,128092",
+ [28538]="32891,131564", [28539]="33760,135040", [28540]="34629,138516", [28541]="35498,141992", [28542]="36368,145472", [28543]="37236,148944",
+ [28544]="38105,152420", [28545]="43900,219500", [28565]="24032,120163", [28566]="42450,212251", [28567]="36305,181529", [28568]="36436,182181",
+ [28569]="63869,319346", [28570]="36696,183483", [28572]="111436,557182", [28573]="139838,699190", [28578]="46850,234251", [28579]="91160,364641",
+ [28581]="88820,444103", [28582]="35654,178274", [28583]="53677,268388", [28584]="119717,598589", [28585]="36045,180227", [28586]="36172,180861",
+ [28587]="151260,756301", [28588]="91081,455408", [28589]="55082,275413", [28590]="91160,364641", [28591]="61366,306831", [28592]="36949,184749",
+ [28593]="58607,293039", [28594]="46155,230779", [28595]="2500,10000", [28596]="12500,50000", [28597]="81675,408379", [28599]="70528,352643",
+ [28600]="58990,294954", [28601]="59202,296010", [28602]="47535,237676", [28603]="203059,1015299", [28604]="149618,748090", [28606]="77160,385800",
+ [28608]="63623,318117", [28609]="102777,411111", [28610]="51371,256856", [28611]="73015,365079", [28612]="34352,171764", [28621]="82874,414373",
+ [28631]="51556,257784", [28632]="15000,60000", [28633]="143665,718325", [28647]="42122,210614", [28649]="60256,241024", [28652]="22897,114486",
+ [28653]="34472,172362", [28654]="23068,115342", [28655]="28944,144720", [28656]="34863,174315", [28657]="116632,583164", [28658]="150219,751096",
+ [28659]="36689,146756", [28660]="36313,181565", [28661]="60256,241024", [28662]="85329,426649", [28663]="36700,183500", [28666]="58626,293131",
+ [28669]="42439,212198", [28670]="31250,125000", [28671]="51318,256591", [28672]="34338,171694", [28673]="86172,430863", [28674]="88355,353421",
+ [28675]="60256,241024", [28726]="34483,172415", [28727]="91160,364641", [28728]="203059,1015299", [28729]="116234,581170", [28730]="60256,241024",
+ [28731]="102777,411111", [28732]="44071,220358", [28733]="41521,207606", [28734]="203059,1015299", [28735]="71295,356479", [28740]="67403,337019",
+ [28741]="56386,281934", [28742]="45283,226415", [28743]="59548,297741", [28744]="34219,171096", [28745]="102777,411111", [28746]="51949,259746",
+ [28747]="60451,302259", [28748]="81051,405259", [28749]="116222,581111", [28750]="29164,145820", [28751]="70247,351235", [28752]="44067,220336",
+ [28753]="60256,241024", [28754]="75763,378818", [28755]="45716,228584", [28756]="36703,183518", [28757]="113642,454568", [28762]="102777,411111",
+ [28763]="60256,241024", [28764]="36919,184596", [28765]="37059,185299", [28766]="37196,185982", [28767]="124456,622283", [28768]="124925,624625",
+ [28770]="125848,629244", [28771]="129671,648357", [28772]="97604,488023", [28773]="163260,816300", [28774]="163829,819147", [28775]="68922,344613",
+ [28776]="33000,165000", [28777]="39740,198702", [28778]="36076,180381", [28779]="42494,212472", [28780]="24238,121191", [28781]="203059,1015299",
+ [28782]="152643,763219", [28783]="91937,459687", [28785]="91160,364641", [28788]="2500,10000", [28789]="91160,364641", [28790]="60256,241024",
+ [28791]="60256,241024", [28792]="60256,241024", [28793]="60256,241024", [28794]="163813,819068", [28795]="46294,231474", [28796]="49495,247476",
+ [28797]="39732,198664", [28799]="24142,120710", [28800]="151457,757286", [28801]="54735,273676", [28802]="122102,610512", [28803]="47221,236109",
+ [28804]="37914,189570", [28810]="58388,291941", [28822]="102777,411111", [28823]="91160,364641", [28824]="44481,222407", [28825]="81175,405875",
+ [28826]="36689,146756", [28827]="38328,191640", [28828]="32057,160285", [28830]="91160,364641", [28927]="0,100000", [28936]="0,1000000",
+ [28972]="2350,9400", [28979]="3,15", [29007]="7,30", [29008]="18,75", [29009]="50,200", [29010]="200,800",
+ [29013]="200,800", [29014]="200,800", [29102]="0,1000000", [29103]="0,1000000", [29104]="0,1000000", [29105]="0,1000000",
+ [29108]="58074,290374", [29109]="72850,364252", [29110]="1,4", [29111]="1,4", [29112]="75,300", [29115]="68812,344063",
+ [29116]="46037,230189", [29117]="33434,167172", [29118]="25000,100000", [29119]="197528,790112", [29121]="399034,1995172", [29122]="125555,627777",
+ [29123]="197528,790112", [29124]="414544,2072720", [29125]="416074,2080372", [29126]="197528,790112", [29127]="62408,312042", [29128]="7102,28410",
+ [29129]="35918,179594", [29130]="112653,563267", [29131]="45224,226120", [29132]="43988,175952", [29133]="113863,569315", [29134]="32178,160892",
+ [29135]="41279,206398", [29136]="41426,207131", [29137]="104471,522358", [29138]="104878,524392", [29139]="25265,126329", [29140]="26062,130314",
+ [29141]="43600,218004", [29142]="43763,218818", [29143]="25000,100000", [29144]="25000,100000", [29145]="43988,175952", [29146]="43988,175952",
+ [29147]="33426,167132", [29148]="33548,167743", [29151]="318849,1594245", [29152]="319996,1599984", [29153]="428192,2140963", [29155]="431211,2156059",
+ [29156]="402301,2011508", [29157]="1500,6000", [29158]="1750,7000", [29159]="8375,33500", [29160]="9125,36500", [29165]="415991,2079958",
+ [29166]="111003,555019", [29167]="111410,557054", [29168]="43988,175952", [29169]="43988,175952", [29170]="197528,790112", [29171]="531363,2656817",
+ [29172]="197528,790112", [29173]="43988,175952", [29174]="25474,127371", [29175]="400730,2003650", [29176]="268985,1344928", [29177]="197528,790112",
+ [29179]="43988,175952", [29180]="26057,130288", [29181]="197528,790112", [29182]="411359,2056797", [29183]="86279,431396", [29184]="61700,308501",
+ [29185]="88468,442344", [29186]="250000,1000000", [29187]="75000,300000", [29189]="250000,1000000", [29190]="250000,1000000", [29191]="250000,1000000",
+ [29192]="250000,1000000", [29193]="250000,1000000", [29194]="250000,1000000", [29195]="250000,1000000", [29196]="250000,1000000", [29197]="250000,1000000",
+ [29198]="250000,1000000", [29199]="250000,1000000", [29200]="3658,18291", [29201]="150,600", [29202]="600,2400", [29203]="10000,40000",
+ [29204]="20000,80000", [29209]="500,2000", [29211]="9954,39818", [29212]="30000,120000", [29213]="30000,120000", [29214]="40000,160000",
+ [29215]="40000,160000", [29217]="30000,120000", [29218]="30000,120000", [29219]="30000,120000", [29220]="0,100000", [29221]="0,100000",
+ [29222]="0,100000", [29223]="0,1000000", [29224]="0,1000000", [29227]="0,1000000", [29229]="0,1000000", [29230]="0,1000000",
+ [29231]="0,1000000", [29232]="20000,80000", [29238]="39896,199483", [29239]="59610,298051", [29240]="22835,114176", [29241]="22916,114582",
+ [29242]="34499,172498", [29243]="34624,173124", [29244]="34749,173749", [29245]="52539,262699", [29246]="29163,145819", [29247]="29268,146340",
+ [29248]="44054,220271", [29249]="23578,117894", [29250]="21406,107033", [29251]="32235,161175", [29252]="37965,189826", [29253]="39163,195815",
+ [29254]="58518,292590", [29255]="22418,112092", [29257]="22582,112914", [29258]="33999,169997", [29259]="34124,170623", [29261]="34371,171856",
+ [29262]="51974,259872", [29263]="28848,144242", [29264]="28952,144763", [29265]="43585,217926", [29292]="10,40", [29312]="11665,58329",
+ [29313]="33669,168346", [29314]="37384,186922", [29315]="15009,75048", [29316]="41649,208245", [29317]="16377,81887", [29318]="30818,154092",
+ [29319]="24743,123715", [29320]="7102,28410", [29321]="7102,28410", [29322]="7102,28410", [29323]="7102,28410", [29325]="37866,189330",
+ [29326]="32789,163946", [29327]="18203,91018", [29328]="14618,73093", [29329]="106924,534620", [29330]="34450,137801", [29332]="32440,162200",
+ [29333]="41953,167814", [29334]="41953,167814", [29335]="41953,167814", [29336]="41953,167814", [29337]="55814,279074", [29339]="48180,240904",
+ [29340]="40294,201471", [29341]="32350,161751", [29342]="55280,276402", [29343]="35848,179243", [29344]="43186,215930", [29345]="28902,144511",
+ [29346]="108284,541421", [29347]="88355,353421", [29348]="104629,523148", [29349]="88355,353421", [29350]="84694,423473", [29351]="81510,407553",
+ [29352]="60256,241024", [29353]="109480,547401", [29354]="34374,171873", [29355]="137836,689180", [29356]="138335,691679", [29357]="28958,144791",
+ [29359]="139821,699106", [29360]="112256,561283", [29362]="113045,565226", [29363]="100000,400000", [29364]="25000,100000", [29371]="69666,348334",
+ [29372]="69923,349616", [29377]="88988,444941", [29378]="53585,267925", [29380]="71952,359762", [29391]="69653,348265", [29393]="280,5600",
+ [29394]="400,8000", [29395]="320,6400", [29398]="30284,121136", [29399]="72796,363980", [29400]="17538,87691", [29401]="320,6400",
+ [29412]="280,5600", [29425]="200,800", [29426]="200,800", [29448]="400,8000", [29449]="400,8000", [29450]="400,8000",
+ [29451]="400,8000", [29452]="400,8000", [29453]="400,8000", [29454]="280,5600", [29456]="69716,348580", [29457]="69987,349938",
+ [29458]="77562,387811", [29463]="39750,198750", [29483]="15000,60000", [29485]="15000,60000", [29486]="15000,60000", [29487]="15000,60000",
+ [29488]="15000,60000", [29489]="52781,263907", [29490]="26486,132430", [29491]="40049,200246", [29492]="53353,266767", [29493]="40332,201663",
+ [29494]="24968,124842", [29495]="41772,208864", [29496]="20965,104829", [29497]="31564,157824", [29498]="42245,211226", [29499]="31803,159015",
+ [29500]="21281,106407", [29502]="40447,202237", [29503]="27064,135324", [29504]="40743,203715", [29505]="40893,204465", [29506]="27361,136809",
+ [29507]="27461,137309", [29508]="49606,248032", [29509]="33190,165954", [29510]="46388,231940", [29511]="31045,155226", [29512]="46950,234753",
+ [29514]="62803,314018", [29515]="71156,355784", [29516]="34352,171764", [29517]="31758,158791", [29518]="936,4682", [29519]="72225,361125",
+ [29520]="34870,174351", [29521]="35000,175002", [29522]="60864,304321", [29523]="29381,146905", [29524]="29489,147448", [29525]="61534,307674",
+ [29526]="30483,152418", [29527]="30589,152946", [29528]="5000,20000", [29529]="5000,20000", [29530]="5000,20000", [29531]="5000,20000",
+ [29532]="5000,20000", [29533]="20000,80000", [29534]="20000,80000", [29535]="40000,160000", [29536]="40000,160000", [29539]="1250,5000",
+ [29540]="30000,120000", [29547]="1250,5000", [29548]="2000,8000", [29549]="100000,400000", [29550]="10000,40000", [29553]="870,3480",
+ [29554]="990,3960", [29555]="1325,5300", [29556]="1185,4740", [29559]="1185,4740", [29560]="1325,5300", [29561]="870,3480",
+ [29562]="990,3960", [29563]="1185,4740", [29564]="1325,5300", [29567]="1185,4740", [29568]="1325,5300", [29570]="670,2680",
+ [29571]="670,2680", [29572]="670,2680", [29573]="55,220", [29574]="80,320", [29575]="670,2680", [29576]="670,2680",
+ [29577]="87,350", [29578]="990,3960", [29579]="870,3480", [29580]="1185,4740", [29581]="1325,5300", [29583]="1462,7313",
+ [29584]="150,600", [29664]="12500,50000", [29669]="12500,50000", [29672]="12500,50000", [29673]="12500,50000", [29674]="12500,50000",
+ [29675]="12500,50000", [29677]="20000,80000", [29682]="20000,80000", [29684]="20000,80000", [29689]="20000,80000", [29691]="20000,80000",
+ [29693]="20000,80000", [29698]="20000,80000", [29700]="20000,80000", [29701]="20000,80000", [29702]="20000,80000", [29703]="20000,80000",
+ [29704]="20000,80000", [29713]="30000,120000", [29714]="40000,160000", [29717]="30000,120000", [29718]="40000,160000", [29719]="15000,60000",
+ [29720]="15000,60000", [29721]="30000,120000", [29722]="30000,120000", [29723]="60000,240000", [29724]="60000,240000", [29725]="60000,240000",
+ [29726]="60000,240000", [29727]="60000,240000", [29728]="60000,240000", [29729]="60000,240000", [29730]="60000,240000", [29731]="60000,240000",
+ [29732]="60000,240000", [29733]="60000,240000", [29734]="60000,240000", [29743]="0,100000", [29744]="0,100000", [29745]="0,1000000",
+ [29746]="0,1000000", [29747]="0,1000000", [29753]="50000,0", [29754]="50000,0", [29755]="50000,0", [29756]="50000,0",
+ [29757]="50000,0", [29758]="50000,0", [29759]="50000,0", [29760]="50000,0", [29761]="50000,0", [29762]="50000,0",
+ [29763]="50000,0", [29764]="50000,0", [29765]="50000,0", [29766]="50000,0", [29767]="50000,0", [29771]="14706,73530",
+ [29772]="18446,92232", [29773]="33322,166610", [29774]="52018,260091", [29775]="34629,138516", [29776]="34629,138516", [29777]="19896,99482",
+ [29779]="50120,250602", [29780]="32469,162347", [29781]="39728,198640", [29782]="35891,179456", [29783]="57552,287763", [29784]="17922,89614",
+ [29785]="21586,107932", [29786]="37841,189209", [29787]="72472,362364", [29788]="43641,218206", [29789]="51098,255494", [29791]="38522,192613",
+ [29792]="22133,110668", [29793]="35498,141992", [29794]="35498,141992", [29799]="1185,4740", [29800]="1325,5300", [29804]="26881,134409",
+ [29806]="21660,108304", [29807]="25507,127539", [29808]="21818,109092", [29810]="27467,137337", [29811]="22052,110264", [29812]="25967,129839",
+ [29813]="25562,127813", [29814]="27999,111996", [29815]="27999,111996", [29901]="1250,5000", [29902]="25000,100000", [29903]="1250,5000",
+ [29904]="1250,5000", [29908]="63676,318384", [29909]="51139,255699", [29910]="64172,320864", [29911]="64414,322071", [29913]="53349,266745",
+ [29914]="53547,267736", [29915]="40305,201526", [29916]="40454,202270", [29917]="34647,173238", [29918]="26216,131084", [29919]="34898,174491",
+ [29920]="60256,241024", [29921]="79504,397521", [29922]="60256,241024", [29923]="203059,1015299", [29924]="139688,698441", [29925]="40322,201613",
+ [29926]="22362,111813", [29927]="16831,84157", [29928]="20942,104714", [29929]="26277,131388", [29930]="26374,131871", [29931]="19855,99275",
+ [29932]="31887,159435", [29933]="32006,160030", [29934]="24091,120457", [29935]="37614,188072", [29936]="37753,188766", [29937]="28362,141811",
+ [29938]="27162,135812", [29939]="27261,136308", [29940]="20520,102602", [29941]="32948,164743", [29942]="33067,165339", [29943]="24890,124450",
+ [29944]="36094,180472", [29945]="36229,181148", [29946]="27224,136121", [29947]="31454,157274", [29948]="131728,658642", [29949]="99160,495803",
+ [29950]="89069,445349", [29951]="57730,288650", [29953]="1250,5000", [29954]="20744,103721", [29955]="17350,86754", [29956]="1250,5000",
+ [29957]="1250,5000", [29958]="25000,100000", [29959]="24788,123942", [29960]="1250,5000", [29962]="128733,643667", [29964]="15290,76453",
+ [29965]="43947,219735", [29966]="31332,156660", [29967]="33680,168401", [29968]="40565,202829", [29969]="35561,177809", [29970]="15642,78211",
+ [29971]="18839,94196", [29972]="51269,256347", [29973]="38564,192824", [29974]="38708,193542", [29975]="46617,233088", [29976]="40050,200254",
+ [29977]="53592,267963", [29978]="30242,151214", [29979]="28450,142254", [29980]="53296,266483", [29981]="160275,801379", [29982]="96539,482699",
+ [29983]="64912,324564", [29984]="31089,155447", [29985]="74902,374510", [29986]="37590,187953", [29987]="26958,134794", [29988]="172526,862632",
+ [29989]="40745,203729", [29990]="40895,204478", [29991]="82099,410495", [29992]="42305,211527", [29993]="180462,902312", [29994]="42609,213045",
+ [29995]="71271,356357", [29996]="145925,729627", [29997]="60256,241024", [29998]="50711,253559", [29999]="27088,135443", [30000]="14498,72492",
+ [30001]="19742,98713", [30002]="34618,173091", [30003]="17412,87062", [30004]="31603,158017", [30005]="36774,183874", [30006]="36368,145472",
+ [30007]="86443,345774", [30008]="88355,353421", [30009]="105395,526977", [30010]="105783,528915", [30011]="106170,530853", [30012]="106558,532791",
+ [30013]="85548,427741", [30014]="41860,209304", [30015]="102777,411111", [30016]="44182,220914", [30017]="88355,353421", [30018]="102777,411111",
+ [30019]="51135,255676", [30020]="27073,135365", [30021]="160225,801126", [30022]="102777,411111", [30023]="37156,185780", [30024]="38324,191620",
+ [30025]="36368,145472", [30026]="38611,193056", [30027]="67691,338459", [30028]="60256,241024", [30029]="32531,162659", [30030]="39181,195908",
+ [30031]="68688,343441", [30032]="46305,231528", [30033]="69183,345915", [30034]="46642,233212", [30035]="39891,199459", [30036]="26690,133451",
+ [30037]="40179,200895", [30038]="26881,134408", [30039]="50577,252889", [30040]="31458,157290", [30041]="47366,236833", [30042]="31697,158487",
+ [30043]="57519,287597", [30044]="38320,191601", [30045]="57952,289760", [30046]="38607,193037", [30047]="38747,193735", [30048]="67929,339645",
+ [30049]="203059,1015299", [30050]="33564,167823", [30051]="39317,196587", [30052]="60256,241024", [30053]="69176,345881", [30054]="79488,397444",
+ [30055]="49859,249299", [30056]="49567,247836", [30057]="43787,218938", [30058]="130230,651154", [30059]="88355,353421", [30060]="47182,235912",
+ [30061]="60256,241024", [30062]="31691,158455", [30063]="38172,190864", [30064]="25544,127721", [30065]="89730,448654", [30066]="58156,290784",
+ [30067]="33564,167823", [30068]="38886,194434", [30069]="22391,111955", [30070]="19263,96315", [30071]="32222,161113", [30072]="32340,161701",
+ [30073]="33297,166488", [30074]="51597,257985", [30075]="61713,308567", [30076]="44570,222851", [30077]="74563,372815", [30079]="37598,187992",
+ [30080]="98401,492008", [30081]="66166,330834", [30082]="132200,661003", [30083]="60256,241024", [30084]="66912,334561", [30085]="57934,289673",
+ [30086]="96412,482061", [30087]="77416,387084", [30088]="97120,485600", [30089]="80037,400189", [30090]="174677,873389", [30091]="40338,201690",
+ [30092]="50597,252986", [30093]="101472,507362", [30095]="128719,643599", [30096]="43605,218027", [30097]="56209,281049", [30098]="37451,187255",
+ [30099]="86443,345774", [30100]="37734,188671", [30101]="63129,315649", [30102]="95073,475369", [30103]="139053,695266", [30104]="61847,309239",
+ [30105]="107885,539425", [30106]="35382,176913", [30107]="56812,284060", [30108]="145402,727011", [30109]="60256,241024", [30110]="60256,241024",
+ [30111]="54025,270127", [30112]="50892,254461", [30155]="150,600", [30183]="20000,0", [30218]="26421,132105", [30224]="21594,107970",
+ [30225]="25427,127136", [30226]="54369,271847", [30227]="34629,138516", [30236]="50000,0", [30237]="50000,0", [30238]="50000,0",
+ [30239]="50000,0", [30240]="50000,0", [30241]="50000,0", [30242]="50000,0", [30243]="50000,0", [30244]="50000,0",
+ [30245]="50000,0", [30246]="50000,0", [30247]="50000,0", [30248]="50000,0", [30249]="50000,0", [30250]="50000,0",
+ [30252]="51684,258420", [30253]="14527,72639", [30254]="25661,128306", [30255]="43902,219511", [30256]="33847,169236", [30257]="42459,212299",
+ [30258]="59660,298304", [30262]="26795,133975", [30263]="32412,162064", [30264]="25332,126660", [30265]="13760,68802", [30266]="25899,129497",
+ [30267]="24403,122016", [30268]="27154,135774", [30269]="25551,127755", [30270]="47874,239374", [30271]="21111,105557", [30272]="35317,176585",
+ [30273]="32042,160210", [30274]="20823,104116", [30275]="36505,182527", [30276]="34629,138516", [30277]="71933,359666", [30278]="72196,360980",
+ [30279]="54344,271720", [30280]="30000,120000", [30281]="30000,120000", [30282]="30000,120000", [30283]="30000,120000", [30284]="20559,102798",
+ [30285]="17198,85994", [30286]="31214,156071", [30290]="35050,175254", [30291]="36867,184336", [30293]="21612,86450", [30294]="20821,104105",
+ [30295]="31483,157415", [30296]="48936,244682", [30297]="31838,159193", [30298]="52460,262301", [30299]="61414,307074", [30300]="41903,167612",
+ [30301]="60000,240000", [30302]="60000,240000", [30303]="60000,240000", [30304]="60000,240000", [30305]="60000,240000", [30306]="60000,240000",
+ [30307]="60000,240000", [30308]="60000,240000", [30321]="60000,240000", [30322]="60000,240000", [30323]="60000,240000", [30324]="60000,240000",
+ [30328]="35632,178162", [30329]="32187,160935", [30330]="25950,129753", [30331]="14798,73992", [30332]="18565,92826", [30333]="33684,168422",
+ [30334]="39191,195956", [30335]="28148,140740", [30336]="22599,112996", [30337]="39610,198052", [30338]="22758,113792", [30339]="36368,145472",
+ [30340]="36368,145472", [30341]="17345,86726", [30342]="20895,104475", [30352]="26134,130674", [30355]="400,8000", [30357]="400,8000",
+ [30358]="400,8000", [30359]="400,8000", [30361]="400,8000", [30362]="25556,127781", [30363]="41039,205198", [30364]="68655,343278",
+ [30365]="7086,28347", [30366]="7086,28347", [30368]="25292,126461", [30369]="31731,158658", [30370]="25475,127379", [30371]="30000,150004",
+ [30372]="21384,106924", [30373]="32193,160968", [30374]="38940,194702", [30375]="30434,152172", [30377]="7086,28347", [30378]="7086,28347",
+ [30379]="35377,176889", [30380]="25000,125003", [30381]="37358,186790", [30382]="14311,71555", [30383]="13678,68392", [30384]="17162,85811",
+ [30386]="36236,181184", [30394]="86762,433813", [30395]="87099,435495", [30396]="87435,437177", [30397]="50141,250706", [30398]="20638,103193",
+ [30399]="17264,86322", [30400]="24400,122004", [30401]="25452,127262", [30402]="23981,119907", [30418]="59304,296524", [30419]="750,3000",
+ [30420]="677,2710", [30421]="2542,10170", [30422]="8375,33500", [30443]="20000,80000", [30444]="12500,50000", [30446]="72039,288156",
+ [30447]="72039,288156", [30448]="72039,288156", [30449]="72039,288156", [30450]="72039,288156", [30457]="320,6400", [30458]="280,5600",
+ [30463]="17128,85641", [30466]="1185,4740", [30467]="1325,5300", [30475]="1185,4740", [30476]="1325,5300", [30477]="1185,4740",
+ [30478]="1325,5300", [30483]="10000,40000", [30504]="1258,6291", [30505]="631,3157", [30506]="375,1500", [30507]="82,331",
+ [30508]="27,110", [30509]="55,220", [30510]="1185,4740", [30511]="1325,5300", [30512]="1185,4740", [30513]="1325,5300",
+ [30514]="20361,101809", [30515]="20438,102194", [30516]="13677,68385", [30517]="28831,144159", [30518]="28939,144697", [30519]="21785,108926",
+ [30520]="14229,71145", [30521]="13930,69653", [30522]="91772,458861", [30523]="55355,276778", [30531]="43665,218326", [30532]="43827,219137",
+ [30533]="76989,384949", [30534]="66241,331207", [30535]="55409,277048", [30536]="77857,389287", [30538]="56029,280146", [30541]="69770,348851",
+ [30542]="5000,20000", [30543]="46846,234234", [30544]="5000,20000", [30546]="30000,120000", [30547]="30000,120000", [30548]="30000,120000",
+ [30549]="30000,120000", [30550]="30000,120000", [30551]="30000,120000", [30552]="30000,120000", [30553]="30000,120000", [30554]="30000,120000",
+ [30555]="30000,120000", [30556]="30000,120000", [30558]="30000,120000", [30559]="30000,120000", [30560]="30000,120000", [30563]="30000,120000",
+ [30564]="30000,120000", [30565]="30000,120000", [30566]="30000,120000", [30568]="5535,22142", [30569]="3633,18166", [30570]="17545,87726",
+ [30571]="35243,140972", [30572]="30000,120000", [30573]="30000,120000", [30574]="30000,120000", [30575]="30000,120000", [30581]="30000,120000",
+ [30582]="30000,120000", [30583]="30000,120000", [30584]="30000,120000", [30585]="30000,120000", [30586]="30000,120000", [30587]="30000,120000",
+ [30588]="30000,120000", [30589]="30000,120000", [30590]="30000,120000", [30591]="30000,120000", [30592]="30000,120000", [30593]="30000,120000",
+ [30594]="30000,120000", [30597]="18492,92463", [30598]="35243,140972", [30599]="5535,22142", [30600]="30000,120000", [30601]="30000,120000",
+ [30602]="30000,120000", [30603]="30000,120000", [30604]="30000,120000", [30605]="30000,120000", [30606]="30000,120000", [30607]="30000,120000",
+ [30608]="30000,120000", [30609]="0,2000000", [30610]="280,5600", [30611]="6,5000", [30612]="6,5000", [30615]="1333,16000",
+ [30619]="91160,364641", [30620]="72039,288156", [30621]="72039,288156", [30622]="25000,100000", [30623]="25000,100000", [30626]="91160,364641",
+ [30627]="91160,364641", [30629]="91160,364641", [30633]="25000,100000", [30634]="25000,100000", [30635]="25000,100000", [30637]="25000,100000",
+ [30641]="58878,294391", [30642]="33835,169178", [30643]="33965,169829", [30644]="28413,142066", [30663]="72039,288156", [30664]="72039,288156",
+ [30665]="72039,288156", [30666]="88355,353421", [30667]="60256,241024", [30668]="23692,118462", [30673]="24124,120621", [30674]="45395,226978",
+ [30675]="24295,121477", [30676]="30477,152389", [30677]="36703,183518", [30678]="43218,216091", [30681]="42122,210614", [30682]="50968,254842",
+ [30683]="60937,304686", [30684]="93381,466907", [30685]="29290,146450", [30686]="35278,176392", [30687]="41542,207710", [30696]="15000,60000",
+ [30705]="46039,230197", [30707]="31466,157334", [30708]="26648,133244", [30709]="33564,167823", [30710]="50287,201151", [30720]="72039,288156",
+ [30722]="150514,752573", [30723]="120862,604314", [30724]="90976,454882", [30725]="24350,121753", [30726]="102777,411111", [30727]="49062,245310",
+ [30728]="55392,276962", [30729]="37063,185318", [30730]="61998,309991", [30731]="65210,326053", [30732]="144890,724452", [30733]="116363,581817",
+ [30734]="46725,233629", [30735]="35179,175898", [30736]="60256,241024", [30737]="44308,221542", [30738]="60256,241024", [30739]="71427,357138",
+ [30740]="62616,313082", [30741]="42221,211109", [30744]="30000,120000", [30745]="35000,140000", [30746]="25000,100000", [30747]="30000,120000",
+ [30748]="35000,140000", [30749]="29108,145540", [30750]="37874,189372", [30751]="29676,148381", [30752]="33679,168397", [30753]="65333,326668",
+ [30754]="27483,137417", [30755]="50995,254979", [30757]="20851,104257", [30758]="20675,103377", [30759]="20499,102498", [30765]="25321,126608",
+ [30771]="13006,65032", [30775]="21719,108595", [30777]="11851,59255", [30781]="20200,101003", [30784]="10100,50501", [30787]="90791,453956",
+ [30788]="91108,455540", [30789]="114292,571460", [30804]="1064,4258", [30809]="200,800", [30810]="200,800", [30811]="175,700",
+ [30812]="1185,4740", [30813]="1325,5300", [30814]="1185,4740", [30815]="1325,5300", [30816]="5,20", [30817]="1,25",
+ [30820]="1325,5300", [30821]="1185,4740", [30823]="75000,300000", [30825]="37037,148148", [30826]="30000,120000", [30830]="501016,2505080",
+ [30831]="25066,125331", [30832]="100968,504841", [30833]="15000,60000", [30834]="49382,197528", [30835]="52125,260629", [30836]="34880,174403",
+ [30837]="17088,85444", [30838]="17430,87150", [30839]="35267,176339", [30841]="43988,175952", [30842]="15000,60000", [30843]="20000,80000",
+ [30844]="25000,100000", [30845]="250000,1000000", [30846]="250000,1000000", [30855]="54657,273287", [30856]="28744,143724", [30857]="27388,109552",
+ [30859]="62985,314929", [30860]="41555,166220", [30861]="51559,257799", [30862]="51744,258720", [30863]="36880,184404", [30864]="44409,222048",
+ [30865]="134401,672006", [30866]="70700,353502", [30868]="33989,169945", [30869]="40943,204719", [30870]="27400,137003", [30871]="27502,137512",
+ [30872]="203059,1015299", [30873]="62628,313142", [30874]="139081,695408", [30878]="75931,379657", [30879]="36354,181770", [30880]="65964,329823",
+ [30881]="146462,732313", [30882]="94071,470355", [30883]="184368,921843", [30884]="44405,222027", [30885]="40316,201580", [30886]="50586,252930",
+ [30887]="81251,406258", [30888]="27188,135942", [30889]="87338,436690", [30891]="51561,257808", [30892]="64079,320396", [30893]="85374,426874",
+ [30894]="37542,187714", [30895]="28664,143323", [30896]="100692,503464", [30897]="50818,254091", [30898]="72439,362197", [30899]="72701,363505",
+ [30900]="87555,437776", [30901]="146434,732172", [30902]="195738,978692", [30903]="110003,550019", [30904]="110394,551970", [30905]="71583,357915",
+ [30906]="107792,538963", [30907]="86568,432843", [30908]="186039,930195", [30909]="95599,477996", [30910]="149931,749656", [30911]="203059,1015299",
+ [30912]="60418,302092", [30913]="60635,303177", [30914]="35696,178482", [30915]="50444,252224", [30916]="57527,287637", [30917]="54128,270640",
+ [30918]="144864,724324", [30919]="43616,218082", [30922]="22675,113378", [30923]="15170,75854", [30924]="15901,79505", [30925]="24553,122766",
+ [30926]="20879,104396", [30927]="14314,71570", [30928]="28046,140231", [30929]="28151,140757", [30930]="14474,72370", [30931]="21789,108948",
+ [30932]="16799,83997", [30933]="42153,210769", [30936]="18492,92463", [30937]="18559,92799", [30938]="27273,136366", [30939]="32306,161534",
+ [30940]="17421,87108", [30941]="34142,170710", [30942]="17556,87781", [30943]="20303,101519", [30944]="20381,101907", [30945]="35512,177562",
+ [30946]="26096,130482", [30947]="41907,209538", [30948]="49654,248272", [30950]="21188,105940", [30951]="25103,125519", [30952]="32948,164740",
+ [30953]="33069,165349", [30955]="32370,161850", [30956]="22189,110945", [30957]="45695,228479", [30958]="31251,156258", [30959]="48587,242935",
+ [30960]="47610,238050", [30961]="36652,183264", [30962]="28475,142378", [30964]="37072,185361", [30966]="24490,122454", [30967]="29018,145092",
+ [30968]="37632,188162", [30971]="21785,108926", [30973]="40860,163440", [30981]="36368,145472", [30984]="52160,260801", [30986]="44524,222621",
+ [30999]="79950,399750", [31000]="60195,300975", [31002]="80880,404401", [31009]="106568,532843", [31010]="106956,534781", [31013]="86486,432434",
+ [31025]="24577,122885", [31031]="25116,125582", [31033]="25295,126477", [31036]="108344,541721", [31038]="101456,507282", [31062]="103834,519172",
+ [31071]="79665,398325", [31072]="59981,299907", [31073]="80285,401426", [31074]="41555,166220", [31075]="41555,166220", [31076]="41555,166220",
+ [31077]="41555,166220", [31078]="41555,166220", [31079]="10000,40000", [31080]="4000,16000", [31089]="50000,0", [31090]="50000,0",
+ [31091]="50000,0", [31092]="50000,0", [31093]="50000,0", [31094]="50000,0", [31095]="50000,0", [31096]="50000,0",
+ [31097]="50000,0", [31098]="50000,0", [31099]="50000,0", [31100]="50000,0", [31101]="50000,0", [31102]="50000,0",
+ [31103]="50000,0", [31104]="25765,128825", [31105]="45161,225805", [31106]="38922,194614", [31107]="39062,195312", [31109]="32781,163907",
+ [31110]="32897,164488", [31111]="13825,69126", [31112]="26020,130103", [31113]="43988,175952", [31114]="20977,104889", [31115]="36782,183912",
+ [31116]="30000,120000", [31117]="30000,120000", [31118]="30000,120000", [31125]="33546,167732", [31126]="17317,86586", [31127]="41706,208532",
+ [31131]="16005,80025", [31133]="25608,128040", [31134]="82877,414389", [31136]="48207,241036", [31137]="24331,121657", [31138]="19802,99013",
+ [31139]="69628,348144", [31140]="20965,104827", [31142]="66009,330046", [31143]="21832,109162", [31145]="25499,127497", [31147]="28836,115344",
+ [31148]="27782,138912", [31149]="13599,67998", [31150]="13599,67998", [31151]="24635,123178", [31152]="50352,251762", [31153]="72203,361018",
+ [31154]="750,3000", [31155]="58153,290766", [31156]="50031,250158", [31157]="41843,209219", [31158]="33599,167995", [31159]="44177,220886",
+ [31160]="38247,191236", [31161]="31844,159224", [31162]="25568,127844", [31163]="28611,143057", [31164]="22786,113932", [31165]="18988,94943",
+ [31166]="15259,76297", [31168]="43954,219771", [31170]="37218,186093", [31172]="31015,155077", [31173]="31634,158172", [31174]="24812,124062",
+ [31175]="17496,87484", [31176]="24964,124821", [31177]="20399,101997", [31178]="38775,155100", [31179]="17928,89640", [31180]="25335,126679",
+ [31181]="13599,67998", [31182]="33546,167732", [31183]="31627,158135", [31184]="24007,120037", [31185]="19206,96030", [31186]="90367,451835",
+ [31187]="32533,162667", [31188]="24635,123178", [31189]="20996,104981", [31190]="26991,134956", [31191]="17496,87484", [31192]="13997,69987",
+ [31193]="71976,359883", [31194]="37731,150924", [31195]="27778,138894", [31196]="8788,35155", [31197]="22786,113932", [31198]="18988,94943",
+ [31199]="15191,75955", [31200]="47338,236690", [31201]="24836,124181", [31202]="26036,130180", [31203]="39818,159272", [31204]="55282,276412",
+ [31209]="56839,284195", [31210]="48900,244501", [31211]="40905,204526", [31212]="32848,164241", [31213]="41885,209425", [31214]="38398,191994",
+ [31215]="31973,159868", [31216]="25672,128360", [31217]="45002,225014", [31218]="35970,179850", [31219]="29975,149875", [31220]="23980,119900",
+ [31221]="26736,133680", [31222]="36400,182004", [31223]="22786,113932", [31224]="18921,94605", [31225]="15191,75955", [31226]="36982,184914",
+ [31227]="24126,120630", [31228]="20399,101997", [31229]="16999,84998", [31230]="23239,116195", [31231]="13599,67998", [31232]="35631,178155",
+ [31233]="30735,153676", [31234]="80717,403585", [31235]="25499,127497", [31236]="21834,109173", [31237]="40796,203982", [31238]="36689,146756",
+ [31240]="49481,247407", [31242]="50527,252638", [31243]="39605,198027", [31244]="33004,165023", [31246]="26403,132018", [31247]="35821,179109",
+ [31248]="31012,155061", [31249]="24753,123767", [31250]="20737,103685", [31254]="21593,107965", [31255]="24298,121493", [31256]="658,3294",
+ [31258]="55035,220141", [31263]="523,2616", [31264]="420,2101", [31268]="1066,5332", [31269]="1070,5352", [31270]="805,4029",
+ [31272]="24033,120167", [31275]="41903,167612", [31276]="40842,204213", [31277]="41903,167612", [31280]="23383,116916", [31281]="29587,147938",
+ [31282]="31177,155888", [31283]="15899,79496", [31284]="28806,144030", [31285]="41068,205343", [31286]="47960,239800", [31287]="51157,255786",
+ [31288]="29975,149875", [31289]="99916,499583", [31290]="10709,42837", [31291]="107599,537997", [31292]="52430,262152", [31293]="24576,122883",
+ [31294]="40363,201819", [31295]="40961,204806", [31297]="32769,163845", [31298]="58768,293844", [31299]="105351,526757", [31303]="64180,320904",
+ [31304]="85891,429455", [31305]="86216,431083", [31306]="33564,167823", [31308]="104889,524447", [31312]="21446,107232", [31313]="17936,89680",
+ [31314]="32544,162722", [31315]="25434,127172", [31318]="123328,616641", [31319]="79025,316102", [31320]="69592,347960", [31321]="115200,460801",
+ [31322]="125228,626140", [31323]="75416,377080", [31326]="60256,241024", [31328]="63118,315592", [31329]="28260,141301", [31330]="47683,238415",
+ [31331]="106334,531673", [31332]="106717,533586", [31333]="40162,200812", [31334]="134340,671700", [31335]="53927,269636", [31336]="432949,2164745",
+ [31337]="6250,25000", [31338]="88355,353421", [31339]="60256,241024", [31340]="39762,198814", [31341]="20052,100261", [31342]="102901,514509",
+ [31343]="41313,206568", [31354]="10000,40000", [31355]="10000,40000", [31356]="10000,40000", [31357]="10000,40000", [31358]="30000,120000",
+ [31359]="15000,60000", [31361]="15000,60000", [31362]="30000,120000", [31364]="82308,411540", [31367]="83219,416097", [31368]="62517,312585",
+ [31369]="83818,419094", [31370]="74152,370760", [31371]="55708,278542", [31380]="41903,167612", [31381]="41903,167612", [31382]="41903,167612",
+ [31383]="41903,167612", [31390]="60000,240000", [31391]="60000,240000", [31392]="60000,240000", [31393]="60000,240000", [31394]="60000,240000",
+ [31395]="60000,240000", [31398]="60256,241024", [31399]="60256,241024", [31401]="30000,120000", [31402]="30000,120000", [31414]="83568,417844",
+ [31415]="44029,220145", [31416]="50525,252628", [31417]="102273,511368", [31418]="12893,64466", [31419]="24266,121331", [31420]="29359,146795",
+ [31421]="22947,114735", [31422]="65433,327169", [31423]="67420,337102", [31424]="50747,253739", [31425]="13580,67900", [31426]="17036,85180",
+ [31427]="30911,154555", [31428]="24155,120778", [31429]="20660,103301", [31430]="15631,78157", [31431]="18830,94154", [31432]="33015,165076",
+ [31433]="25968,129841", [31434]="32585,162926", [31435]="30196,150984", [31436]="35293,176466", [31438]="19848,99244", [31439]="17050,85252",
+ [31440]="20533,102668", [31441]="35996,179981", [31442]="27578,137890", [31443]="34597,172987", [31444]="31247,156235", [31445]="24530,122650",
+ [31446]="69937,349688", [31447]="70180,350903", [31448]="70430,352152", [31452]="12932,64664", [31453]="24342,121713", [31454]="19549,97745",
+ [31455]="23653,118265", [31456]="20754,103773", [31457]="26039,130196", [31458]="41816,209083", [31459]="48960,244803", [31460]="31388,156943",
+ [31461]="17899,89498", [31462]="26944,134722", [31464]="22616,113082", [31465]="27237,136187", [31470]="25002,125013", [31471]="32246,161232",
+ [31472]="19420,97104", [31473]="22872,114364", [31474]="50204,251023", [31475]="67189,335947", [31476]="67439,337196", [31477]="13188,65940",
+ [31478]="24818,124094", [31479]="19928,99640", [31480]="23468,117340", [31481]="13381,66907", [31482]="16787,83938", [31483]="35314,176572",
+ [31484]="20291,101456", [31485]="27149,135748", [31486]="34058,170294", [31487]="28583,142919", [31488]="33411,167058", [31490]="52380,261901",
+ [31491]="52578,262893", [31492]="81771,408859", [31493]="41555,166220", [31494]="41555,166220", [31501]="100000,400000", [31508]="26847,134236",
+ [31509]="20212,101061", [31510]="13186,65933", [31511]="33940,169700", [31512]="16606,83033", [31513]="16669,83345", [31514]="41189,205946",
+ [31515]="20669,103347", [31516]="20225,101128", [31519]="50226,251130", [31520]="37732,188660", [31521]="36916,184581", [31523]="41555,166220",
+ [31526]="41555,166220", [31527]="41555,166220", [31528]="41555,166220", [31531]="13574,67873", [31532]="25548,127742", [31533]="30910,154551",
+ [31534]="24159,120797", [31537]="20835,104177", [31538]="26135,130677", [31539]="20983,104916", [31540]="24708,123541", [31541]="72250,361251",
+ [31542]="90633,453165", [31543]="82287,411437", [31544]="39983,199917", [31545]="40134,200671", [31546]="24173,120867", [31547]="36399,181999",
+ [31548]="56839,284195", [31549]="57050,285251", [31552]="133297,26659", [31553]="26754,133772", [31554]="35802,179013", [31555]="17966,89832",
+ [31556]="36063,180315", [31557]="25855,129277", [31558]="18160,90800", [31559]="91125,18225", [31560]="34290,171454", [31561]="34412,172064",
+ [31562]="46046,230233", [31563]="20903,104515", [31564]="41964,209823", [31565]="30097,150487", [31566]="21145,105725", [31567]="109046,21809",
+ [31568]="39399,39399", [31569]="39721,198607", [31570]="52922,264614", [31571]="26559,132795", [31572]="53308,266541", [31573]="38395,191975",
+ [31574]="26849,134247", [31576]="236167,47233", [31577]="47404,237020", [31578]="63553,317769", [31579]="32070,160350", [31580]="64003,320017",
+ [31581]="45802,229010", [31582]="32413,162068", [31583]="151230,30246", [31615]="8222,32891", [31617]="8222,32891", [31657]="22454,112272",
+ [31658]="21130,105652", [31659]="16969,84848", [31660]="15873,79366", [31661]="15092,75461", [31666]="5000,20000", [31670]="200,800",
+ [31671]="200,800", [31672]="150,600", [31673]="150,600", [31674]="7500,30000", [31675]="7500,30000", [31676]="5000,20000",
+ [31677]="5000,20000", [31679]="3000,12000", [31680]="10000,40000", [31681]="10000,40000", [31682]="10000,40000", [31683]="13887,69438",
+ [31684]="17423,87118", [31685]="41966,209831", [31686]="49140,245700", [31687]="21136,105684", [31688]="26514,132573", [31689]="42577,212886",
+ [31690]="25068,125344", [31691]="39818,159272", [31692]="39818,159272", [31693]="39818,159272", [31694]="39818,159272", [31695]="39818,159272",
+ [31696]="39818,159272", [31699]="34629,138516", [31700]="85828,429141", [31701]="86148,430743", [31703]="69424,347122", [31711]="20900,104501",
+ [31712]="24355,121777", [31713]="29338,146694", [31714]="23037,115187", [31715]="28546,114184", [31717]="27137,135686", [31718]="34046,170231",
+ [31719]="41009,205045", [31720]="48023,240115", [31723]="62449,312249", [31724]="48321,241608", [31725]="12933,64665", [31726]="30574,122296",
+ [31727]="30574,122296", [31728]="32023,128092", [31729]="32023,128092", [31730]="32023,128092", [31731]="32023,128092", [31732]="32023,128092",
+ [31733]="61828,309143", [31734]="39721,198609", [31735]="25,20000", [31737]="25,20000", [31745]="91143,455716", [31746]="60256,241024",
+ [31747]="41953,167814", [31748]="41953,167814", [31749]="41953,167814", [31756]="71638,358193", [31758]="72181,360908", [31759]="72453,362265",
+ [31760]="5000,20000", [31761]="47720,238603", [31762]="47893,239467", [31764]="39664,198320", [31765]="46440,232203", [31766]="19974,99871",
+ [31768]="18476,92384", [31770]="11890,59453", [31773]="2500,10000", [31774]="2500,10000", [31776]="2500,10000", [31777]="2500,10000",
+ [31778]="2500,10000", [31779]="2500,10000", [31780]="2500,10000", [31781]="2500,10000", [31782]="39375,196879", [31783]="26345,131726",
+ [31784]="24787,123938", [31785]="82921,414608", [31786]="27639,138196", [31787]="21600,108004", [31788]="15396,76980", [31789]="16773,83869",
+ [31790]="34629,138516", [31791]="41555,166220", [31792]="20526,102630", [31793]="17169,85845", [31794]="44616,223080", [31796]="19263,96316",
+ [31797]="24165,120828", [31798]="25871,129357", [31804]="2500,10000", [31816]="82425,412127", [31817]="29915,149575", [31818]="34629,138516",
+ [31819]="34935,174676", [31820]="32891,131564", [31821]="67150,335753", [31823]="32023,128092", [31829]="0,700000", [31830]="0,700000",
+ [31831]="0,700000", [31832]="0,700000", [31833]="0,700000", [31834]="0,700000", [31835]="0,700000", [31836]="0,700000",
+ [31837]="14750,59000", [31853]="1000,4000", [31855]="1000,4000", [31856]="100000,400000", [31857]="100000,400000", [31858]="100000,400000",
+ [31859]="100000,400000", [31860]="2500,10000", [31861]="30000,120000", [31862]="2500,10000", [31863]="30000,120000", [31864]="2500,10000",
+ [31865]="30000,120000", [31866]="2500,10000", [31867]="30000,120000", [31868]="30000,120000", [31869]="2500,10000", [31870]="15000,60000",
+ [31871]="15000,60000", [31872]="15000,60000", [31873]="15000,60000", [31874]="15000,60000", [31875]="30000,120000", [31876]="30000,120000",
+ [31877]="30000,120000", [31878]="30000,120000", [31879]="30000,120000", [31882]="25000,100000", [31883]="25000,100000", [31884]="25000,100000",
+ [31885]="25000,100000", [31886]="25000,100000", [31887]="25000,100000", [31888]="25000,100000", [31889]="25000,100000", [31890]="200000,800000",
+ [31891]="200000,800000", [31892]="25000,100000", [31893]="25000,100000", [31894]="25000,100000", [31895]="25000,100000", [31896]="25000,100000",
+ [31898]="25000,100000", [31899]="25000,100000", [31900]="25000,100000", [31901]="25000,100000", [31902]="25000,100000", [31903]="25000,100000",
+ [31904]="25000,100000", [31905]="25000,100000", [31906]="25000,100000", [31907]="200000,800000", [31908]="25000,100000", [31909]="25000,100000",
+ [31910]="25000,100000", [31911]="25000,100000", [31912]="25000,100000", [31913]="25000,100000", [31914]="200000,800000", [31915]="25000,100000",
+ [31916]="25000,100000", [31917]="25000,100000", [31918]="25000,100000", [31919]="51700,206800", [31920]="51700,206800", [31921]="51700,206800",
+ [31922]="51700,206800", [31923]="51700,206800", [31924]="51700,206800", [31925]="10709,42837", [31926]="10709,42837", [31927]="10709,42837",
+ [31928]="10709,42837", [31929]="10709,42837", [31935]="25757,128787", [31936]="25850,129252", [31937]="24090,120453", [31938]="24183,120918",
+ [31939]="24276,121383", [31940]="22464,89857", [31942]="25775,128876", [31943]="10709,42837", [31944]="870,3480", [31945]="990,3960",
+ [31949]="6,5000", [31951]="2500,10000", [31952]="750,3000", [31955]="12,50", [32062]="1250,5000", [32063]="1500,6000",
+ [32067]="1500,6000", [32068]="1500,6000", [32070]="10000,40000", [32072]="38286,191433", [32073]="57213,286066", [32076]="33127,165637",
+ [32077]="33252,166262", [32078]="50288,251444", [32080]="42030,210152", [32081]="197528,790112", [32082]="74176,370882", [32193]="60000,240000",
+ [32194]="60000,240000", [32195]="60000,240000", [32196]="60000,240000", [32197]="60000,240000", [32198]="60000,240000", [32199]="60000,240000",
+ [32200]="60000,240000", [32201]="60000,240000", [32202]="60000,240000", [32203]="60000,240000", [32204]="60000,240000", [32205]="60000,240000",
+ [32206]="60000,240000", [32207]="60000,240000", [32208]="60000,240000", [32209]="60000,240000", [32210]="60000,240000", [32211]="60000,240000",
+ [32212]="60000,240000", [32213]="60000,240000", [32214]="60000,240000", [32215]="60000,240000", [32216]="60000,240000", [32217]="60000,240000",
+ [32218]="60000,240000", [32219]="60000,240000", [32220]="60000,240000", [32221]="60000,240000", [32222]="60000,240000", [32223]="60000,240000",
+ [32224]="60000,240000", [32225]="60000,240000", [32226]="60000,240000", [32227]="50000,0", [32228]="50000,0", [32229]="50000,0",
+ [32230]="50000,0", [32231]="50000,0", [32232]="50639,253195", [32233]="1250,5000", [32234]="43467,217339", [32235]="58105,290528",
+ [32236]="145939,729697", [32237]="146462,732313", [32238]="60256,241024", [32239]="37542,187714", [32240]="55506,277534", [32241]="60474,302371",
+ [32242]="62666,313333", [32243]="72923,364616", [32245]="73471,367357", [32247]="60256,241024", [32248]="177210,886051", [32249]="50000,0",
+ [32250]="65575,327875", [32251]="42997,214985", [32252]="71923,359617", [32253]="108266,541334", [32254]="144879,724395", [32255]="93057,465287",
+ [32256]="29185,145925", [32257]="43930,219651", [32258]="40965,204825", [32259]="41122,205610", [32260]="88355,353421", [32261]="60256,241024",
+ [32262]="138629,693145", [32263]="87600,438001", [32264]="63126,315634", [32265]="35046,175230", [32266]="60256,241024", [32267]="67698,338493",
+ [32268]="74271,371358", [32269]="142263,711315", [32270]="28557,142786", [32271]="62571,312857", [32273]="43302,216512", [32274]="15000,60000",
+ [32275]="40494,202471", [32276]="40647,203235", [32277]="15000,60000", [32278]="48060,240304", [32279]="48240,241200", [32280]="44050,220252",
+ [32281]="15000,60000", [32282]="15000,60000", [32283]="15000,60000", [32284]="15000,60000", [32285]="15000,60000", [32286]="15000,60000",
+ [32287]="15000,60000", [32288]="15000,60000", [32289]="15000,60000", [32290]="15000,60000", [32291]="15000,60000", [32292]="15000,60000",
+ [32293]="15000,60000", [32294]="15000,60000", [32295]="15000,60000", [32296]="15000,60000", [32297]="15000,60000", [32298]="15000,60000",
+ [32299]="15000,60000", [32300]="15000,60000", [32301]="15000,60000", [32302]="15000,60000", [32303]="15000,60000", [32304]="15000,60000",
+ [32305]="15000,60000", [32306]="15000,60000", [32307]="15000,60000", [32308]="15000,60000", [32309]="15000,60000", [32310]="15000,60000",
+ [32311]="15000,60000", [32312]="15000,60000", [32314]="0,2000000", [32316]="0,2000000", [32317]="0,2000000", [32318]="0,2000000",
+ [32319]="0,2000000", [32323]="42852,214264", [32324]="35841,179207", [32325]="107906,539531", [32326]="36368,145472", [32327]="57968,289843",
+ [32328]="36357,181788", [32329]="43786,218930", [32330]="43943,219715", [32331]="44100,220500", [32332]="184386,921932", [32333]="52107,260536",
+ [32334]="80640,403203", [32335]="60256,241024", [32336]="108233,541167", [32337]="40787,203935", [32338]="40943,204719", [32339]="35187,175937",
+ [32340]="50057,250286", [32341]="87600,438001", [32342]="50091,250457", [32343]="107110,535554", [32344]="179172,895861", [32345]="75383,376915",
+ [32346]="43315,216576", [32347]="36223,181116", [32348]="181770,908852", [32349]="88355,353421", [32350]="203059,1015299", [32351]="36742,183714",
+ [32352]="55310,276553", [32353]="29603,148018", [32354]="70418,352094", [32361]="203059,1015299", [32362]="86443,345774", [32363]="107100,535501",
+ [32365]="100692,503464", [32366]="54133,270667", [32367]="57951,289758", [32368]="75000,300000", [32369]="145925,729627", [32370]="102777,411111",
+ [32373]="72100,360504", [32374]="183948,919743", [32375]="94538,472692", [32376]="62618,313092", [32377]="52373,261865", [32378]="9,37",
+ [32381]="4000,16000", [32387]="25096,125484", [32388]="146,585", [32389]="50288,251440", [32390]="25241,126205", [32391]="38007,190037",
+ [32392]="25432,127163", [32393]="31912,159561", [32394]="48050,240252", [32395]="32155,160775", [32396]="64546,322731", [32397]="38873,194366",
+ [32398]="58788,293943", [32399]="39164,195823", [32400]="78612,393063", [32401]="46290,231451", [32402]="69163,345819", [32403]="47855,239279",
+ [32404]="95498,477493", [32409]="30000,120000", [32410]="30000,120000", [32411]="30000,120000", [32412]="30000,120000", [32413]="2500,10000",
+ [32420]="40345,201727", [32423]="2000,8000", [32428]="20000,80000", [32429]="20000,80000", [32430]="20000,80000", [32431]="20000,80000",
+ [32432]="20000,80000", [32433]="20000,80000", [32434]="20000,80000", [32435]="20000,80000", [32436]="20000,80000", [32437]="20000,80000",
+ [32438]="20000,80000", [32439]="20000,80000", [32440]="20000,80000", [32441]="20000,80000", [32442]="20000,80000", [32443]="20000,80000",
+ [32444]="20000,80000", [32445]="2500,10000", [32447]="20000,80000", [32453]="125,2500", [32455]="60,1200", [32458]="0,1000000",
+ [32461]="69205,346027", [32464]="1500,6000", [32468]="1000,4000", [32470]="1250,5000", [32471]="149388,746944", [32472]="66971,334856",
+ [32473]="67220,336101", [32474]="57941,289705", [32475]="58149,290745", [32476]="58363,291815", [32478]="48992,244961", [32479]="49165,245828",
+ [32480]="49343,246718", [32483]="91160,364641", [32485]="72039,288156", [32486]="72039,288156", [32487]="72039,288156", [32488]="72039,288156",
+ [32489]="72039,288156", [32490]="72039,288156", [32491]="72039,288156", [32492]="72039,288156", [32493]="72039,288156", [32494]="38619,193098",
+ [32495]="38762,193811", [32496]="91160,364641", [32497]="60256,241024", [32500]="143271,716358", [32501]="91160,364641", [32505]="91160,364641",
+ [32508]="3500,14000", [32510]="63120,315602", [32512]="49524,247620", [32513]="28240,141202", [32514]="10709,42837", [32515]="45804,229023",
+ [32516]="26806,134033", [32517]="66456,332284", [32518]="55331,276659", [32519]="29614,148074", [32520]="22464,89857", [32521]="75350,376753",
+ [32522]="53945,269727", [32524]="43636,218184", [32525]="43804,219020", [32526]="60256,241024", [32527]="60256,241024", [32528]="60256,241024",
+ [32529]="30465,152329", [32531]="41953,167814", [32532]="22462,112312", [32533]="22464,89857", [32534]="66290,265161", [32535]="55035,220141",
+ [32536]="91143,455716", [32537]="91468,457344", [32538]="27538,137691", [32539]="27633,138166", [32540]="30808,154043", [32541]="30928,154643",
+ [32568]="50091,250457", [32570]="65575,327875", [32571]="50639,253195", [32573]="65575,327875", [32574]="43624,218124", [32575]="65964,329823",
+ [32577]="44091,220457", [32579]="66904,334521", [32580]="34533,172667", [32581]="51991,259956", [32582]="34791,173958", [32583]="52383,261918",
+ [32584]="28039,140198", [32585]="42216,211082", [32586]="28249,141245", [32587]="42530,212652", [32589]="60256,241024", [32590]="42997,214985",
+ [32591]="88355,353421", [32592]="86613,433067", [32593]="54329,271648", [32596]="2300,0", [32597]="2300,0", [32598]="2300,0",
+ [32599]="2300,0", [32600]="2300,0", [32601]="2300,0", [32606]="49713,248566", [32608]="44050,220252", [32609]="42835,214179",
+ [32620]="1250,5000", [32624]="32200,0", [32625]="24150,0", [32626]="0,32200", [32627]="0,24150", [32628]="32200,0",
+ [32629]="32200,0", [32630]="24150,0", [32631]="24150,0", [32634]="9200,0", [32635]="9200,0", [32636]="9200,0",
+ [32637]="9200,0", [32638]="9200,0", [32639]="9200,0", [32640]="36800,0", [32641]="36800,0", [32645]="55200,0",
+ [32647]="55200,0", [32648]="55200,0", [32650]="19550,0", [32651]="55200,0", [32652]="19550,0", [32653]="19550,0",
+ [32654]="19550,0", [32655]="20699,103495", [32656]="31165,155826", [32658]="10000,40000", [32659]="85574,427872", [32660]="88222,441112",
+ [32661]="88547,442739", [32662]="111091,555459", [32663]="111498,557493", [32664]="43988,175952", [32665]="26952,134761", [32667]="85,340",
+ [32668]="320,6400", [32681]="155,620", [32682]="155,620", [32683]="155,620", [32684]="155,620", [32685]="400,8000",
+ [32686]="400,8000", [32688]="1,1", [32689]="1,1", [32690]="1,1", [32691]="1,1", [32692]="1,1",
+ [32693]="1,1", [32700]="1,1", [32701]="1,1", [32702]="1,1", [32703]="1,1", [32704]="1,1",
+ [32705]="1,1", [32706]="1,1", [32707]="1,1", [32708]="1,1", [32709]="1,1", [32710]="1,1",
+ [32711]="1,1", [32712]="1,1", [32713]="1,1", [32714]="27,111", [32715]="12500,50000", [32716]="12500,50000",
+ [32717]="12500,50000", [32718]="12500,50000", [32721]="225,4500", [32722]="200,4000", [32725]="2,10", [32727]="2,10",
+ [32728]="250,1000", [32735]="30000,120000", [32736]="7500,30000", [32737]="7500,30000", [32738]="7500,30000", [32739]="7500,30000",
+ [32742]="7500,30000", [32744]="12500,50000", [32745]="12500,50000", [32746]="12500,50000", [32747]="12500,50000", [32748]="12500,50000",
+ [32749]="12500,50000", [32750]="12500,50000", [32751]="12500,50000", [32752]="12500,50000", [32753]="12500,50000", [32754]="12500,50000",
+ [32755]="12500,50000", [32756]="80011,400058", [32758]="2500,10000", [32759]="8050,0", [32760]="20,100", [32769]="20977,104889",
+ [32770]="10307,41230", [32771]="10307,41230", [32772]="39122,156488", [32774]="39122,156488", [32776]="26757,133785", [32778]="43969,219848",
+ [32779]="83797,335188", [32780]="62933,314668", [32781]="90808,454044", [32782]="4618,18475", [32783]="690,0", [32784]="460,0",
+ [32828]="2300,0", [32829]="103467,517339", [32830]="103855,519277", [32831]="62545,312729", [32832]="9954,39818", [32833]="10000,40000",
+ [32836]="10000,40000", [32837]="243112,1215564", [32838]="243974,1219873", [32839]="750,3000", [32849]="750,3000", [32850]="750,3000",
+ [32851]="750,3000", [32852]="750,3000", [32854]="139429,697148", [32857]="0,2000000", [32858]="0,2000000", [32859]="0,2000000",
+ [32860]="0,2000000", [32861]="0,2000000", [32862]="0,2000000", [32863]="17500,70000", [32865]="17688,88444", [32866]="37217,186085",
+ [32867]="14257,71286", [32868]="32343,161716", [32869]="36876,184381", [32870]="44412,222064", [32871]="38924,194622", [32872]="55914,279571",
+ [32882]="6,5000", [32883]="6,5000", [32909]="690,0", [32910]="460,0", [32941]="97528,390112", [32942]="97528,390112",
+ [32943]="140184,700922", [32944]="134251,671256", [32945]="141230,706154", [32946]="141739,708699", [33012]="25000,100000", [33014]="12500,50000",
+ [33023]="50,200", [33024]="100,400", [33025]="125,500", [33026]="200,800", [33028]="3,15", [33029]="12,50",
+ [33030]="1,3", [33031]="25,100", [33032]="50,200", [33033]="100,400", [33034]="100,400", [33035]="160,640",
+ [33036]="160,640", [33042]="320,6400", [33043]="0,3", [33048]="200,4000", [33052]="200,4000", [33053]="200,4000",
+ [33054]="60256,241024", [33055]="60256,241024", [33058]="60256,241024", [33060]="30000,120000", [33081]="5,20", [33083]="0,10",
+ [33092]="5000,20000", [33093]="5000,20000", [33117]="20000,80000", [33122]="38029,190146", [33124]="12500,50000", [33131]="30000,120000",
+ [33132]="30000,120000", [33133]="30000,120000", [33134]="30000,120000", [33135]="30000,120000", [33137]="30000,120000", [33138]="30000,120000",
+ [33139]="30000,120000", [33140]="30000,120000", [33141]="30000,120000", [33142]="30000,120000", [33143]="30000,120000", [33144]="30000,120000",
+ [33148]="25000,100000", [33149]="25000,100000", [33150]="25000,100000", [33151]="25000,100000", [33152]="25000,100000", [33153]="25000,100000",
+ [33155]="30000,120000", [33156]="30000,120000", [33157]="30000,120000", [33158]="30000,120000", [33159]="30000,120000", [33160]="30000,120000",
+ [33165]="7500,30000", [33173]="46380,231903", [33174]="20000,80000", [33185]="18000,72000", [33186]="950,3800", [33191]="69481,347406",
+ [33203]="48289,241445", [33204]="52547,262735", [33205]="60000,240000", [33206]="57303,286516", [33208]="5000,20000", [33209]="10000,40000",
+ [33211]="33146,165731", [33214]="137848,689243", [33215]="94140,470702", [33216]="94475,472377", [33224]="0,100000", [33225]="0,1000000",
+ [33228]="3227,16136", [33229]="3239,16195", [33230]="4170,20854", [33231]="3390,16953", [33232]="2701,13505", [33233]="2276,11382",
+ [33234]="200,4000", [33235]="1031,5158", [33236]="280,5600", [33237]="5772,28861", [33239]="5407,27036", [33240]="5025,25126",
+ [33241]="5447,27238", [33242]="5468,27340", [33243]="3811,19055", [33244]="3825,19125", [33245]="1994,9974", [33246]="280,5600",
+ [33247]="3014,15070", [33248]="3327,16638", [33249]="3339,16699", [33250]="2234,11173", [33251]="6277,31388", [33252]="5401,27008",
+ [33253]="3696,18480", [33254]="400,8000", [33255]="3748,18744", [33256]="3763,18816", [33257]="3500,17503", [33258]="7540,37701",
+ [33259]="4171,20857", [33260]="3617,18088", [33261]="3631,18156", [33262]="5105,20420", [33263]="5514,22056", [33264]="4728,18912",
+ [33265]="4378,17512", [33266]="4378,17512", [33267]="9547,47739", [33268]="9582,47914", [33269]="8905,44527", [33270]="9651,48259",
+ [33271]="10487,52436", [33272]="9026,45130", [33273]="7339,36697", [33274]="6316,31580", [33281]="102777,411111", [33283]="132215,661078",
+ [33285]="25932,129661", [33286]="58563,292815", [33292]="2,10", [33293]="60256,241024", [33297]="88355,353421", [33298]="129945,649725",
+ [33299]="66444,332223", [33300]="47725,238628", [33303]="69237,346186", [33305]="30000,120000", [33307]="15000,60000", [33317]="50333,251665",
+ [33322]="65813,329069", [33326]="85458,427293", [33327]="70220,351100", [33328]="80691,403458", [33329]="67482,337412", [33332]="79001,395007",
+ [33354]="131461,657309", [33356]="48278,241393", [33357]="37012,185062", [33388]="128494,642473", [33389]="128987,644935", [33421]="73002,365013",
+ [33432]="60691,303457", [33446]="43619,218096", [33453]="40605,203028", [33463]="42080,210404", [33464]="59168,295842", [33465]="163113,815566",
+ [33466]="88355,353421", [33467]="136956,684782", [33468]="137469,687347", [33469]="80013,400067", [33471]="38338,191693", [33473]="94727,473638",
+ [33474]="101161,505805", [33476]="141544,707724", [33478]="178195,890979", [33479]="51857,259287", [33480]="24892,124461", [33481]="65461,327309",
+ [33489]="38619,193095", [33490]="166140,830701", [33491]="100053,500267", [33492]="167354,836772", [33493]="134375,671879", [33494]="168585,842926",
+ [33495]="135360,676802", [33496]="60256,241024", [33497]="60256,241024", [33498]="60256,241024", [33499]="60256,241024", [33500]="60256,241024",
+ [33533]="80412,402062", [33590]="39763,198819", [33591]="39907,199536", [33592]="37194,185974", [33622]="30000,120000", [33640]="131408,657043",
+ [33782]="30000,120000", [33791]="316,1582", [33792]="25,100", [33803]="2,1000", [33804]="15000,60000", [33805]="55765,278827",
+ [33820]="25490,127451", [33823]="8,160", [33824]="8,160", [33825]="150,600", [33828]="91160,364641", [33829]="91160,364641",
+ [33830]="91160,364641", [33831]="91160,364641", [33844]="87,350", [33846]="463,1855", [33854]="563,2255", [33855]="3750,15000",
+ [33856]="33,135", [33857]="113,455", [33865]="400,1600", [33866]="550,2200", [33867]="8,160", [33869]="5000,20000",
+ [33870]="5000,20000", [33871]="5000,20000", [33872]="150,600", [33873]="5000,20000", [33874]="150,600", [33875]="5000,20000",
+ [33924]="125,500", [33925]="5000,20000", [33926]="250,1000", [33928]="250,1000", [33934]="11500,4000", [33935]="11500,4000",
+ [33954]="120000,480000", [33971]="61687,308437", [33976]="0,100000", [33977]="0,1000000", [33999]="0,20000000", [34009]="134867,674339",
+ [34010]="41605,208028", [34011]="86315,431577", [34012]="40460,202301", [34017]="1,3", [34018]="3,15", [34019]="12,50",
+ [34020]="25,100", [34021]="50,200", [34022]="100,400", [34029]="8991,35965", [34063]="12,50", [34064]="25,100",
+ [34065]="3,15", [34067]="50000,200000", [34085]="1,7", [34086]="1,5", [34087]="1,7", [34092]="0,2000000",
+ [34099]="22500,90000", [34100]="22500,90000", [34105]="37500,150000", [34106]="37500,150000", [34109]="625,2500", [34113]="10000,40000",
+ [34114]="30000,120000", [34130]="95,380", [34164]="151025,755128", [34165]="151593,757967", [34166]="60256,241024", [34167]="110128,550640",
+ [34168]="94746,473732", [34169]="62571,312857", [34170]="63625,318129", [34172]="40000,160000", [34173]="40000,160000", [34174]="40000,160000",
+ [34175]="40000,160000", [34176]="132215,661078", [34177]="88355,353421", [34178]="86443,345774", [34179]="203059,1015299", [34180]="107273,536365",
+ [34181]="61526,307632", [34182]="187343,936717", [34183]="188053,940266", [34184]="102777,411111", [34185]="97000,485000", [34186]="94035,470175",
+ [34188]="81034,405170", [34189]="60256,241024", [34190]="47535,237678", [34192]="65575,327875", [34193]="65575,327875", [34194]="74834,374170",
+ [34195]="56371,281855", [34196]="109851,549255", [34197]="147035,735179", [34198]="184504,922523", [34199]="148171,740857", [34200]="40000,160000",
+ [34201]="40000,160000", [34202]="46315,231578", [34203]="154493,772468", [34204]="88355,353421", [34205]="46684,233420", [34206]="203059,1015299",
+ [34207]="7500,30000", [34208]="73247,366238", [34209]="60989,304945", [34210]="48966,244833", [34211]="81895,409478", [34212]="82188,410940",
+ [34213]="60256,241024", [34214]="160693,803465", [34215]="105203,526018", [34216]="105613,528065", [34218]="40000,160000", [34220]="30000,120000",
+ [34221]="30000,120000", [34227]="6200,24800", [34228]="97222,486110", [34229]="97572,487864", [34230]="60256,241024", [34231]="101743,508718",
+ [34232]="65744,328721", [34233]="64043,320219", [34234]="41378,206893", [34240]="55395,276976", [34241]="48771,243858", [34242]="48952,244762",
+ [34243]="85819,429095", [34244]="61642,308210", [34245]="61861,309308", [34247]="207710,1038554", [34249]="250000,1000000", [34261]="1250,5000",
+ [34262]="1250,5000", [34319]="1250,5000", [34329]="155299,776495", [34330]="7500,30000", [34331]="156503,782515", [34332]="72630,363152",
+ [34333]="72901,364507", [34334]="182930,914654", [34335]="163190,815954", [34336]="163793,818965", [34337]="205493,1027469", [34339]="49674,248374",
+ [34340]="49855,249277", [34341]="44050,220252", [34342]="33477,167389", [34343]="50392,251962", [34344]="33715,168576", [34345]="88649,443249",
+ [34346]="160109,800549", [34347]="120496,602483", [34348]="112452,562260", [34349]="36368,145472", [34350]="45316,226584", [34351]="37906,189530",
+ [34352]="44050,220252", [34353]="59014,295074", [34354]="82761,413808", [34355]="71337,356686", [34356]="71600,358002", [34357]="83681,418406",
+ [34358]="88355,353421", [34359]="88355,353421", [34360]="88355,353421", [34361]="60256,241024", [34362]="60256,241024", [34363]="60256,241024",
+ [34364]="60849,304249", [34365]="61077,305387", [34366]="30655,153278", [34367]="30772,153863", [34369]="77508,387544", [34370]="38900,194503",
+ [34371]="78093,390469", [34372]="39193,195965", [34373]="94404,472024", [34374]="47377,236889", [34375]="95106,475534", [34376]="47728,238644",
+ [34377]="111765,558829", [34378]="44050,220252", [34379]="112584,562923", [34380]="58294,291472", [34410]="200,4000", [34411]="160,640",
+ [34412]="50,1000", [34413]="2500,10000", [34416]="4005,20029", [34417]="5007,25036", [34418]="20060,100301", [34419]="25914,103656",
+ [34421]="12089,60448", [34422]="14025,70128", [34423]="10000,40000", [34424]="10000,40000", [34427]="72039,288156", [34428]="72039,288156",
+ [34429]="72039,288156", [34430]="72039,288156", [34440]="7000,28000", [34469]="10000,40000", [34470]="72039,288156", [34471]="72039,288156",
+ [34472]="72039,288156", [34473]="72039,288156", [34476]="100000,400000", [34482]="30000,120000", [34484]="2500,10000", [34486]="2500,10000",
+ [34490]="40000,160000", [34491]="24000,96000", [34504]="6250,25000", [34535]="2500,10000", [34537]="2500,10000", [34538]="1500,6000",
+ [34539]="1500,6000", [34581]="12,10000", [34582]="12,10000", [34601]="61631,308159", [34602]="29513,147565", [34603]="36689,146756",
+ [34604]="118908,594542", [34605]="85715,428578", [34606]="122873,614366", [34607]="33469,167348", [34608]="139999,699996", [34609]="121317,606588",
+ [34610]="48709,243546", [34611]="122241,611208", [34612]="64300,321500", [34613]="46191,230959", [34614]="74180,370901", [34615]="86871,434358",
+ [34616]="124570,622853", [34622]="20000,80000", [34625]="75000,300000", [34664]="22500,90000", [34665]="91803,459015", [34666]="92128,460643",
+ [34667]="83638,418194", [34670]="86938,434690", [34671]="87263,436317", [34672]="87589,437945", [34673]="109893,549466", [34674]="66173,330867",
+ [34675]="75568,377842", [34676]="75846,379231", [34677]="58188,232752", [34678]="58188,232752", [34679]="58188,232752", [34680]="58188,232752",
+ [34689]="30000,120000", [34697]="16782,83911", [34698]="25173,125867", [34699]="83911,419558", [34700]="29536,147684", [34701]="41955,209779",
+ [34702]="25300,126500", [34703]="84659,423297", [34704]="14846,59387", [34705]="16782,83911", [34706]="55035,220141", [34707]="31466,157334",
+ [34708]="25173,125867", [34780]="250,5000", [34783]="43988,175952", [34788]="26567,132835", [34789]="29536,147684", [34790]="89207,446039",
+ [34791]="25173,125867", [34792]="25173,125867", [34793]="16782,83911", [34794]="104889,524447", [34795]="43969,219848", [34796]="41955,209779",
+ [34797]="104889,524447", [34798]="7102,28410", [34799]="64477,322385", [34807]="56310,281550", [34808]="21492,107461", [34809]="42681,213405",
+ [34810]="32238,161192", [34822]="250000,1000000", [34823]="180000,720000", [34824]="150000,600000", [34825]="110000,440000", [34826]="150000,600000",
+ [34827]="112803,564018", [34828]="113219,566099", [34829]="110000,440000", [34831]="30000,120000", [34832]="50,200", [34834]="5000,20000",
+ [34836]="2000,8000", [34837]="11300,45200", [34838]="670,2680", [34839]="15000,60000", [34840]="20000,80000", [34841]="4000,16000",
+ [34843]="15000,60000", [34845]="8750,35000", [34846]="4762,19050", [34847]="48800,244003", [34848]="50000,0", [34850]="25,100",
+ [34851]="50000,0", [34852]="50000,0", [34853]="50000,0", [34854]="50000,0", [34855]="50000,0", [34856]="50000,0",
+ [34857]="50000,0", [34858]="50000,0", [34859]="42800,214001", [34860]="17000,68000", [34861]="137,550", [34872]="37500,150000",
+ [34907]="15000,60000", [35128]="11250,45000", [35181]="46676,233380", [35182]="58564,292822", [35183]="58777,293889", [35184]="72681,363408",
+ [35185]="84940,424701", [35186]="20000,80000", [35187]="37500,150000", [35189]="37500,150000", [35190]="37500,150000", [35191]="37500,150000",
+ [35192]="37500,150000", [35193]="37500,150000", [35194]="37500,150000", [35195]="37500,150000", [35196]="37500,150000", [35197]="37500,150000",
+ [35198]="35000,140000", [35199]="35000,140000", [35200]="35000,140000", [35201]="35000,140000", [35202]="35000,140000", [35203]="35000,140000",
+ [35204]="20000,80000", [35205]="20000,40000", [35206]="20000,80000", [35207]="20000,80000", [35208]="20000,80000", [35209]="20000,80000",
+ [35210]="20000,80000", [35211]="20000,80000", [35212]="20000,80000", [35213]="20000,80000", [35214]="20000,40000", [35215]="20000,80000",
+ [35216]="20000,80000", [35217]="20000,80000", [35218]="20000,80000", [35219]="20000,80000", [35221]="2500,10000", [35225]="0,1000000",
+ [35226]="0,2000000", [35238]="125000,500000", [35239]="125000,500000", [35240]="125000,500000", [35241]="125000,500000", [35242]="125000,500000",
+ [35243]="125000,500000", [35244]="125000,500000", [35245]="125000,500000", [35246]="125000,500000", [35247]="125000,500000", [35248]="125000,500000",
+ [35249]="125000,500000", [35250]="125000,500000", [35251]="125000,500000", [35252]="125000,500000", [35253]="125000,500000", [35254]="125000,500000",
+ [35255]="125000,500000", [35256]="125000,500000", [35257]="125000,500000", [35258]="125000,500000", [35259]="125000,500000", [35260]="125000,500000",
+ [35261]="125000,500000", [35262]="125000,500000", [35263]="125000,500000", [35264]="125000,500000", [35265]="125000,500000", [35266]="125000,500000",
+ [35267]="125000,500000", [35268]="125000,500000", [35269]="125000,500000", [35270]="125000,500000", [35271]="125000,500000", [35273]="20000,80000",
+ [35275]="4618,18475", [35282]="60256,241024", [35283]="60256,241024", [35284]="60256,241024", [35285]="50,200", [35286]="100,400",
+ [35287]="50,0", [35290]="60256,241024", [35291]="60256,241024", [35292]="60256,241024", [35294]="25000,100000", [35295]="20000,80000",
+ [35296]="950,3800", [35297]="30000,120000", [35298]="10000,40000", [35299]="30000,120000", [35300]="60000,240000", [35301]="60000,240000",
+ [35302]="60000,240000", [35303]="60000,240000", [35304]="30000,120000", [35305]="30000,120000", [35306]="30000,120000", [35307]="30000,120000",
+ [35308]="20000,80000", [35309]="30000,120000", [35310]="17500,70000", [35311]="20000,80000", [35314]="75,300", [35315]="30000,120000",
+ [35316]="30000,120000", [35318]="30000,120000", [35322]="30000,120000", [35323]="30000,120000", [35325]="30000,120000", [35328]="17391,86955",
+ [35329]="26181,130908", [35330]="35039,175195", [35331]="26377,131885", [35332]="35299,176497", [35333]="26569,132848", [35334]="35556,177782",
+ [35335]="17843,89216", [35336]="26862,134313", [35337]="35943,179717", [35338]="18036,90184", [35339]="27152,135764", [35340]="36334,181670",
+ [35341]="27345,136728", [35342]="36591,182955", [35343]="27540,137704", [35344]="25693,128467", [35345]="17194,85970", [35346]="34518,172591",
+ [35347]="34648,173242", [35356]="22381,111905", [35357]="33693,168468", [35358]="45087,225438", [35359]="33937,169689", [35360]="42171,210856",
+ [35361]="21167,105835", [35362]="31872,159363", [35363]="42655,213276", [35364]="32113,160567", [35365]="55952,223811", [35366]="21571,107858",
+ [35367]="32476,162381", [35368]="43464,217323", [35369]="32720,163602", [35370]="43790,218950", [35371]="21974,109871", [35372]="33083,165417",
+ [35373]="44273,221369", [35374]="33327,166637", [35375]="55952,223811", [35376]="53709,268547", [35377]="27651,138258", [35378]="37657,188286",
+ [35379]="50405,252025", [35380]="38118,190594", [35381]="50795,253978", [35382]="25492,127464", [35383]="38385,191928", [35384]="51376,256881",
+ [35385]="38850,194253", [35386]="51761,258808", [35387]="25978,129892", [35388]="47383,189533", [35389]="52347,261737", [35390]="39578,197891",
+ [35391]="52732,263664", [35392]="26464,132320", [35393]="40887,204438", [35394]="54712,273561", [35395]="41363,206818", [35396]="650,0",
+ [35397]="650,0", [35398]="650,0", [35399]="650,0", [35400]="650,0", [35402]="59477,297385", [35403]="30023,150115",
+ [35404]="44864,224320", [35405]="60154,300772", [35406]="45200,226002", [35407]="60610,303051", [35408]="30589,152949", [35409]="46929,234646",
+ [35410]="62919,314598", [35411]="47270,236352", [35412]="63369,316846", [35413]="31980,159901", [35414]="47777,238887", [35415]="64052,320263",
+ [35416]="48114,240570", [35417]="650,0", [35418]="650,0", [35419]="650,0", [35420]="650,0", [35421]="650,0",
+ [35422]="650,0", [35423]="650,0", [35424]="650,0", [35425]="650,0", [35426]="650,0", [35427]="650,0",
+ [35428]="650,0", [35429]="650,0", [35430]="650,0", [35431]="650,0", [35432]="650,0", [35433]="650,0",
+ [35434]="650,0", [35435]="650,0", [35436]="650,0", [35437]="650,0", [35438]="650,0", [35439]="650,0",
+ [35440]="650,0", [35441]="650,0", [35442]="650,0", [35443]="650,0", [35444]="650,0", [35445]="650,0",
+ [35446]="650,0", [35447]="650,0", [35448]="650,0", [35449]="650,0", [35450]="650,0", [35451]="650,0",
+ [35452]="650,0", [35453]="650,0", [35454]="650,0", [35455]="650,0", [35456]="650,0", [35457]="650,0",
+ [35458]="650,0", [35459]="650,0", [35460]="650,0", [35461]="650,0", [35462]="650,0", [35464]="35165,175829",
+ [35465]="26469,132346", [35466]="26567,132835", [35467]="35552,177764", [35468]="22301,111509", [35469]="44762,223811", [35470]="33693,168468",
+ [35471]="22543,112719", [35472]="54295,271476", [35473]="25302,126514", [35474]="38100,190503", [35475]="25498,127490", [35476]="44702,223513",
+ [35477]="30143,150719", [35478]="45043,225219", [35487]="60000,240000", [35488]="60000,240000", [35489]="60000,240000", [35494]="32525,162629",
+ [35495]="32647,163237", [35496]="32772,163863", [35497]="32238,161192", [35498]="15000,60000", [35500]="37500,150000", [35501]="30000,120000",
+ [35502]="37500,150000", [35503]="30000,120000", [35504]="2500,10000", [35505]="37500,150000", [35507]="50000,200000", [35508]="50000,200000",
+ [35509]="50000,200000", [35511]="50000,200000", [35513]="0,1000000", [35514]="135496,677481", [35516]="8750,35000", [35557]="0,10",
+ [35562]="37,150", [35563]="12,240", [35564]="4500,18000", [35565]="12,240", [35566]="4500,18000", [35581]="26127,130639",
+ [35582]="15000,60000", [35691]="237,950", [35693]="15000,60000", [35694]="12000,48000", [35695]="62500,250000", [35696]="62500,250000",
+ [35697]="62500,250000", [35698]="62500,250000", [35699]="62500,250000", [35700]="15000,60000", [35702]="15000,60000", [35703]="15000,60000",
+ [35707]="30000,120000", [35708]="30000,120000", [35720]="500,2000", [35733]="60256,241024", [35748]="25000,100000", [35749]="25000,100000",
+ [35750]="25000,100000", [35751]="25000,100000", [35752]="62500,250000", [35753]="62500,250000", [35754]="62500,250000", [35755]="62500,250000",
+ [35756]="30000,120000", [35758]="30000,120000", [35759]="30000,120000", [35760]="60000,240000", [35761]="60000,240000", [35762]="15000,60000",
+ [35763]="15000,60000", [35764]="15000,60000", [35765]="15000,60000", [35766]="125000,500000", [35767]="125000,500000", [35768]="125000,500000",
+ [35769]="125000,500000", [37127]="0,35965", [37128]="0,35965", [37148]="8750,35000", [37488]="6,150", [37489]="6,150",
+ [37490]="6,150", [37491]="6,150", [37492]="6,150", [37493]="6,150", [37494]="6,150", [37495]="0,150",
+ [37496]="6,150", [37497]="6,150", [37498]="6,150", [37499]="6,150", [37503]="60000,240000", [37504]="125000,500000",
+ [37588]="275,5500", [37597]="122920,614601", [37676]="0,2000000", [37710]="5000,20000", [37719]="0,1000000", [37828]="0,1000000",
+ [37915]="1250,5000", [37934]="50000,24000000", [38082]="100000,12000000", [38089]="40000,20000000", [38090]="50000,6000000", [38091]="0,30000000",
+ [38175]="119893,599469", [38225]="23750,95000", [38276]="12556,62781", [38277]="1824,9122", [38278]="1664,8324", [38287]="0,100000",
+ [38288]="0,100000", [38289]="0,100000", [38290]="0,100000", [38327]="1250,5000", [38328]="1125,4500", [38427]="280,5600",
+ [38428]="400,8000", [38429]="200,4000", [38430]="280,5600", [38431]="320,6400", [38432]="375,1500", [38466]="500,2000",
+ [38506]="25500,127503", [38518]="37,150", [38576]="0,1000000", [38626]="2,1", [38628]="100000,400000" }
+for k,v in pairs(pfSellData_tbc) do pfSellData[k] = v end
diff --git a/libs/librange.lua b/libs/librange.lua
index 05c06743..1b050316 100644
--- a/libs/librange.lua
+++ b/libs/librange.lua
@@ -1,6 +1,8 @@
-- load pfUI environment
setfenv(1, pfUI:GetEnvironment())
+local superwow_active = HasSuperWoW()
+
--[[ librange ]]--
-- A pfUI library that detects and caches distance to units.
--
diff --git a/modules/castbar.lua b/modules/castbar.lua
index b8ad0df7..ea6d33ae 100644
--- a/modules/castbar.lua
+++ b/modules/castbar.lua
@@ -1,4 +1,6 @@
pfUI:RegisterModule("castbar", "vanilla", function ()
+ local superwow_active = HasSuperWoW()
+
local font = C.castbar.use_unitfonts == "1" and pfUI.font_unit or pfUI.font_default
local font_size = C.castbar.use_unitfonts == "1" and C.global.font_unit_size or C.global.font_size
local rawborder, default_border = GetBorderSize("unitframes")
diff --git a/modules/combatlogfix.lua b/modules/combatlogfix.lua
new file mode 100644
index 00000000..99ac6a0a
--- /dev/null
+++ b/modules/combatlogfix.lua
@@ -0,0 +1,7 @@
+pfUI:RegisterModule("combatlogfix", "tbc", function ()
+ -- Fixes the combatlog break bugs that exist since patch 2.4 by simply clearing the whole log
+ -- on every update. This is required in order to receive new log events. Otherwise, addons like
+ -- Omen or Recount won't work and simply don't receive any new data at a given time.
+ local combatlog = CreateFrame("Frame", "pfCombatLogFix", UIParent)
+ combatlog:SetScript("OnUpdate", CombatLogClearEntries)
+end)
diff --git a/modules/nameplates.lua b/modules/nameplates.lua
index ce25a161..1835b99a 100644
--- a/modules/nameplates.lua
+++ b/modules/nameplates.lua
@@ -2,6 +2,9 @@ pfUI:RegisterModule("nameplates", "vanilla", function ()
-- disable original castbars
pcall(SetCVar, "ShowVKeyCastbar", 0)
+ -- check for SuperWoW support
+ local superwow_active = HasSuperWoW()
+
local unitcolors = {
["ENEMY_NPC"] = { .9, .2, .3, .8 },
["NEUTRAL_NPC"] = { 1, 1, .3, .8 },
@@ -631,6 +634,7 @@ pfUI:RegisterModule("nameplates", "vanilla", function ()
end
if player and unittype == "ENEMY_NPC" then unittype = "ENEMY_PLAYER" end
+ if player and unittype == "FRIENDLY_NPC" then unittype = "FRIENDLY_PLAYER" end
elite = plate.original.levelicon:IsShown() and not player and "boss" or elite
if not class then plate.wait_for_scan = true end
diff --git a/modules/thirdparty-tbc.lua b/modules/thirdparty-tbc.lua
new file mode 100644
index 00000000..8642dada
--- /dev/null
+++ b/modules/thirdparty-tbc.lua
@@ -0,0 +1,381 @@
+pfUI:RegisterModule("thirdparty-tbc", "tbc", function ()
+ -- abort when thirdparty core module is not loaded
+ if not pfUI.thirdparty then return end
+ local rawborder, default_border = GetBorderSize()
+
+ HookAddonOrVariable("Omen", function()
+ local docktable = { "omen", "Omen", "OmenBarList",
+ function() -- single
+ Omen.BarList:ClearAllPoints()
+ Omen.BarList:SetPoint("TOPLEFT", pfUI.chat.right, "TOPLEFT", -5, 5)
+ Omen.BarList:SetPoint("BOTTOMRIGHT", pfUI.chat.right, "BOTTOMRIGHT", 5, pfUI.panel.right:GetHeight()-5)
+ Omen.BarList:SetWidth(pfUI.chat.right:GetWidth() + 7)
+
+ -- backdrop adjustments
+ if Omen.BarList.backdrop then
+ Omen.BarList.backdrop:SetPoint("TOPLEFT", -default_border+5, default_border-5)
+ Omen.BarList.backdrop:SetPoint("BOTTOMRIGHT", default_border-5, -18-default_border+5)
+ end
+ end,
+ function() -- dual
+ Omen.BarList:ClearAllPoints()
+ Omen.BarList:SetPoint("TOPLEFT", pfUI.chat.right, "TOPLEFT", -5, 5)
+ Omen.BarList:SetPoint("BOTTOMRIGHT", pfUI.chat.right, "BOTTOM", -default_border+5, pfUI.panel.right:GetHeight()-5)
+ Omen.BarList:SetWidth(pfUI.chat.right:GetWidth() / 2 + 7)
+
+ -- backdrop adjustments
+ if Omen.BarList.backdrop then
+ Omen.BarList.backdrop:SetPoint("TOPLEFT", -default_border+5, default_border-5)
+ Omen.BarList.backdrop:SetPoint("BOTTOMRIGHT", default_border-5, -18-default_border+5)
+ end
+ end,
+ function() -- show
+ Omen:UpdateDisplay()
+ Omen:EnableLastModule()
+ Omen:LayoutModuleIcons()
+
+ Omen.ModuleList:SetPoint("BOTTOMLEFT", Omen.BarList, "TOPLEFT", 5, default_border*3-5)
+ Omen.ModuleList:SetPoint("BOTTOMRIGHT", Omen.BarList, "TOPRIGHT", -5, default_border*3)
+
+ -- fake sizes to retain proper button sizes
+ Omen.ModuleList._GetHeight = Omen.ModuleList._GetHeight or Omen.ModuleList.GetHeight
+ Omen.ModuleList.GetHeight = function() return 30 end
+ Omen:LayoutModuleIcons()
+ Omen.ModuleList.GetHeight = Omen.ModuleList._GetHeight
+ Omen.ModuleList:SetHeight(20)
+
+ OmenResizeGrip:Hide()
+ Omen:Toggle(true)
+ end,
+ function() -- hide
+ Omen:Toggle(nil)
+ end,
+ function() -- once
+ Omen.Title:Hide()
+ Omen.Title.Show = function() return end
+ EnableAutohide(Omen.ModuleList, 1)
+
+ local hookUpdateDisplay = Omen.UpdateDisplay
+ Omen.UpdateDisplay = function(self)
+ hookUpdateDisplay(self)
+ pfUI.thirdparty.meters:Resize()
+ end
+
+ Omen.UpdateVisible = function()
+ if pfUI.thirdparty.meters.state then
+ Omen.Anchor:Show()
+ else
+ Omen.Anchor:Hide()
+ end
+ end
+ end,
+ }
+
+ pfUI.thirdparty.meters:RegisterMeter("threat", docktable)
+
+ if C.thirdparty.omen.skin == "1" then
+ if Omen.Anchor then
+
+ local hookUpdateDisplay = Omen.UpdateDisplay
+ Omen.UpdateDisplay = function(self)
+ hookUpdateDisplay(self)
+
+ StripTextures(Omen.Title)
+ StripTextures(Omen.ModuleList)
+ StripTextures(Omen.BarList)
+
+ if not Omen.Title.backdrop or not Omen.ModuleList.backdrop or not Omen.BarList.backdrop then
+ CreateBackdrop(Omen.Title, nil, nil, (C.thirdparty.chatbg == "1" and .8))
+ CreateBackdropShadow(Omen.Title)
+
+ CreateBackdrop(Omen.ModuleList, nil, nil, (C.thirdparty.chatbg == "1" and .8))
+ CreateBackdropShadow(Omen.ModuleList)
+
+ CreateBackdrop(Omen.BarList, nil, nil, (C.thirdparty.chatbg == "1" and .8))
+ CreateBackdropShadow(Omen.BarList)
+ end
+
+ if C.thirdparty.chatbg == "1" and C.chat.global.custombg == "1" then
+ local r, g, b, a = strsplit(",", C.chat.global.background)
+ Omen.BarList.backdrop:SetBackdropColor(tonumber(r), tonumber(g), tonumber(b), tonumber(a))
+ Omen.ModuleList.backdrop:SetBackdropColor(tonumber(r), tonumber(g), tonumber(b), tonumber(a))
+
+ local r, g, b, a = strsplit(",", C.chat.global.border)
+ Omen.BarList.backdrop:SetBackdropBorderColor(tonumber(r), tonumber(g), tonumber(b), tonumber(a))
+ Omen.ModuleList.backdrop:SetBackdropColor(tonumber(r), tonumber(g), tonumber(b), tonumber(a))
+ end
+ end
+
+ HookScript(Omen.Anchor, "OnShow", function()
+ for i, child in pairs({ OmenModuleButtons:GetChildren() }) do
+ if child and child:IsObjectType("Button") then
+ child:GetNormalTexture():SetTexCoord(.08, .92, .08, .92)
+ CreateBackdrop(child, nil, true)
+ end
+ end
+ end)
+
+ Omen:UpdateDisplay()
+ end
+ end
+ end)
+
+ HookAddonOrVariable("Recount", function()
+ local docktable = { "recount", "Recount", "Recount_MainWindow",
+ function() -- single
+ Recount.MainWindow:ClearAllPoints()
+ Recount.MainWindow:SetPoint("TOPLEFT", pfUI.chat.right, "TOPLEFT", 0, 10)
+ Recount.MainWindow:SetPoint("BOTTOMRIGHT", pfUI.chat.right, "BOTTOMRIGHT", 0, 18)
+ Recount.MainWindow:SetWidth(pfUI.chat.right:GetWidth())
+ end,
+ function() -- dual
+ Recount.MainWindow:ClearAllPoints()
+ Recount.MainWindow:SetPoint("TOPLEFT", pfUI.chat.right, "TOP", default_border, 10)
+ Recount.MainWindow:SetPoint("BOTTOMRIGHT", pfUI.chat.right, "BOTTOMRIGHT", 0, 18)
+ Recount.MainWindow:SetWidth(pfUI.chat.right:GetWidth() / 2)
+ end,
+ function() -- show
+ Recount.MainWindow:Show()
+ Recount:ResizeMainWindow()
+ Recount:RefreshMainWindow()
+ end,
+ function() -- hide
+ Recount.MainWindow:Hide()
+ end,
+ function() -- once
+ local hookResize = Recount.ResizeMainWindow
+ Recount.ResizeMainWindow = function()
+ hookResize()
+
+ local a, b, c = Recount.MainWindow:GetPoint()
+ if b == pfUI.chat.right and Recount.MainWindow.backdrop then
+ Recount.MainWindow.backdrop:SetPoint("BOTTOMRIGHT", default_border, -18-default_border)
+ else
+ Recount.MainWindow.backdrop:SetPoint("BOTTOMRIGHT", default_border, default_border)
+ end
+ end
+ end,
+ }
+
+ pfUI.thirdparty.meters:RegisterMeter("damage", docktable)
+
+ if C.thirdparty.recount.skin == "1" then
+ if Recount_MainWindow then
+ StripTextures(Recount.MainWindow)
+ CreateBackdrop(Recount.MainWindow, nil, nil, (C.thirdparty.chatbg == "1" and .8))
+ CreateBackdropShadow(Recount.MainWindow)
+ SkinScrollbar(Recount_MainWindow_ScrollBarScrollBar)
+ Recount_MainWindow_ScrollBarScrollBarScrollUpButton.Overlay:SetTexture(nil)
+ Recount_MainWindow_ScrollBarScrollBarScrollDownButton.Overlay:SetTexture(nil)
+ Recount.MainWindow.DragBottomLeft:SetNormalTexture(nil)
+ Recount.MainWindow.DragBottomRight:SetNormalTexture(nil)
+
+ -- backdrop adjustments
+ Recount.MainWindow.backdrop:SetPoint("TOPLEFT", -default_border, -5-default_border-GetPerfectPixel())
+ if C.thirdparty.chatbg == "1" and C.chat.global.custombg == "1" then
+ local r, g, b, a = strsplit(",", C.chat.global.background)
+ Recount.MainWindow.backdrop:SetBackdropColor(tonumber(r), tonumber(g), tonumber(b), tonumber(a))
+
+ local r, g, b, a = strsplit(",", C.chat.global.border)
+ Recount.MainWindow.backdrop:SetBackdropBorderColor(tonumber(r), tonumber(g), tonumber(b), tonumber(a))
+ end
+ end
+ end
+ end)
+
+ HookAddonOrVariable("BCEPGP_LootFrame_Update", function()
+ if C.thirdparty.bcepgp.enable == "0" then return end
+
+ local hook = _G.BCEPGP_LootFrame_Update
+ _G.BCEPGP_LootFrame_Update = function(a,b,c,d,e,f)
+ LootFrame.numLootItems = GetNumLootItems()
+ hook(a,b,c,d,e,f)
+ end
+ end)
+
+ -- Sheep Watch Continued
+ -- https://www.curseforge.com/wow/addons/sheep-watch-continued/files/225593
+ HookAddonOrVariable("SheepWatch", function()
+ if C.thirdparty.sheepwatch.enable == "0" then return end
+
+ StripTextures(SheepWatch)
+
+ if SheepWatchFrameStatusBar then
+ SheepWatchFrameStatusBar:SetStatusBarTexture(pfUI.media["img:bar"])
+ SheepWatchFrameStatusBar:SetHeight(14)
+ CreateBackdrop(SheepWatchFrameStatusBar)
+ CreateBackdropShadow(SheepWatchFrameStatusBar)
+ end
+
+ if SheepWatchText then
+ SheepWatchText:ClearAllPoints()
+ SheepWatchText:SetPoint("CENTER", 0, 4)
+ end
+
+ if SheepWatchCounterText then
+ SheepWatchCounterText:ClearAllPoints()
+ SheepWatchCounterText:SetPoint("RIGHT", 0, 4)
+ end
+ end)
+
+ HookAddonOrVariable("Bag_Sort", function()
+ if C.thirdparty.bag_sort.enable == "0" then return end
+
+ local sort = CreateFrame("Frame", nil)
+ sort:RegisterEvent("PLAYER_ENTERING_WORLD")
+ sort:SetScript("OnEvent", function()
+ this:UnregisterAllEvents()
+
+ pfUI.thirdparty.RegisterBagSort("Bag_Sort",
+ function()
+ BS_slashBagSortHandler()
+ end,
+ function()
+ GameTooltip:SetOwner(this, "ANCHOR_RIGHT")
+ GameTooltip:SetText(GetAddOnMetadata("Bag_Sort","Title"))
+ GameTooltip:AddLine(GetAddOnMetadata("Bag_Sort","Notes"),1,1,1)
+ GameTooltip:Show()
+ end,
+ function()
+ BS_slashBankSortHandler()
+ end,
+ function()
+ GameTooltip:SetOwner(this, "ANCHOR_RIGHT")
+ GameTooltip:SetText(GetAddOnMetadata("Bag_Sort","Title"))
+ GameTooltip:AddLine(GetAddOnMetadata("Bag_Sort","Notes"),1,1,1)
+ GameTooltip:Show()
+ end)
+ end)
+ end)
+
+ HookAddonOrVariable("AckisRecipeList", function()
+ if C.thirdparty.ackis.enable == "0" then return end
+ if AckisRecipeList.ShowScanButton then
+ local AckisRecipeListShowScanButton = AckisRecipeList.ShowScanButton
+ AckisRecipeList.ShowScanButton = function(a1,a2,a3,a4)
+ -- run the original function
+ AckisRecipeListShowScanButton(a1,a2,a3,a4)
+
+ -- apply skin and reposition the button
+ SkinButton(AckisRecipeList.ScanButton)
+ local a,b,c,d,e = AckisRecipeList.ScanButton:GetPoint()
+ AckisRecipeList.ScanButton:SetPoint(a,b,c,d-14,e-2)
+ end
+ end
+ end)
+
+ HookAddonOrVariable("TotemTimers", function()
+ if C.thirdparty.totemtimers.enable == "0" then return end
+
+ local function skin(button, weapon)
+ if button and not button.pfskinned then
+ button.pfskinned = true
+
+ local icon = button.icon or _G[button:GetName().."Icon"]
+ icon:SetDrawLayer("BORDER")
+
+ SkinButton(button, nil, nil, nil, icon)
+ SetAllPointsOffset(icon, button, 2)
+
+ if _G[button:GetName().."Flash"] then
+ SetAllPointsOffset(_G[button:GetName().."Flash"], button, 3)
+ _G[button:GetName().."Flash"]:SetTexCoord(.08, .92, .08, .92)
+ end
+
+ if button.spellIcon then
+ button.spellIcon:SetPoint("BOTTOMRIGHT", button, "BOTTOMRIGHT", -2, 2)
+ button.spellIcon:SetTexCoord(.08, .92, .08, .92)
+ end
+
+ if weapon then
+ -- weapon button skin workaround taken from ElvUI-TBC:
+ -- https://github.com/ElvUI-TBC/ElvUI_AddOnSkins/blob/master/ElvUI_AddOnSkins/Skins/Addons/totemTimers.lua#L92-L135
+ local icon2frame = _G[button:GetName().."Icon2Frame"]
+ icon2frame:SetFrameStrata("MEDIUM")
+ icon2frame:SetWidth(icon2frame:GetWidth() + 1)
+ button.icon2 = _G[button:GetName().."Icon2"]
+ SetAllPointsOffset(button.icon2, icon2frame, 2)
+
+ button.icon1Frame = CreateFrame("Frame", "TotemTimers_MainHandIcon1Frame", button)
+ button.icon1Frame:SetWidth(16)
+ button.icon1Frame:SetHeight(30)
+ button.icon1Frame:SetPoint("LEFT", 0, 0)
+
+ button.icon1 = button.icon1Frame:CreateTexture(nil, "MEDIUM")
+ SetAllPointsOffset(button.icon1, button.icon1Frame, 3)
+ button.icon1:SetTexture(icon:GetTexture())
+ button.icon1:SetAlpha(icon:GetAlpha())
+
+ _G[button:GetName().."Cooldown"]:SetFrameLevel(button.icon1Frame:GetFrameLevel() + 1)
+
+ icon:Hide()
+ hooksecurefunc(icon, "SetTexture", function(_, texture)
+ button.icon1:SetTexture(texture)
+ end)
+ hooksecurefunc(icon, "SetAlpha", function(_, alpha)
+ button.icon1:SetAlpha(alpha)
+ end)
+
+ if icon:GetTexCoordModifiesRect() then
+ button.icon1:SetTexCoord(.08, .5, .08, .92)
+ else
+ button.icon1:SetTexCoord(.08, .92, .08, .92)
+ end
+ button.icon2:SetTexCoord(.5, .92, .08, .92)
+
+ hooksecurefunc(icon, "SetTexCoord", function(self, arg1, arg2)
+ if arg2 == 0.5 and arg1 == 0 then
+ button.icon1:SetTexCoord(.08, .5, .08, .92)
+ elseif arg2 == 1 then
+ button.icon1:SetTexCoord(.08, .92, .08, .92)
+ end
+ end)
+ hooksecurefunc(button.icon2, "SetTexCoord", function(self, arg1, arg2)
+ if arg2 == 1 then self:SetTexCoord(.5, .92, .08, .92) end
+ end)
+ end
+ end
+ end
+
+ hooksecurefunc("TotemTimers_SetupGlobals", function()
+ for i=1,4 do -- skin main buttons
+ for j=1,10 do skin(_G[i.."SlaveButton"..j]) end
+ skin(_G["TotemTimers"..i])
+ end
+
+ for _, timer in pairs({ "EarthElemental", "FireElemental", "ManaTide", "ManaTrinket" }) do
+ skin(_G["TotemTimers_"..timer])
+ end
+
+ for i, tracker in pairs({ "Ankh", "Shield", "MainHand", "EarthShield" }) do
+ skin(_G["TotemTimers_"..tracker], i==3)
+ end
+ end)
+ end)
+
+ HookAddonOrVariable("DruidBarFrame", function()
+ if C.thirdparty.druidbar.enable == "0" then return end
+ local p = ManaBarColor[0]
+ local pr, pg, pb = 0, 0, 0
+ if p then pr, pg, pb = p.r + .5, p.g +.5, p.b +.5 end
+ DruidBarKey.color = { pr, pg, pb, 1 }
+ DruidBarKey.bordercolor = {1,1,1,0}
+ DruidBarKey.bgcolor = {0,0,0,0}
+ DruidBarKey.manatexture = pfUI.media[pfUI.uf.player.config.pbartexture]
+ DruidBarKey.bordertexture = ""
+
+ hooksecurefunc("DruidBar_MainGraphics", function()
+ local f = pfUI.uf.player
+ DruidBarFrame:SetWidth((f.config.pwidth ~= "-1" and f.config.pwidth or f.config.width))
+ DruidBarFrame:SetHeight(f.config.pheight)
+ DruidBarMana:SetAllPoints(DruidBarFrame)
+
+ DruidBarText:SetFont(pfUI.font_unit, C.global.font_unit_size, "OUTLINE")
+ DruidBarText1:SetFont(pfUI.font_unit, C.global.font_unit_size, "OUTLINE")
+
+ StripTextures(DruidBarFrame)
+ CreateBackdrop(DruidBarFrame)
+ CreateBackdropShadow(DruidBarFrame)
+ end)
+ end)
+end)
diff --git a/pfUI.toc b/pfUI.toc
index 72c42fa4..187f4a22 100644
--- a/pfUI.toc
+++ b/pfUI.toc
@@ -3,7 +3,7 @@
## Author: Shagu
## Notes: A complete user interface replacement.
## Notes-ruRU: Полная замена пользовательского интерфейса.
-## Version: 5.5.4
+## Version: 5.5.5
## SavedVariables: pfUI_profiles, pfUI_addon_profiles, pfUI_cache
## SavedVariablesPerCharacter: pfUI_config, pfUI_init, pfUI_playerDB
diff --git a/skins/blizzard/arena.lua b/skins/blizzard/arena.lua
new file mode 100644
index 00000000..d87c98eb
--- /dev/null
+++ b/skins/blizzard/arena.lua
@@ -0,0 +1,55 @@
+pfUI:RegisterSkin("Arena", "tbc", function ()
+ StripTextures(ArenaFrame)
+ CreateBackdrop(ArenaFrame, nil, nil, .75)
+ CreateBackdropShadow(ArenaFrame)
+
+ ArenaFrame.backdrop:SetPoint("TOPLEFT", 10, -10)
+ ArenaFrame.backdrop:SetPoint("BOTTOMRIGHT", -32, 72)
+ ArenaFrame:SetHitRectInsets(10,32,10,72)
+ EnableMovable(ArenaFrame)
+
+ SkinCloseButton(ArenaFrameCloseButton, ArenaFrame.backdrop, -6, -6)
+
+ ArenaFrame:DisableDrawLayer("BACKGROUND")
+
+ ArenaFrameFrameLabel:ClearAllPoints()
+ ArenaFrameFrameLabel:SetPoint("TOP", TabardFrame.backdrop, "TOP", 0, -10)
+
+ ArenaFrame.zones_bg = CreateFrame("Frame", "ArenaFrameZonesBackground", ArenaFrame)
+ CreateBackdrop(ArenaFrame.zones_bg, nil, nil, .7)
+ ArenaFrame.zones_bg:SetWidth(324)
+ ArenaFrame.zones_bg:SetHeight(204)
+ ArenaFrame.zones_bg:SetPoint("TOPLEFT", ArenaFrame.backdrop, "TOPLEFT", 9, -62)
+
+ ArenaFrame.tex1 = ArenaFrame.backdrop:CreateTexture("ArenaFrameWorldMap1", "ARTWORK")
+ ArenaFrame.tex1:SetTexture("Interface\\BattlefieldFrame\\UI-Battlefield-WorldMap1")
+ ArenaFrame.tex1:SetPoint("TOPLEFT", 11, -64)
+ ArenaFrame.tex1:SetHeight(240)
+ ArenaFrame.tex2 = ArenaFrame.backdrop:CreateTexture("ArenaFrameWorldMap2", "ARTWORK")
+ ArenaFrame.tex2:SetTexture("Interface\\BattlefieldFrame\\UI-Battlefield-WorldMap2")
+ ArenaFrame.tex2:SetPoint("LEFT", ArenaFrame.tex1, "RIGHT", 0, 0)
+ ArenaFrame.tex2:SetHeight(240)
+
+ ArenaFrameNameHeader:ClearAllPoints()
+ ArenaFrameNameHeader:SetPoint("BOTTOMLEFT", ArenaFrameDivider, "TOPLEFT", 14, 70)
+ local shift = 28
+ ArenaZone1:ClearAllPoints()
+ ArenaZone1:SetPoint("TOPLEFT", ArenaFrame, "TOPLEFT", 23, -79 - shift)
+ ArenaZone4:ClearAllPoints()
+ ArenaZone4:SetPoint("TOPLEFT", ArenaZone3, "TOPLEFT", 0, -85 + shift)
+
+ ArenaFrame.textbox = CreateFrame("Frame", "ArenaFrameTextBox", ArenaFrame)
+ ArenaFrame.textbox:SetWidth(324)
+ ArenaFrame.textbox:SetHeight(110)
+ CreateBackdrop(ArenaFrame.textbox)
+ ArenaFrame.textbox:SetPoint("BOTTOM", ArenaFrame.backdrop, "BOTTOM", 0, 36)
+
+ ArenaFrameZoneDescription:SetFontObject(GameFontWhite)
+ ArenaFrameZoneDescription:ClearAllPoints()
+ ArenaFrameZoneDescription:SetPoint("TOPLEFT", ArenaFrame.textbox, "TOPLEFT", 4, -4)
+ ArenaFrameZoneDescription:SetPoint("BOTTOMRIGHT", ArenaFrame.textbox, "BOTTOMRIGHT", -4, 4)
+
+ SkinButton(ArenaFrameCancelButton)
+ SkinButton(ArenaFrameJoinButton)
+ SkinButton(ArenaFrameGroupJoinButton)
+end)
diff --git a/skins/blizzard/arena_registrar.lua b/skins/blizzard/arena_registrar.lua
new file mode 100644
index 00000000..0dc6f699
--- /dev/null
+++ b/skins/blizzard/arena_registrar.lua
@@ -0,0 +1,119 @@
+pfUI:RegisterSkin("Arena Registrar", "tbc", function ()
+ local rawborder, border = GetBorderSize()
+ local bpad = rawborder > 1 and border - GetPerfectPixel() or GetPerfectPixel()
+
+ do -- ArenaRegistrarFrame
+ StripTextures(ArenaRegistrarFrame)
+ StripTextures(ArenaRegistrarGreetingFrame)
+ CreateBackdrop(ArenaRegistrarFrame, nil, nil, .75)
+ CreateBackdropShadow(ArenaRegistrarFrame)
+
+ ArenaRegistrarFrame.backdrop:SetPoint("TOPLEFT", 14, -18)
+ ArenaRegistrarFrame.backdrop:SetPoint("BOTTOMRIGHT", -28, 66)
+ ArenaRegistrarFrame:SetHitRectInsets(14,28,18,66)
+ EnableMovable(ArenaRegistrarFrame)
+
+ SkinCloseButton(ArenaRegistrarFrameCloseButton, ArenaRegistrarFrame.backdrop, -6, -6)
+
+ ArenaRegistrarFrame:DisableDrawLayer("BACKGROUND")
+
+ ArenaRegistrarFrameNpcNameText:ClearAllPoints()
+ ArenaRegistrarFrameNpcNameText:SetPoint("TOP", ArenaRegistrarFrame.backdrop, "TOP", 0, -10)
+
+ SkinButton(ArenaRegistrarFrameGoodbyeButton)
+ SkinButton(ArenaRegistrarFrameCancelButton)
+ SkinButton(ArenaRegistrarFramePurchaseButton)
+
+ ArenaRegistrarCostLabel:SetFontObject("GameFontWhite")
+ ArenaRegistrarFrameEditBox:DisableDrawLayer("BACKGROUND")
+ CreateBackdrop(ArenaRegistrarFrameEditBox, nil, nil, 1)
+ ArenaRegistrarFrameEditBox:SetHeight(16)
+
+ local bg = ArenaRegistrarFrame:CreateTexture(nil, "LOW")
+ bg:SetTexCoord(.1,1,0,1)
+ bg:SetTexture("Interface\\Stationery\\StationeryTest1")
+ bg:SetPoint("TOPLEFT", 23, -81)
+ bg:SetPoint("BOTTOMRIGHT", -40, 100)
+ end
+
+ do -- PVPBannerFrame
+ StripTextures(PVPBannerFrame)
+ CreateBackdrop(PVPBannerFrame, nil, nil, .75)
+ CreateBackdropShadow(PVPBannerFrame)
+
+ PVPBannerFrame.backdrop:SetPoint("TOPLEFT", 10, -12)
+ PVPBannerFrame.backdrop:SetPoint("BOTTOMRIGHT", -32, 72)
+ PVPBannerFrame:SetHitRectInsets(10,32,12,72)
+ EnableMovable(PVPBannerFrame)
+
+ SkinCloseButton(PVPBannerFrameCloseButton, PVPBannerFrame.backdrop, -6, -6)
+
+ PVPBannerFrame:DisableDrawLayer("BACKGROUND")
+
+ PVPBannerFrameNameText:ClearAllPoints()
+ PVPBannerFrameNameText:SetPoint("TOP", ArenaRegistrarFrame.backdrop, "TOP", 0, -10)
+ PVPBannerFrameGreetingText:ClearAllPoints()
+ PVPBannerFrameGreetingText:SetPoint("TOP", PVPBannerFrameNameText, "TOP", 0, -10)
+
+ PVPBannerFrameCustomizationBorder:Hide()
+ PVPBannerFrameCustomization1:ClearAllPoints()
+ PVPBannerFrameCustomization1:SetPoint("TOPLEFT", PVPBannerFrameCustomizationBorder, "TOPLEFT", 48, -45)
+ for i = 1, 2 do
+ local frame = _G["PVPBannerFrameCustomization"..i]
+ StripTextures(frame)
+ CreateBackdrop(frame, nil, true)
+ frame:SetHeight(25)
+
+ local left = _G["PVPBannerFrameCustomization"..i.."LeftButton"]
+ StripTextures(left)
+ SkinArrowButton(left, "left", 25)
+ left:ClearAllPoints()
+ left:SetPoint("LEFT", 0, 0)
+
+ local right = _G["PVPBannerFrameCustomization"..i.."RightButton"]
+ StripTextures(right)
+ SkinArrowButton(right, "right", 25)
+ right:ClearAllPoints()
+ right:SetPoint("RIGHT", 0, 0)
+
+ local text = _G["PVPBannerFrameCustomization"..i.."Text"]
+ text:ClearAllPoints()
+ text:SetPoint("CENTER", 0, 0)
+ end
+
+ local width = PVPBannerFrameCustomization2:GetWidth()
+ for i = 1, 3 do
+ local btn = _G["PVPColorPickerButton"..i]
+ local prev = _G["PVPColorPickerButton"..(i-1)]
+
+ SkinButton(btn)
+ btn:SetWidth(width)
+ btn:ClearAllPoints()
+ if prev then
+ btn:SetPoint("TOPLEFT", prev, "BOTTOMLEFT", 0, -5)
+ else
+ btn:SetPoint("TOPLEFT", PVPBannerFrameCustomization2, "BOTTOMLEFT", 0, -5)
+ end
+ end
+
+ local PVPBannerFrameCancelButton
+ do -- fix Blizzard bug. A button with the same name is created twice.
+ for k,v in ipairs({PVPBannerFrameCustomizationFrame:GetChildren()}) do
+ if v:GetName() == "PVPBannerFrameCancelButton" then v:Hide() end -- This is the wrong and broken button.
+ end
+
+ for k,v in ipairs({PVPBannerFrame:GetChildren()}) do
+ if v:GetName() == "PVPBannerFrameCancelButton" then PVPBannerFrameCancelButton = v end
+ end
+ end
+
+ SkinButton(PVPBannerFrameSaveButton)
+
+ SkinButton(PVPBannerFrameCancelButton)
+ PVPBannerFrameCancelButton:ClearAllPoints()
+ PVPBannerFrameCancelButton:SetPoint("TOPRIGHT", PVPColorPickerButton3, "BOTTOMRIGHT", 0, -10)
+ SkinButton(PVPBannerFrameAcceptButton)
+ PVPBannerFrameAcceptButton:ClearAllPoints()
+ PVPBannerFrameAcceptButton:SetPoint("RIGHT", PVPBannerFrameCancelButton, "LEFT", -2*bpad, 0)
+ end
+end)
diff --git a/skins/blizzard/guildbank.lua b/skins/blizzard/guildbank.lua
new file mode 100644
index 00000000..c33d37b4
--- /dev/null
+++ b/skins/blizzard/guildbank.lua
@@ -0,0 +1,131 @@
+pfUI:RegisterSkin("Guild Bank", "tbc", function ()
+ local rawborder, border = GetBorderSize()
+ local bpad = rawborder > 1 and border - GetPerfectPixel() or GetPerfectPixel()
+
+ HookAddonOrVariable("Blizzard_GuildBankUI", function()
+ do -- GuildBankFrame
+ StripTextures(GuildBankFrame)
+ CreateBackdrop(GuildBankFrame, nil, nil, .75)
+ CreateBackdropShadow(GuildBankFrame)
+ GuildBankFrame.backdrop:SetPoint("TOPLEFT", 10, -30)
+ GuildBankFrame.backdrop:SetPoint("BOTTOMRIGHT", 0, 4)
+ GuildBankFrame:SetHitRectInsets(10,0,30,4)
+ EnableMovable(GuildBankFrame)
+
+ SkinCloseButton(GetNoNameObject(GuildBankFrame, "Button", nil, "UI-Panel-MinimizeButton-Up"), GuildBankFrame.backdrop, -6, -6)
+
+ GuildBankEmblemFrame:ClearAllPoints()
+ GuildBankEmblemFrame:SetPoint("BOTTOM", GuildBankFrame.backdrop, "TOP", -70, 0)
+
+ for i = 1, 4 do
+ local tab = _G["GuildBankFrameTab"..i]
+ local lastTab = _G["GuildBankFrameTab"..(i-1)]
+ tab:ClearAllPoints()
+ if lastTab then
+ tab:SetPoint("LEFT", lastTab, "RIGHT", border*2 + 1, 0)
+ else
+ tab:SetPoint("TOPLEFT", GuildBankFrame.backdrop, "BOTTOMLEFT", bpad, -(border + (border == 1 and 1 or 2)))
+ end
+ SkinTab(tab)
+ end
+ for i = 1, 6 do
+ local frame = _G["GuildBankTab"..i]
+ local button = _G["GuildBankTab"..i.."Button"]
+ local lastbutton = _G["GuildBankTab"..(i-1).."Button"]
+ local texture = _G["GuildBankTab"..i.."ButtonIconTexture"]
+
+ StripTextures(frame)
+ SkinButton(button, nil, nil, nil, texture)
+
+ button:ClearAllPoints()
+ if lastbutton then
+ button:SetPoint("TOP", lastbutton, "BOTTOM", 0, - (border + (border == 1 and 1 or 2) + bpad))
+ else
+ button:SetPoint("TOPLEFT", 6, -60)
+ end
+
+ function button.SetChecked(self, checked)
+ if checked then
+ self.locked = true
+ self:SetBackdropBorderColor(1,1,1)
+ else
+ self.locked = false
+ self:SetBackdropBorderColor(GetStringColor(pfUI_config.appearance.border.color))
+ end
+ end
+ end
+
+ for i = 1, NUM_GUILDBANK_COLUMNS do
+ local column = _G["GuildBankColumn"..i]
+ StripTextures(column)
+ for j = 1, NUM_SLOTS_PER_GUILDBANK_GROUP do
+ local slot = _G["GuildBankColumn"..i.."Button"..j]
+ SkinButton(slot, nil, nil, nil, _G[slot:GetName().."IconTexture"], true)
+ end
+ end
+
+ hooksecurefunc("GuildBankFrame_Update", function()
+ if GuildBankFrame.mode ~= "bank" then return end
+
+ for i = 1, MAX_GUILDBANK_SLOTS_PER_TAB do
+ local index = math.fmod(i, NUM_SLOTS_PER_GUILDBANK_GROUP)
+ if index == 0 then index = NUM_SLOTS_PER_GUILDBANK_GROUP end
+ local column = ceil((i-.5)/NUM_SLOTS_PER_GUILDBANK_GROUP)
+ local slot = _G["GuildBankColumn"..column.."Button"..index]
+ local tab = GetCurrentGuildBankTab()
+ local link = GetGuildBankItemLink(tab, i)
+ if link then
+ local r,g,b = GetItemQualityColor(select(3, GetItemInfo(link)))
+ slot:SetBackdropBorderColor(r,g,b,1)
+ else
+ slot:SetBackdropBorderColor(GetStringColor(pfUI_config.appearance.border.color))
+ end
+ end
+ end)
+
+ SkinButton(GuildBankFrameDepositButton)
+ SkinButton(GuildBankFrameWithdrawButton)
+ GuildBankFrameWithdrawButton:ClearAllPoints()
+ GuildBankFrameWithdrawButton:SetPoint("RIGHT", GuildBankFrameDepositButton, "LEFT", -2*bpad, 0)
+
+ SkinButton(GuildBankInfoSaveButton)
+ GuildBankInfoScrollFrameScrollBar:Hide()
+ end
+
+ do -- GuildBankPopupFrame
+ StripTextures(GuildBankPopupFrame)
+ CreateBackdrop(GuildBankPopupFrame, nil, nil, .75)
+ CreateBackdropShadow(GuildBankPopupFrame)
+ GuildBankPopupFrame.backdrop:SetPoint("TOPLEFT", 0, -6)
+ GuildBankPopupFrame.backdrop:SetPoint("BOTTOMRIGHT", -26, 26)
+ GuildBankPopupFrame:SetHitRectInsets(0,26,6,26)
+
+ GuildBankPopupFrame.backdrop:SetPoint("TOPLEFT", GuildBankFrame.backdrop, "TOPRIGHT", 2*border, 0)
+
+ GuildBankPopupEditBox:DisableDrawLayer("BACKGROUND")
+ CreateBackdrop(GuildBankPopupEditBox)
+
+ StripTextures(GuildBankPopupScrollFrame)
+ CreateBackdrop(GuildBankPopupScrollFrame)
+ SkinScrollbar(GuildBankPopupScrollFrameScrollBar)
+ GuildBankPopupScrollFrame:ClearAllPoints()
+ GuildBankPopupScrollFrame:SetPoint("TOPLEFT", GuildBankPopupEditBox, "BOTTOMLEFT", -11, -14)
+ GuildBankPopupScrollFrame:SetWidth(182)
+ GuildBankPopupScrollFrame:SetHeight(178)
+
+ for i = 1, 16 do
+ local slot = _G["GuildBankPopupButton"..i]
+ StripTextures(slot)
+ SkinButton(slot, nil, nil, nil, _G["GuildBankPopupButton"..i.."Icon"], true)
+ end
+
+ GuildBankPopupButton1:ClearAllPoints()
+ GuildBankPopupButton1:SetPoint("TOPLEFT", GuildBankPopupScrollFrame, "TOPLEFT", 4, -4)
+
+ SkinButton(GuildBankPopupCancelButton)
+ SkinButton(GuildBankPopupOkayButton)
+ GuildBankPopupOkayButton:ClearAllPoints()
+ GuildBankPopupOkayButton:SetPoint("RIGHT", GuildBankPopupCancelButton, "LEFT", -2*bpad, 0)
+ end
+ end)
+end)
diff --git a/skins/blizzard/lfg.lua b/skins/blizzard/lfg.lua
new file mode 100644
index 00000000..c784fb85
--- /dev/null
+++ b/skins/blizzard/lfg.lua
@@ -0,0 +1,75 @@
+pfUI:RegisterSkin("Looking for group", "tbc", function ()
+ local rawborder, border = GetBorderSize()
+ local bpad = rawborder > 1 and border - GetPerfectPixel() or GetPerfectPixel()
+
+ StripTextures(LFGParentFrame)
+ CreateBackdrop(LFGParentFrame, nil, nil, .75)
+ CreateBackdropShadow(LFGParentFrame)
+
+ LFGParentFrame.backdrop:SetPoint("TOPLEFT", 14, -10)
+ LFGParentFrame.backdrop:SetPoint("BOTTOMRIGHT", -26, 72)
+ LFGParentFrame:SetHitRectInsets(14,26,10,72)
+ EnableMovable(LFGParentFrame)
+
+ SkinCloseButton(GetNoNameObject(LFGParentFrame, 'Button', nil, "UI-Panel-MinimizeButton-Up"), LFGParentFrame.backdrop, -6, -6)
+
+ LFGParentFrame:DisableDrawLayer("BACKGROUND")
+
+ LFGParentFrameTitle:ClearAllPoints()
+ LFGParentFrameTitle:SetPoint("TOP", LFGParentFrame.backdrop, "TOP", 0, -10)
+
+ SkinTab(LFGParentFrameTab1)
+ LFGParentFrameTab1:ClearAllPoints()
+ LFGParentFrameTab1:SetPoint("TOPLEFT", LFGParentFrame.backdrop, "BOTTOMLEFT", bpad, -(border + (border == 1 and 1 or 2)))
+ SkinTab(LFGParentFrameTab2)
+ LFGParentFrameTab2:ClearAllPoints()
+ LFGParentFrameTab2:SetPoint("LEFT", LFGParentFrameTab1, "RIGHT", border*2 + 1, 0)
+ LFGParentFrameBackground:Hide()
+
+ LFGFrameClearAllButton:ClearAllPoints()
+ LFGFrameClearAllButton:SetPoint("RIGHT", LFGFrameDoneButton, "LEFT", -2*bpad, 0)
+
+ StripTextures(AutoJoinBackground)
+ SkinCheckbox(AutoJoinCheckButton)
+
+ StripTextures(AddMemberBackground)
+ SkinCheckbox(AutoAddMembersCheckButton)
+
+ CreateBackdrop(LFGComment)
+
+ -- skin buttons
+ local buttons = {
+ "LFGWizardFrameLFGButton",
+ "LFGWizardFrameLFMButton",
+ "LFGFrameDoneButton",
+ "LFGFrameClearAllButton",
+ "LFMFrameGroupInviteButton",
+ "LFMFrameSendMessageButton",
+ "LFMFrameSearchButton",
+ "LFMFrameColumnHeader1",
+ "LFMFrameColumnHeader2",
+ "LFMFrameColumnHeader3",
+ "LFMFrameColumnHeader4",
+ }
+
+ for _, name in pairs(buttons) do
+ SkinButton(_G[name])
+ end
+
+ -- skin dropdowns
+ local dropdowns = {
+ "LFGFrameTypeDropDown1",
+ "LFGFrameNameDropDown1",
+ "LFGFrameTypeDropDown2",
+ "LFGFrameNameDropDown2",
+ "LFGFrameTypeDropDown3",
+ "LFGFrameNameDropDown3",
+ }
+
+ for _, name in pairs(dropdowns) do
+ SkinDropDown(_G[name])
+ end
+
+ SkinDropDown(LFMFrameTypeDropDown, nil, nil, nil, true)
+ SkinDropDown(LFMFrameNameDropDown, nil, nil, nil, true)
+end)
diff --git a/skins/blizzard/options-interface.lua b/skins/blizzard/options-interface.lua
new file mode 100644
index 00000000..3ecb0945
--- /dev/null
+++ b/skins/blizzard/options-interface.lua
@@ -0,0 +1,175 @@
+pfUI:RegisterSkin("Options - Interface", "tbc", function ()
+ local rawborder, border = GetBorderSize()
+ local bpad = rawborder > 1 and border - GetPerfectPixel() or GetPerfectPixel()
+
+ StripTextures(InterfaceOptionsFrame)
+ CreateBackdrop(InterfaceOptionsFrame, nil, nil, .75)
+ CreateBackdropShadow(InterfaceOptionsFrame)
+
+ EnableMovable(InterfaceOptionsFrame)
+
+ InterfaceOptionsFrameHeaderText:ClearAllPoints()
+ InterfaceOptionsFrameHeaderText:SetPoint("TOP", InterfaceOptionsFrame.backdrop, "TOP", 0, -10)
+
+ StripTextures(InterfaceOptionsFrameCategories)
+ CreateBackdrop(InterfaceOptionsFrameCategories, nil, true, .75)
+ StripTextures(InterfaceOptionsFrameAddOns)
+ CreateBackdrop(InterfaceOptionsFrameAddOns, nil, true, .75)
+ CreateBackdrop(InterfaceOptionsFramePanelContainer, nil, true, .75)
+
+ SkinTab(InterfaceOptionsFrameTab1)
+ InterfaceOptionsFrameTab1:ClearAllPoints()
+ InterfaceOptionsFrameTab1:SetPoint("BOTTOMLEFT", InterfaceOptionsFrameCategories, "TOPLEFT", bpad, border + (border == 1 and 1 or 2))
+ SkinTab(InterfaceOptionsFrameTab2)
+ InterfaceOptionsFrameTab2:ClearAllPoints()
+ InterfaceOptionsFrameTab2:SetPoint("LEFT", InterfaceOptionsFrameTab1, "RIGHT", border*2 + 1, 0)
+
+ SkinButton(InterfaceOptionsFrameDefaults)
+ InterfaceOptionsFrameDefaults:ClearAllPoints()
+ InterfaceOptionsFrameDefaults:SetPoint("TOPLEFT", InterfaceOptionsFrameCategories, "BOTTOMLEFT", 0, -10)
+ SkinButton(InterfaceOptionsFrameCancel)
+ InterfaceOptionsFrameCancel:ClearAllPoints()
+ InterfaceOptionsFrameCancel:SetPoint("TOPRIGHT", InterfaceOptionsFramePanelContainer, "BOTTOMRIGHT", 0, -10)
+ SkinButton(InterfaceOptionsFrameOkay)
+ InterfaceOptionsFrameOkay:ClearAllPoints()
+ InterfaceOptionsFrameOkay:SetPoint("RIGHT", InterfaceOptionsFrameCancel, "LEFT", -2*bpad, 0)
+
+ -- universal code for handling any frames!
+ local function SkinAllObjects(frame)
+ for _,obj in ipairs({frame:GetChildren()}) do
+ local obj_type = obj:GetObjectType()
+ if obj_type == "CheckButton" then
+ local size = obj:GetHeight()
+ if size > 26 then size = 26 end
+ SkinCheckbox(obj, size)
+ elseif obj_type == "Button" then
+ SkinButton(obj)
+ elseif obj_type == "Slider" then
+ SkinSlider(obj)
+ elseif obj_type == "Frame" then
+ local name = obj.GetName and obj:GetName()
+ if name and _G[name.."Button"] then
+ SkinDropDown(obj)
+ else
+ SkinAllObjects(obj)
+ end
+ end
+ end
+ end
+
+ local blizzardCategories = {
+ InterfaceOptionsControlsPanel, InterfaceOptionsCombatPanel, InterfaceOptionsDisplayPanel,
+ InterfaceOptionsQuestsPanel, InterfaceOptionsSocialPanel, InterfaceOptionsActionBarsPanel,
+ InterfaceOptionsNamesPanel, InterfaceOptionsCombatTextPanel, InterfaceOptionsStatusTextPanel,
+ InterfaceOptionsPartyRaidPanel, InterfaceOptionsCameraPanel, InterfaceOptionsMousePanel,
+ InterfaceOptionsHelpPanel, InterfaceOptionsLanguagesPanel
+ }
+ for _,frame in ipairs(blizzardCategories) do
+ SkinAllObjects(frame)
+ end
+
+ -- skin the option panel of any addon
+ for _,frame in pairs(INTERFACEOPTIONS_ADDONCATEGORIES) do
+ SkinAllObjects(frame)
+ end
+end)
+
+pfUI:RegisterSkin("Options - Interface", "vanilla", function ()
+ local rawborder, border = GetBorderSize()
+ local bpad = rawborder > 1 and border - GetPerfectPixel() or GetPerfectPixel()
+
+ UIOptionsFrame:SetParent(UIParent)
+ UIOptionsFrame:SetWidth(1024)
+ UIOptionsFrame:SetHeight(700)
+
+ StripTextures(UIOptionsFrame)
+ CreateBackdrop(UIOptionsFrame, nil, nil, .75)
+ CreateBackdropShadow(UIOptionsFrame)
+
+ EnableMovable(UIOptionsFrame)
+
+ HookScript(UIOptionsFrame, "OnShow", function()
+ this:ClearAllPoints()
+ this:SetPoint("CENTER", 0, 0)
+ end)
+
+ UIOptionsFrame.backdrop:SetPoint("BOTTOMRIGHT", 0, 50)
+ UIOptionsFrame:SetHitRectInsets(0,0,0,50)
+
+
+ -- increase button layer
+ UIOptionsFrameTab1:SetFrameLevel(8)
+ UIOptionsFrameTab2:SetFrameLevel(8)
+ UIOptionsFrameDefaults:SetFrameLevel(8)
+ UIOptionsFrameCancel:SetFrameLevel(8)
+ UIOptionsFrameOkay:SetFrameLevel(8)
+
+ local close = GetNoNameObject(UIOptionsFrame, "Button", nil, "UI-Panel-MinimizeButton-Up")
+ if close then
+ close:SetFrameLevel(8)
+ SkinCloseButton(close, UIOptionsFrame.backdrop, -6, -6)
+ end
+
+ if UIOptionsFrameTitle then
+ UIOptionsFrameTitle:ClearAllPoints()
+ UIOptionsFrameTitle:SetPoint("TOP", UIOptionsFrame.backdrop, "TOP", 0, -10)
+ end
+
+ SkinTab(UIOptionsFrameTab1)
+ UIOptionsFrameTab1:ClearAllPoints()
+ UIOptionsFrameTab1:SetPoint("TOPLEFT", UIOptionsFrame.backdrop, "TOPLEFT", 20, -20)
+ UIOptionsFrameTab1:SetScript("OnClick", function()
+ PanelTemplates_Tab_OnClick(UIOptionsFrame)
+ BasicOptions:Show()
+ AdvancedOptions:Hide()
+ PlaySound("igCharacterInfoTab")
+ end)
+ SkinTab(UIOptionsFrameTab2)
+ UIOptionsFrameTab2:ClearAllPoints()
+ UIOptionsFrameTab2:SetPoint("LEFT", UIOptionsFrameTab1, "RIGHT", border*2 + 1, 0)
+ UIOptionsFrameTab2:SetScript("OnClick", function()
+ PanelTemplates_Tab_OnClick(UIOptionsFrame)
+ BasicOptions:Hide()
+ AdvancedOptions:Show()
+ PlaySound("igCharacterInfoTab")
+ end)
+
+ UIOptionsFrameCheckButton1:ClearAllPoints() -- Invert Mouse button
+ UIOptionsFrameCheckButton1:SetPoint("TOPLEFT", UIOptionsFrameSlider1, "TOPRIGHT", 38, 14)
+
+ for i=1, 69 do
+ local buton = _G["UIOptionsFrameCheckButton"..i]
+ if buton then
+ SkinCheckbox(buton)
+ end
+ end
+
+ for i=1, 4 do
+ SkinSlider(_G["UIOptionsFrameSlider"..i])
+ end
+
+ CreateBackdrop(BasicOptionsGeneral, nil, true, .75)
+ CreateBackdrop(BasicOptionsDisplay, nil, true, .75)
+ CreateBackdrop(BasicOptionsCamera, nil, true, .75)
+ CreateBackdrop(BasicOptionsHelp, nil, true, .75)
+ CreateBackdrop(AdvancedOptionsActionBars, nil, true, .75)
+ CreateBackdrop(AdvancedOptionsChat, nil, true, .75)
+ CreateBackdrop(AdvancedOptionsRaid, nil, true, .75)
+ CreateBackdrop(AdvancedOptionsCombatText, nil, true, .75)
+
+ SkinDropDown(UIOptionsFrameClickCameraDropDown)
+ SkinDropDown(UIOptionsFrameCameraDropDown)
+ SkinDropDown(UIOptionsFrameTargetofTargetDropDown)
+ SkinDropDown(UIOptionsFrameCombatTextDropDown)
+
+ SkinButton(UIOptionsFrameResetTutorials)
+ SkinButton(UIOptionsFrameDefaults)
+ UIOptionsFrameDefaults:ClearAllPoints()
+ UIOptionsFrameDefaults:SetPoint("BOTTOMLEFT", UIOptionsFrame.backdrop, "BOTTOMLEFT", 14, 14)
+ SkinButton(UIOptionsFrameCancel)
+ UIOptionsFrameCancel:ClearAllPoints()
+ UIOptionsFrameCancel:SetPoint("BOTTOMRIGHT", UIOptionsFrame.backdrop, "BOTTOMRIGHT", -14, 14)
+ SkinButton(UIOptionsFrameOkay)
+ UIOptionsFrameOkay:ClearAllPoints()
+ UIOptionsFrameOkay:SetPoint("RIGHT", UIOptionsFrameCancel, "LEFT", -2*bpad, 0)
+end)
diff --git a/skins/blizzard/socket.lua b/skins/blizzard/socket.lua
new file mode 100644
index 00000000..f2c2aeec
--- /dev/null
+++ b/skins/blizzard/socket.lua
@@ -0,0 +1,39 @@
+pfUI:RegisterSkin("Item Socketing", "tbc", function ()
+ local rawborder, border = GetBorderSize()
+ local bpad = rawborder > 1 and border - GetPerfectPixel() or GetPerfectPixel()
+
+ HookAddonOrVariable("Blizzard_ItemSocketingUI", function()
+ StripTextures(ItemSocketingFrame)
+ CreateBackdrop(ItemSocketingFrame, nil, nil, .75)
+ CreateBackdropShadow(ItemSocketingFrame)
+ ItemSocketingFrame.backdrop:SetPoint("TOPLEFT", 8, -14)
+ ItemSocketingFrame.backdrop:SetPoint("BOTTOMRIGHT", -4, 28)
+ ItemSocketingFrame:SetHitRectInsets(8,4,14,28)
+ EnableMovable(ItemSocketingFrame)
+
+ SkinCloseButton(ItemSocketingCloseButton, ItemSocketingFrame.backdrop, -6, -6)
+
+ ItemSocketingFrame:DisableDrawLayer("BACKGROUND")
+
+ StripTextures(ItemSocketingScrollFrame)
+ CreateBackdrop(ItemSocketingScrollFrame)
+ ItemSocketingScrollFrame:ClearAllPoints()
+ ItemSocketingScrollFrame:SetPoint("TOPLEFT", 32, -70)
+ ItemSocketingScrollFrame.backdrop:SetPoint("TOPLEFT", 0, 10)
+ ItemSocketingScrollFrame.backdrop:SetPoint("BOTTOMRIGHT", 0, -10)
+ SkinScrollbar(ItemSocketingScrollFrameScrollBar)
+ ItemSocketingScrollFrameScrollBar:ClearAllPoints()
+ ItemSocketingScrollFrameScrollBar:SetPoint("TOPLEFT", ItemSocketingScrollFrame.backdrop, "TOPRIGHT", 6, -16)
+ ItemSocketingScrollFrameScrollBar:SetPoint("BOTTOMLEFT", ItemSocketingScrollFrame.backdrop, "BOTTOMRIGHT", 6, 16)
+ SkinButton(ItemSocketingSocketButton)
+ for i = 1, MAX_NUM_SOCKETS do
+ local btn = _G["ItemSocketingSocket"..i]
+ StripTextures(btn)
+ SkinButton(btn, nil, nil, nil, _G["ItemSocketingSocket"..i.."IconTexture"], true)
+ end
+ local orig = ItemSocketingSocket1.SetPoint
+ ItemSocketingSocket1.SetPoint = function(self,a,b,c,x,y)
+ orig(self,a,b,c,x-10,y+15)
+ end
+ end)
+end)
diff --git a/skins/blizzard/time_manager.lua b/skins/blizzard/time_manager.lua
new file mode 100644
index 00000000..dfa4eb88
--- /dev/null
+++ b/skins/blizzard/time_manager.lua
@@ -0,0 +1,122 @@
+pfUI:RegisterSkin("Time Manager", "tbc", function ()
+ local rawborder, border = GetBorderSize()
+ local bpad = rawborder > 1 and border - GetPerfectPixel() or GetPerfectPixel()
+
+ HookAddonOrVariable("Blizzard_TimeManager", function()
+ do -- TimeManagerFrame
+ StripTextures(TimeManagerFrame)
+ CreateBackdrop(TimeManagerFrame, nil, nil, .75)
+ CreateBackdropShadow(TimeManagerFrame)
+ TimeManagerClockButton:Hide()
+ TimeManagerClockButton.Show = function() return end
+
+ TimeManagerFrame.backdrop:SetPoint("TOPLEFT", 10, -10)
+ TimeManagerFrame.backdrop:SetPoint("BOTTOMRIGHT", -48, 1)
+ TimeManagerFrame:SetHitRectInsets(10,48,10,1)
+ EnableMovable(TimeManagerFrame)
+
+ SkinCloseButton(TimeManagerCloseButton, TimeManagerFrame.backdrop, -6, -6)
+
+ local header = GetNoNameObject(TimeManagerFrame, 'FontString', 'BORDER', TIMEMANAGER_TITLE)
+ header:ClearAllPoints()
+ header:SetPoint("TOP", TimeManagerFrame.backdrop, "TOP", 0, -10)
+
+ TimeManagerFrameTicker:ClearAllPoints()
+ TimeManagerFrameTicker:SetPoint("TOPLEFT", TimeManagerFrame.backdrop, "TOPLEFT", 30, -37)
+
+ StripTextures(TimeManagerStopwatchFrame)
+ local texture = TimeManagerStopwatchCheck:GetNormalTexture():GetTexture()
+ SkinButton(TimeManagerStopwatchCheck)
+ TimeManagerStopwatchCheck:SetNormalTexture(texture)
+ HandleIcon(TimeManagerStopwatchCheck, TimeManagerStopwatchCheck:GetNormalTexture())
+
+ local frames = {
+ [TimeManagerAlarmHourDropDown] = '0',
+ [TimeManagerAlarmMinuteDropDown] = '1',
+ [TimeManagerAlarmAMPMDropDown] = '-4'
+ }
+ for frame,Xoffset in pairs(frames) do
+ SkinDropDown(frame, nil, nil, nil, true)
+ local text = _G[frame:GetName().."Text"]
+ local left = _G[frame:GetName().."Left"]
+ text:ClearAllPoints()
+ text:SetPoint("LEFT", left, "LEFT", Xoffset, 1)
+ end
+ TimeManagerAlarmHourDropDown:ClearAllPoints()
+ TimeManagerAlarmHourDropDown:SetPoint("TOPLEFT", TimeManagerAlarmTimeLabel, "BOTTOMLEFT", -4, -4)
+
+ TimeManagerAlarmMessageFrame:ClearAllPoints()
+ TimeManagerAlarmMessageFrame:SetPoint("TOPLEFT", TimeManagerAlarmTimeFrame, "BOTTOMLEFT", 0, 0)
+
+ TimeManagerAlarmMessageEditBox:DisableDrawLayer("BACKGROUND")
+ CreateBackdrop(TimeManagerAlarmMessageEditBox)
+ TimeManagerAlarmMessageEditBox:ClearAllPoints()
+ TimeManagerAlarmMessageEditBox:SetWidth(142)
+ TimeManagerAlarmMessageEditBox:SetPoint("TOPLEFT", TimeManagerAlarmMessageLabel, "BOTTOMLEFT", 13, -5)
+
+ SkinButton(TimeManagerAlarmEnabledButton)
+ TimeManagerAlarmEnabledButton.SetNormalTexture = function() end
+ TimeManagerAlarmEnabledButton.SetPushedTexture = function() end
+ hooksecurefunc("TimeManagerAlarmEnabledButton_Update", function()
+ if TimeManagerAlarmEnabledButton:GetText() == TIMEMANAGER_ALARM_ENABLED then
+ TimeManagerAlarmEnabledButton:LockHighlight()
+ else
+ TimeManagerAlarmEnabledButton:UnlockHighlight()
+ end
+ end)
+ TimeManagerAlarmEnabledButton:ClearAllPoints()
+ TimeManagerAlarmEnabledButton:SetWidth(146)
+ TimeManagerAlarmEnabledButton:SetPoint("TOP", TimeManagerAlarmMessageEditBox, "BOTTOM", 0, -8)
+
+
+ SkinCheckbox(TimeManagerMilitaryTimeCheck)
+ SkinCheckbox(TimeManagerLocalTimeCheck)
+ end
+
+ do -- StopwatchFrame
+ StripTextures(StopwatchFrame)
+
+ StripTextures(StopwatchTabFrame)
+ CreateBackdrop(StopwatchTabFrame, nil, true)
+ StopwatchTabFrame:SetWidth(122)
+ StopwatchTabFrame:SetHeight(18)
+ StopwatchTitle:ClearAllPoints()
+ StopwatchTitle:SetPoint("CENTER", 0, 0)
+ SkinCloseButton(StopwatchCloseButton, StopwatchTabFrame, 0, 0)
+
+ local orig = StopwatchResetButton.SetNormalTexture
+ StopwatchResetButton.SetNormalTexture = function(self, tex)
+ orig(self, tex)
+ local texture = self:GetNormalTexture()
+ texture:SetDesaturated(1)
+ texture:SetTexCoord(.25, .75, .28, .78)
+ end
+ SkinButton(StopwatchResetButton, nil, nil, nil, StopwatchResetButton:GetNormalTexture())
+ StopwatchResetButton:SetNormalTexture("Interface\\TimeManager\\ResetButton") -- initiate update texture
+ StopwatchResetButton:ClearAllPoints()
+ StopwatchResetButton:SetWidth(20)
+ StopwatchResetButton:SetHeight(20)
+ StopwatchResetButton:SetPoint("TOPRIGHT", StopwatchTabFrame, "BOTTOMRIGHT", 0, -2*border + 1)
+
+ local orig = StopwatchPlayPauseButton.SetNormalTexture
+ StopwatchPlayPauseButton.SetNormalTexture = function(self, tex)
+ orig(self, tex)
+ local texture = self:GetNormalTexture()
+ texture:SetDesaturated(1)
+ texture:SetTexCoord(.25, .75, .28, .78)
+ end
+ SkinButton(StopwatchPlayPauseButton, nil, nil, nil, StopwatchPlayPauseButton:GetNormalTexture())
+ StopwatchPlayPauseButton:SetNormalTexture("Interface\\Buttons\\UI-SpellbookIcon-NextPage-Up") -- initiate update texture
+ StopwatchPlayPauseButton:ClearAllPoints()
+ StopwatchPlayPauseButton:SetWidth(20)
+ StopwatchPlayPauseButton:SetHeight(20)
+ StopwatchPlayPauseButton:SetPoint("RIGHT", StopwatchResetButton, "LEFT", -2*bpad, 0)
+
+ CreateBackdrop(StopwatchTicker)
+ StopwatchTicker:ClearAllPoints()
+ StopwatchTicker:SetWidth(70)
+ StopwatchTicker:SetHeight(16)
+ StopwatchTicker:SetPoint("RIGHT", StopwatchPlayPauseButton, "LEFT", -2*border + 1, 0)
+ end
+ end)
+end)
diff --git a/skins/blizzard/tracking.lua b/skins/blizzard/tracking.lua
new file mode 100644
index 00000000..3e6644d4
--- /dev/null
+++ b/skins/blizzard/tracking.lua
@@ -0,0 +1,11 @@
+pfUI:RegisterSkin("tracking", "tbc", function ()
+ MINIMAP_TRACKING_FRAME:DisableDrawLayer("ARTWORK") -- hide border
+ SkinButton(MINIMAP_TRACKING_FRAME, nil, nil, nil, MiniMapTrackingIcon, true)
+ MINIMAP_TRACKING_FRAME:SetHeight(tonumber(C.appearance.minimap.tracking_size) + 10)
+ MINIMAP_TRACKING_FRAME:SetWidth(tonumber(C.appearance.minimap.tracking_size) + 10)
+ MINIMAP_TRACKING_FRAME:ClearAllPoints()
+ MINIMAP_TRACKING_FRAME:SetPoint("TOPLEFT", pfUI.minimap, "TOPLEFT", -10, -10)
+ MINIMAP_TRACKING_FRAME:SetFrameStrata("LOW")
+ MINIMAP_TRACKING_FRAME:SetParent(UIParent)
+ UpdateMovable(MINIMAP_TRACKING_FRAME)
+end)
From 250d7ee37479c6b0742d2defd78cf95950441b05 Mon Sep 17 00:00:00 2001
From: Meow <30401521+me0wg4ming@users.noreply.github.com>
Date: Sat, 3 Jan 2026 19:49:33 +0100
Subject: [PATCH 16/40] Delete .github directory
---
.github/FUNDING.yml | 2 --
.github/workflows/close-issues.yml | 24 ------------------------
2 files changed, 26 deletions(-)
delete mode 100644 .github/FUNDING.yml
delete mode 100644 .github/workflows/close-issues.yml
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
deleted file mode 100644
index 4cb83f66..00000000
--- a/.github/FUNDING.yml
+++ /dev/null
@@ -1,2 +0,0 @@
-github: [shagu]
-ko_fi: shagu
diff --git a/.github/workflows/close-issues.yml b/.github/workflows/close-issues.yml
deleted file mode 100644
index da0f0103..00000000
--- a/.github/workflows/close-issues.yml
+++ /dev/null
@@ -1,24 +0,0 @@
-name: Close inactive issues
-on:
- workflow_dispatch:
- schedule:
- - cron: "30 1 * * *"
-
-jobs:
- close-issues:
- runs-on: ubuntu-latest
- permissions:
- issues: write
- pull-requests: write
- steps:
- - uses: actions/stale@v5
- with:
- operations-per-run: 100
- days-before-issue-stale: 30
- days-before-issue-close: 14
- stale-issue-label: "stale"
- stale-issue-message: "This issue is stale because it has been open for 30 days with no activity."
- close-issue-message: "This issue was closed because it has been inactive for 14 days since being marked as stale."
- days-before-pr-stale: -1
- days-before-pr-close: -1
- repo-token: ${{ secrets.GITHUB_TOKEN }}
From 01f9947e3f28c765e315e555723f9426062a6551 Mon Sep 17 00:00:00 2001
From: Meow <30401521+me0wg4ming@users.noreply.github.com>
Date: Mon, 5 Jan 2026 07:25:05 +0100
Subject: [PATCH 17/40] Revert "Delete .github directory"
This reverts commit 250d7ee37479c6b0742d2defd78cf95950441b05.
---
.github/FUNDING.yml | 2 ++
.github/workflows/close-issues.yml | 24 ++++++++++++++++++++++++
2 files changed, 26 insertions(+)
create mode 100644 .github/FUNDING.yml
create mode 100644 .github/workflows/close-issues.yml
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
new file mode 100644
index 00000000..4cb83f66
--- /dev/null
+++ b/.github/FUNDING.yml
@@ -0,0 +1,2 @@
+github: [shagu]
+ko_fi: shagu
diff --git a/.github/workflows/close-issues.yml b/.github/workflows/close-issues.yml
new file mode 100644
index 00000000..da0f0103
--- /dev/null
+++ b/.github/workflows/close-issues.yml
@@ -0,0 +1,24 @@
+name: Close inactive issues
+on:
+ workflow_dispatch:
+ schedule:
+ - cron: "30 1 * * *"
+
+jobs:
+ close-issues:
+ runs-on: ubuntu-latest
+ permissions:
+ issues: write
+ pull-requests: write
+ steps:
+ - uses: actions/stale@v5
+ with:
+ operations-per-run: 100
+ days-before-issue-stale: 30
+ days-before-issue-close: 14
+ stale-issue-label: "stale"
+ stale-issue-message: "This issue is stale because it has been open for 30 days with no activity."
+ close-issue-message: "This issue was closed because it has been inactive for 14 days since being marked as stale."
+ days-before-pr-stale: -1
+ days-before-pr-close: -1
+ repo-token: ${{ secrets.GITHUB_TOKEN }}
From c259e9b59df4ac169d6523b1d4acb7511f3db362 Mon Sep 17 00:00:00 2001
From: Meow <30401521+me0wg4ming@users.noreply.github.com>
Date: Mon, 5 Jan 2026 09:06:08 +0100
Subject: [PATCH 18/40] revert of deletion and merged hotfixes
Please read the Readme for more details.
---
README.md | 412 +++++++++++++++++--------
api/api.lua | 12 +-
api/config.lua | 16 +-
api/unitframes.lua | 12 +
init/compat.xml | 1 +
init/modules.xml | 3 +
init/skins.xml | 10 +
modules/addonbuttons.lua | 2 +-
modules/addons.lua | 2 +-
modules/afkcam.lua | 2 +-
modules/autovendor.lua | 2 +-
modules/bags.lua | 6 +-
modules/bubbles.lua | 2 +-
modules/buff.lua | 2 +-
modules/buffwatch.lua | 2 +-
modules/chat.lua | 5 +-
modules/chatcopy.lua | 2 +-
modules/combopoints.lua | 2 +-
modules/cooldown.lua | 15 +-
modules/easteregg.lua | 2 +-
modules/energytick.lua | 24 +-
modules/farmmode.lua | 2 +-
modules/feigndeath.lua | 2 +-
modules/firstrun.lua | 2 +-
modules/focus.lua | 2 +-
modules/group.lua | 2 +-
modules/gryphons.lua | 2 +-
modules/gui.lua | 50 +--
modules/hoverbind.lua | 2 +-
modules/infight.lua | 2 +-
modules/loot.lua | 2 +-
modules/map.lua | 2 +-
modules/mapreveal.lua | 2 +-
modules/minimap.lua | 4 +-
modules/mirrortimers.lua | 2 +-
modules/panel.lua | 2 +-
modules/pet.lua | 2 +-
modules/pettarget.lua | 2 +-
modules/pixelperfect.lua | 2 +-
modules/player.lua | 2 +-
modules/questitem.lua | 6 +-
modules/raid.lua | 2 +-
modules/roll.lua | 2 +-
modules/screenshot.lua | 2 +-
modules/sellvalue.lua | 2 +-
modules/share.lua | 2 +-
modules/socialmod.lua | 2 +-
modules/superwow.lua | 72 +----
modules/target.lua | 2 +-
modules/targettarget.lua | 2 +-
modules/targettargettarget.lua | 2 +-
modules/thirdparty.lua | 14 +-
modules/totems.lua | 5 +-
modules/uf_tukui.lua | 2 +-
modules/unlock.lua | 2 +-
modules/unusable.lua | 2 +-
modules/updatenotify.lua | 2 +-
modules/xpbar.lua | 2 +-
pfUI-tbc.toc | 17 +
pfUI.lua | 36 ++-
pfUI.toc | 2 +-
skins/blizzard/auction.lua | 15 +-
skins/blizzard/battlefield.lua | 2 +-
skins/blizzard/battlefield_minimap.lua | 2 +-
skins/blizzard/character.lua | 25 +-
skins/blizzard/dressup.lua | 2 +-
skins/blizzard/friends.lua | 60 +++-
skins/blizzard/game_menu.lua | 8 +-
skins/blizzard/gossipquest.lua | 2 +-
skins/blizzard/guild_registrar.lua | 2 +-
skins/blizzard/help.lua | 14 +-
skins/blizzard/inspect.lua | 105 +++++++
skins/blizzard/itemtext.lua | 2 +-
skins/blizzard/keybindings.lua | 2 +-
skins/blizzard/macro.lua | 2 +-
skins/blizzard/mail.lua | 48 ++-
skins/blizzard/merchant.lua | 18 +-
skins/blizzard/miscellaneous.lua | 12 +-
skins/blizzard/options-sound.lua | 44 ++-
skins/blizzard/options-video.lua | 48 ++-
skins/blizzard/popup_dialogs.lua | 9 +-
skins/blizzard/professions.lua | 34 +-
skins/blizzard/questlog.lua | 21 +-
skins/blizzard/readycheck.lua | 10 +-
skins/blizzard/spellbook.lua | 2 +-
skins/blizzard/stable.lua | 2 +-
skins/blizzard/tabard.lua | 2 +-
skins/blizzard/talents.lua | 12 +-
skins/blizzard/taxi.lua | 2 +-
skins/blizzard/tooltips.lua | 2 +-
skins/blizzard/trade.lua | 2 +-
skins/blizzard/trainer.lua | 2 +-
92 files changed, 941 insertions(+), 376 deletions(-)
create mode 100644 pfUI-tbc.toc
diff --git a/README.md b/README.md
index f65eb3d7..eedf2846 100644
--- a/README.md
+++ b/README.md
@@ -1,146 +1,312 @@
-pfUI performance updates, use on own risk.
+# pfUI
-## DLL Integrations
+[](https://github.com/shagu/pfUI)
+[](#)
+[](#)
+[](https://github.com/balakethelock/SuperWoW)
-pfUI includes optional integration modules for client DLLs that provide enhanced functionality beyond what the standard WoW 1.12 client supports. These features are only enabled when the corresponding DLL is installed.
+An AddOn for World of Warcraft: Vanilla (1.12.1) and The Burning Crusade (2.4.3), which aims to be a full replacement for the original interface. The design is inspired by several screenshots I've seen from TukUI, ElvUI and others. This addon delivers modern features and a minimalistic style that's easy to use right from the start. It is entirely written from scratch without any inclusion of third-party addons or libraries.
+
+This is **not** an addon-pack like [ShaguUI](http://shagu.org/ShaguUI/), however, there is support for external addons like MobHealth3, DPSMate and others, but they will never be shipped within the package.
+
+**Please do not re-upload or distribute outdated versions of this project. However, you are more than welcome to fork or link to the official github page.**
---
+## What's New in Version 6.0.0 (January 5, 2026)
+
+### 🚀 Major Performance Improvements
+
+- ✅ **Central Raid/Party Event Handler** - Replaced per-frame event registration with a centralized system using O(1) unitmap lookups instead of O(n) iteration. Reduces event processing from ~5,760 calls/sec to ~400 calls/sec in 40-man raids (97.5% improvement)
+- ✅ **Raid HP/Mana Update Fix** - Fixed race condition where unitmap wasn't rebuilt after frame IDs were reassigned, causing HP/Mana bars to not update when players swap positions
+- ✅ **OnUpdate Throttling** - Added configurable throttles to reduce CPU usage:
+ - Nameplates: 0.1s throttle (target updates remain instant)
+ - Tooltip cursor following: 0.1s throttle
+ - Chat tab mouseover: 0.1s throttle
+ - Panel alignment: 0.2s throttle
+ - Autohide hover check: 0.05s throttle
+ - Libpredict cleanup: 0.1s throttle
+
+### 🔧 Castbar & Pushback System
+
+- ✅ **Pushback Fix** - Fixed spell pushback calculation: now correctly adds delay to `casttime` instead of `start` time, matching actual WoW behavior
+- ✅ **Player GUID Caching** - Caches player GUID on PLAYER_ENTERING_WORLD for efficient self-cast detection
+- ✅ **Hybrid Detection System** - Uses libcast.db for player casts (handles SPELLCAST_DELAYED events) and SuperWoW's UNIT_CASTEVENT for NPC/other player casts
+- ✅ **2-Decimal Precision** - Castbar timer now displays with 2 decimal places (e.g., "1.45 / 2.50") for more precise timing
+
+### 🐱 Druid Stealth Detection
+
+- ✅ **Event-Based Detection** - Replaced polling-based stealth detection with event-driven system using UNIT_CASTEVENT and PLAYER_AURAS_CHANGED
+- ✅ **Instant Cat Form Detection** - Detects Cat Form via UNIT_CASTEVENT (spell ID 768) for immediate actionbar page switch
+- ✅ **Smart Buff Scanning** - Only scans buffs when actually needed (entering Cat Form), eliminates 31-buff scan every frame
+- ✅ **Cached Variables** - Caches stealth state to prevent redundant checks
+
+### 🎯 Nameplate Improvements
+
+- ✅ **Friendly Player Classification** - Fixed friendly players being classified as FRIENDLY_NPC, now correctly uses FRIENDLY_PLAYER for proper nameplate coloring and behavior
+- ✅ **Performance Throttle** - 0.1s update throttle for non-target nameplates while keeping target nameplate updates instant
+
+### 🆕 New Modules
+
+- ✅ **nampower.lua** - Nampower DLL integration module:
+ - Spell Queue Indicator (shows queued spell icon near castbar)
+ - GCD Indicator
+ - Reactive Spell Indicator
+ - Enhanced buff tracking
+ - Requires [Nampower DLL](https://gitea.com/avitasia/nampower)
+
+- ✅ **unitxp.lua** - UnitXP_SP3 DLL integration module:
+ - Line of Sight Indicator on target frame
+ - Behind Indicator on target frame
+ - OS Notifications for combat events
+ - Distance-based features
+ - Requires [UnitXP_SP3 DLL](https://github.com/allfoxwy/UnitXP_SP3)
+
+- ✅ **bgscore.lua** - Battleground Score frame positioning:
+ - Movable BG score frame
+ - Position saving across sessions
+
+### 🛠️ DLL Detection & API Helpers
+
+- ✅ **HasSuperWoW()** - Detects SuperWoW DLL presence
+- ✅ **HasUnitXP()** - Detects UnitXP_SP3 DLL presence
+- ✅ **HasNampower()** - Detects Nampower DLL presence
+- ✅ **GetUnitDistance(unit1, unit2)** - Returns distance using best available method (UnitXP or SuperWoW)
+- ✅ **UnitInLineOfSight(unit1, unit2)** - Line of sight check via UnitXP
+- ✅ **UnitIsBehind(unit1, unit2)** - Behind check via UnitXP
+
+### 📝 New Slash Commands
+
+- ✅ **/pfdll** - Shows DLL status for SuperWoW, Nampower, and UnitXP with detailed diagnostics
+- ✅ **/pfbehind** - Test command for Behind/LOS detection on current target
+- ✅ **/clickthrough** or **/ct** - Toggle clickthrough mode (click through corpses)
+
+### 🎮 SuperWoW API Wrappers
+
+- ✅ **TrackUnit API** - Track group members on minimap (configurable)
+- ✅ **Raid Marker Targeting** - Target units by raid marker ("mark1" to "mark8")
+- ✅ **GetUnitOwner** - Get owner of pets/totems using "owner" suffix
+- ✅ **Enhanced SpellInfo** - Wrapper returning structured spell data
+- ✅ **Clickthrough API** - Toggle clicking through corpses
+- ✅ **Autoloot API** - Control autoloot setting
+- ✅ **GetPlayerBuffSpellId** - Get spell ID from buff index
+- ✅ **LogToCombatLog** - Add custom entries to combat log
+- ✅ **SetLocalRaidTarget** - Set raid markers only visible to self
+- ✅ **GetItemCharges** - Get item charges (SuperWoW returns as negative)
+- ✅ **GetUnitWeaponEnchants** - Get weapon enchant info on any unit
+
+### 💬 Chat Enhancements
+
+- ✅ **Player Level Display** - Shows player level next to names in chat (color-coded by difficulty)
+- ✅ **Tab Mouseover Throttle** - 0.1s throttle for chat tab hover effects
+
+### ⚙️ New Configuration Options
+
+All new features are configurable via `/pfui`:
+
+**Unit Frames → SuperWoW Settings:**
+- Track Group on Minimap
+
+**Unit Frames → Nampower Settings:**
+- Show Spell Queue Indicator
+- Spell Queue Icon Size
+- Show Reactive Spell Indicator
+- Reactive Indicator Size
+- Enhanced Buff Tracking
+
+**Unit Frames → UnitXP Settings:**
+- Show Line of Sight Indicator
+- Show Behind Indicator
+- Enable OS Notifications
+
+**Chat → Text:**
+- Enable Player Levels
+
+### 🐛 Bugfixes
+
+- ✅ **superwow_active Variable** - Fixed inconsistent SuperWoW detection across modules (nameplates, castbar, librange, unitframes)
+- ✅ **Unitmap Race Condition** - Fixed HP/Mana not updating when raid members swap positions
+- ✅ **Friendly Nameplate Color** - Fixed friendly players using NPC color instead of player color
+
+### 🔄 TBC Compatibility Preserved
+
+All TBC-specific features remain intact:
+- ✅ Commanding Shout indicator
+- ✅ Misdirection indicator
+- ✅ Earth Shield indicator
+- ✅ Prayer of Mending indicator
+
+---
+
+**Version:** 6.0.0
+**Release Date:** January 5, 2026
+**Compatibility:** World of Warcraft 1.12.1 (Vanilla) & 2.4.3 (TBC)
+**Optional DLLs:** SuperWoW, Nampower, UnitXP_SP3 (enhanced features when available)
+
+---
+
+## Installation (Vanilla)
+1. Download **[Latest Version](https://github.com/shagu/pfUI/archive/master.zip)**
+2. Unpack the Zip file
+3. Rename the folder "pfUI-master" to "pfUI"
+4. Copy "pfUI" into Wow-Directory\Interface\AddOns
+5. Restart Wow
+
+## Installation (The Burning Crusade)
+1. Download **[Latest Version](https://github.com/shagu/pfUI/archive/master.zip)**
+2. Unpack the Zip file
+3. Rename the folder "pfUI-master" to "pfUI-tbc"
+4. Copy "pfUI-tbc" into Wow-Directory\Interface\AddOns
+5. Restart Wow
+
+## Optional DLL Enhancements
+
+pfUI 6.0.0 includes optional integrations with client-side DLLs for enhanced functionality:
+
### SuperWoW
+**Repository:** [https://github.com/balakethelock/SuperWoW](https://github.com/balakethelock/SuperWoW)
-**Repository:** https://github.com/balakethelock/SuperWoW
-
-SuperWoW provides GUID-based unit tracking, spell information APIs, and various client enhancements.
-
-#### Features
-
-- **GUID-Based Focus Frame** - Focus frame uses actual unit GUIDs instead of name-based emulation
-- **Native Mouseover Casting** - `/pfcast` supports true mouseover targeting via `CastSpellByName(spell, unit)`
-- **Druid Mana Bar** - Shows mana while in feral forms (requires `unitframes.druidmanabar` config)
-- **Enhanced Cast Bars** - Uses `UNIT_CASTEVENT` for accurate cast/channel tracking with spell IDs
-- **Enhanced Debuff Tracking** - Accurate debuff application via `UNIT_CASTEVENT` with caster info
-- **Group Minimap Tracking** - Track party/raid members on minimap via `TrackUnit()` API
-- **Raid Marker Targeting** - Target units by raid marker (`mark1` to `mark8`)
-- **Clickthrough Mode** - Click through corpses to loot underneath (`/clickthrough` or `/ct`)
-- **Config Import/Export** - Save and load pfUI configs via `/pfexport` and `/pfimport`
-- **Local Raid Markers** - Set raid markers visible only to yourself
-- **Enchanting Link Fixes** - Converts enchant links for compatibility with non-SuperWoW clients
-
-#### API Functions
-
-| Function | Description |
-|----------|-------------|
-| `pfUI.api.GetMarkedUnit(index)` | Get unit ID for raid marker 1-8 |
-| `pfUI.api.TargetMark(index)` | Target unit with raid marker |
-| `pfUI.api.GetUnitOwner(unit)` | Get owner of pet/totem |
-| `pfUI.api.GetSpellInfo(spellId)` | Get spell name, rank, texture, range |
-| `pfUI.api.SetClickthrough(enabled)` | Enable/disable clickthrough |
-| `pfUI.api.ToggleClickthrough()` | Toggle clickthrough mode |
-| `pfUI.api.SetAutoloot(enabled)` | Enable/disable autoloot |
-| `pfUI.api.ExportConfig(filename)` | Export config to file |
-| `pfUI.api.ImportConfig(filename)` | Import config from file |
-| `pfUI.api.GetPlayerBuffSpellId(index)` | Get spell ID for player buff |
-| `pfUI.api.LogToCombatLog(text)` | Add text to combat log |
-| `pfUI.api.SetLocalRaidTarget(unit, index)` | Set local-only raid marker |
-| `pfUI.api.GetItemCharges(bag, slot)` | Get item charges (returns positive) |
-| `pfUI.api.GetUnitWeaponEnchants(unit)` | Get weapon enchant info |
-
----
+Provides:
+- Enhanced castbar detection via UNIT_CASTEVENT
+- UnitPosition for distance calculations
+- SetMouseoverUnit for improved targeting
+- SpellInfo for spell data queries
### Nampower
+**Repository:** [https://gitea.com/avitasia/nampower](https://gitea.com/avitasia/nampower)
-**Repository:** https://gitea.com/avitasia/nampower
-
-Nampower provides spell queuing, precise cooldown tracking, and detailed aura/buff information.
-
-#### Features
-
-- **Spell Queue Indicator** - Shows queued spell icon near castbar (requires `unitframes.spellqueue` config)
-- **Reactive Spell Indicator** - Highlights when Overpower, Revenge, Execute, Riposte, etc. are usable (requires `unitframes.reactive_indicator`)
-- **Enhanced Debuff Tracking** - GUID-based debuff tracking via `DEBUFF_ADDED/REMOVED` events
-- **Enhanced Buff Tracking** - GUID-based buff tracking via `BUFF_ADDED/REMOVED` events (requires `unitframes.nampower_buffs`)
-- **Swing Timer** - Track main-hand and off-hand auto-attack timers
-- **Disenchant All** - `/disenchantall` or `/dea` to disenchant eligible items
-
-#### API Functions
-
-| Function | Description |
-|----------|-------------|
-| `pfUI.api.GetUnitAuras(unit)` | Get all buffs/debuffs with spell IDs via `GetUnitField` |
-| `pfUI.api.UnitHasAura(unit, spellId)` | Check if unit has specific aura |
-| `pfUI.api.GetUnitResistances(unit)` | Get unit's resistances (armor, fire, frost, etc.) |
-| `pfUI.api.GetPreciseCooldown(spellId)` | Get precise cooldown info (remaining ms, GCD state) |
-| `pfUI.api.GetPreciseItemCooldown(itemId)` | Get precise item cooldown |
-| `pfUI.api.GetEquippedTrinkets()` | Get equipped trinket info |
-| `pfUI.api.GetTrinketCooldown(slot)` | Get trinket cooldown |
-| `pfUI.api.UseTrinket(slot, target)` | Use trinket |
-| `pfUI.api.GetNampowerItemStats(itemId)` | Get item stats |
-| `pfUI.api.GetNampowerItemLevel(itemId)` | Get item level |
-| `pfUI.api.GetSpellBonus(spellId, modType)` | Get spell modifiers (damage, crit, cost) |
-| `pfUI.api.GetSpellDamageBonus(spellId)` | Get spell damage bonus |
-| `pfUI.api.GetSpellCritBonus(spellId)` | Get spell crit bonus |
-| `pfUI.api.GetSpellCostReduction(spellId)` | Get spell cost reduction |
-| `pfUI.api.GetAllBagItems()` | Get all bag items |
-| `pfUI.api.FindItem(itemIdOrName)` | Find item in bags |
-| `pfUI.api.UseItem(itemIdOrName, target)` | Use item |
-| `pfUI.api.GetPlayerEquipment()` | Get player's equipped items |
-| `pfUI.api.GetTargetEquipment()` | Get target's equipped items |
-| `pfUI.api.GetMaxRankSpellId(spellName)` | Get spell ID for max rank |
-| `pfUI.api.GetSpellSlotInfo(spellName)` | Get spell slot/book info |
-| `pfUI.api.QueueLuaScript(script, priority)` | Queue Lua script for execution |
-| `pfUI.api.QueueSpell(spellName)` | Queue spell by name |
-| `pfUI.api.StopChannelNextTick()` | Stop channeling next tick |
-| `pfUI.api.GetSpellRecord(spellId)` | Get full spell database record |
-| `pfUI.api.GetSpellSchool(spellId)` | Get spell school (Fire, Frost, etc.) |
-| `pfUI.api.GetSwingTimers()` | Get auto-attack swing timers |
-| `pfUI.api.libdebuff_nampower(unit, id)` | Enhanced UnitDebuff with Nampower data |
-
----
+Provides:
+- Spell queue indicator
+- GCD indicator
+- Reactive spell detection
+- Enhanced cast information
### UnitXP_SP3
+**Repository:** [https://github.com/allfoxwy/UnitXP_SP3](https://github.com/allfoxwy/UnitXP_SP3)
-**Repository:** https://github.com/allfoxwy/UnitXP_SP3
+Provides:
+- Line of Sight detection
+- Behind detection
+- Accurate distance calculations
+- OS notifications
-UnitXP provides line-of-sight checks, positional information, precise distances, and OS-level notifications.
+Use `/pfdll` in-game to check which DLLs are detected.
-#### Features
+## Commands
-- **Line of Sight Indicator** - Shows "NO LOS" text on target frame when target is obstructed (requires `unitframes.los_indicator`)
-- **Behind Indicator** - Shows "BEHIND" text on target frame when positioned behind target (requires `unitframes.behind_indicator`)
-- **OS Notifications** - Flashes taskbar and plays system sound on whispers, ready checks, BG queue pops (requires `unitframes.unitxp_notify`)
-- **Precise Distance** - Exact yard distance between units
-- **Smart Targeting** - Target nearest enemy, highest HP, cycle through enemies
+ /pfui Open the configuration GUI
+ /pfdll Show DLL detection status (SuperWoW, Nampower, UnitXP)
+ /pfbehind Test Behind/LOS detection on current target
+ /clickthrough Toggle clickthrough mode (or /ct)
+ /share Open the configuration import/export dialog
+ /gm Open the ticket Dialog
+ /rl Reload the whole UI
+ /farm Toggles the Farm-Mode
+ /pfcast Same as /cast but for mouseover units
+ /focus Creates a Focus-Frame for the current target
+ /castfocus Same as /cast but for focus frame
+ /clearfocus Clears the Focus-Frame
+ /swapfocus Toggle Focus and Target-Frame
+ /pftest Toggle pfUI Unitframe Test Mode
+ /abp Addon Button Panel
-#### API Functions
+## Languages
+pfUI supports and contains language specific code for the following gameclients.
+* English (enUS)
+* Korean (koKR)
+* French (frFR)
+* German (deDE)
+* Chinese (zhCN)
+* Spanish (esES)
+* Russian (ruRU)
-| Function | Description |
-|----------|-------------|
-| `pfUI.api.GetPreciseDistance(unit1, unit2)` | Get exact distance in yards |
-| `pfUI.api.IsInMeleeRange(unit)` | Check if unit is in melee range |
-| `pfUI.api.GetAoEDistance(unit1, unit2)` | Get distance for AoE calculations |
-| `pfUI.api.TargetNearestEnemy()` | Target nearest hostile unit |
-| `pfUI.api.TargetHighestHP()` | Target enemy with most HP |
-| `pfUI.api.TargetNextEnemy()` | Cycle to next enemy |
-| `pfUI.api.TargetPreviousEnemy()` | Cycle to previous enemy |
-| `pfUI.api.TargetNextMarked(order)` | Target next marked enemy in order |
-| `pfUI.api.UnitInLineOfSight(unit1, unit2)` | Check line of sight between units |
-| `pfUI.api.UnitIsBehind(unit1, unit2)` | Check if unit1 is behind unit2 |
+## Recommended Addons
+* [pfQuest](https://shagu.org/pfQuest) A simple database and quest helper
+* [WIM](http://addons.us.to/addon/wim), [WIM (continued)](https://github.com/shirsig/WIM) Give whispers an instant messenger feel
+
+## Plugins
+* [pfUI-eliteoverlay](https://shagu.org/pfUI-eliteoverlay) Add elite dragons to unitframes
+* [pfUI-fonts](https://shagu.org/pfUI-fonts) Additional fonts for pfUI
+* [pfUI-CustomMedia](https://github.com/mrrosh/pfUI-CustomMedia) Additional textures for pfUI
+* [pfUI-Gryphons](https://github.com/mrrosh/pfUI-Gryphons) Add back the gryphons to your actionbars
+
+## FAQ
+**What does "pfUI" stand for?**
+The term "*pfui!*" is german and simply stands for "*pooh!*", because I'm not a
+big fan of creating configuration UI's, especially not via the Wow-API
+(you might have noticed that in ShaguUI).
+
+**How can I donate?**
+You can donate via [GitHub](https://github.com/sponsors/shagu) or [Ko-fi](https://ko-fi.com/shagu)
+
+**How do I report a Bug?**
+Please provide as much information as possible in the [Bugtracker](https://github.com/shagu/pfUI/issues).
+If there is an error message, provide the full content of it. Just telling that "there is an error" won't help any of us.
+Please consider adding additional information such as: since when did you got the error,
+does it still happen using a clean configuration, what other addons are loaded and which version you're running.
+When playing with a non-english client, the language might be relevant too. If possible, explain how people can reproduce the issue.
+
+**How can I contribute?**
+Report errors and issues in the [Bugtracker](https://github.com/shagu/pfUI/issues).
+Please make sure to have the latest version installed and check for conflicting addons beforehand.
+
+**I have bad performance, what can I do?**
+Version 6.0.0 includes significant performance optimizations. If you still experience issues:
+1. Disable "Frame Shadows" in Settings → Appearance → Enable Frame Shadows
+2. Check `/pfdll` to see which DLLs are active (some features require DLLs)
+3. Disable all AddOns but pfUI and enable one-by-one to identify conflicts
+4. Report issues via the [Bugtracker](https://github.com/shagu/pfUI/issues)
+
+**Where is the happiness indicator for pets?**
+The pet happiness is shown as the color of your pet's frame. Depending on your skin, this can either be the text or the background color of your pet's healthbar:
+
+- Green = Happy
+- Yellow = Content
+- Red = Unhappy
+
+Since version 4.0.7 there is also an additional icon that can be enabled from the pet unit frame options.
+
+**Can I use Clique with pfUI?**
+This addon already includes support for clickcasting. If you still want to make use of clique, all pfUI's unitframes are already compatible to Clique-TBC. For Vanilla, a pfUI compatible version can be found [Here](https://github.com/shagu/Clique/archive/master.zip). If you want to keep your current version of Clique, you'll have to apply this [Patch](https://github.com/shagu/Clique/commit/a5ee56c3f803afbdda07bae9cd330e0d4a75d75a).
+
+**Where is the Experience Bar?**
+The experience bar shows up on mouseover and whenever you gain experience, next to left chatframe by default. There's also an option to make it stay visible all the time.
+
+**How do I show the Damage- and Threatmeter Dock?**
+If you enabled the "dock"-feature for your external (third-party) meters such as DPSMate or KTM, then you'll be able to toggle between them and the Right Chat by clicking on the ">" symbol on the bottom-right panel.
+
+**Why is my chat always resetting to only 3 lines of text?**
+This happens if "Simple Chat" is enabled in blizzards interface settings (Advanced Options).
+Paste the following command into your chat to disable that option: `/run SIMPLE_CHAT="0"; pfUI.chat.SetupPositions(); ReloadUI()`
+
+**How can I enable mouseover cast?**
+On Vanilla, create a macro with "/pfcast SPELLNAME". If you also want to see the cooldown, You might want to add "/run if nil then CastSpellByName("SPELLNAME") end" on top of the macro. For The Burning Crusade, just use the regular mouseover macros.
+
+**Will there be pfUI for Activision's "Classic" remakes?**
+No, it would require an entire rewrite of the AddOn since the game is now a different one. The AddOn-API has evolved during the last 15 years and the new "Classic" versions are based on a current retail gameclient. I don't plan to play any of those new versions, so I won't be porting any of my addons to it.
+
+**Everything from scratch?! Are you insane?**
+Most probably, yes.
---
-### Configuration Options
+## 🤝 Credits & Acknowledgments
-These DLL features can be enabled/disabled via `/pfui` settings under Unit Frames:
+- **Shagu** - Original pfUI creator and maintainer
+- **SuperWoW Team** - SuperWoW framework development
+- **Nampower Team** - Nampower DLL development
+- **UnitXP Team** - UnitXP_SP3 DLL development
+- **Community** - Bug reports, feature suggestions, and testing
-| Setting | DLL | Description |
-|---------|-----|-------------|
-| `unitframes.druidmanabar` | SuperWoW | Show mana bar while shapeshifted |
-| `unitframes.track_group` | SuperWoW | Track group members on minimap |
-| `unitframes.spellqueue` | Nampower | Show spell queue indicator |
-| `unitframes.spellqueuesize` | Nampower | Spell queue icon size |
-| `unitframes.reactive_indicator` | Nampower | Show reactive ability procs |
-| `unitframes.reactive_size` | Nampower | Reactive indicator icon size |
-| `unitframes.nampower_buffs` | Nampower | Enhanced buff tracking |
-| `unitframes.los_indicator` | UnitXP | Show line of sight indicator |
-| `unitframes.behind_indicator` | UnitXP | Show behind indicator |
-| `unitframes.unitxp_notify` | UnitXP | Enable OS notifications |
+---
+
+## 📄 License
+
+Same as original pfUI - free to use and modify.
+
+---
+
+**Version:** 6.0.0
+**Release Date:** January 5, 2026
+**Compatibility:** World of Warcraft 1.12.1 (Vanilla) & 2.4.3 (TBC)
+**Status:** Stable & Production-Ready
diff --git a/api/api.lua b/api/api.lua
index dfa73621..030a1afd 100644
--- a/api/api.lua
+++ b/api/api.lua
@@ -3,10 +3,6 @@ pfUI.api = { }
-- load pfUI environment
setfenv(1, pfUI:GetEnvironment())
--- Client API shortcuts
-gfind = string.gmatch or string.gfind
-mod = math.mod or mod
-
-- [ DLL Detection Helpers ]
-- Detects presence of various DLL extensions for enhanced functionality
@@ -83,6 +79,10 @@ function pfUI.api.UnitIsBehind(unit1, unit2)
return nil
end
+-- Client API shortcuts
+gfind = string.gmatch or string.gfind
+mod = math.mod or mod
+
-- [ strsplit ]
-- Splits a string using a delimiter.
-- 'delimiter' [string] characters that will be interpreted as delimiter
@@ -1260,6 +1260,10 @@ function pfUI.api.EnableAutohide(frame, timeout, combat)
end
frame.hover:SetScript("OnUpdate", function()
+ -- throttle to 0.05s
+ if (this.tick or 0) > GetTime() then return end
+ this.tick = GetTime() + 0.05
+
if this.activeTo == "keep" then return end
if MouseIsOver(this, 10, -10, -10, 10) then
diff --git a/api/config.lua b/api/config.lua
index b7e3ceee..de550b88 100644
--- a/api/config.lua
+++ b/api/config.lua
@@ -221,6 +221,13 @@ function pfUI:LoadConfig()
pfUI:UpdateConfig("unitframes", nil, "druidmanabar", "1")
pfUI:UpdateConfig("unitframes", nil, "druidmanaheight", "2")
pfUI:UpdateConfig("unitframes", nil, "druidmanatext", "0")
+ pfUI:UpdateConfig("unitframes", nil, "rangechecki", "4")
+ pfUI:UpdateConfig("unitframes", nil, "combowidth", "6")
+ pfUI:UpdateConfig("unitframes", nil, "comboheight", "6")
+ pfUI:UpdateConfig("unitframes", nil, "abbrevnum", "1")
+ pfUI:UpdateConfig("unitframes", nil, "abbrevname", "1")
+
+ -- Nampower Settings
pfUI:UpdateConfig("unitframes", nil, "spellqueue", "1")
pfUI:UpdateConfig("unitframes", nil, "spellqueuesize", "24")
pfUI:UpdateConfig("unitframes", nil, "gcd_indicator", "0")
@@ -229,15 +236,12 @@ function pfUI:LoadConfig()
pfUI:UpdateConfig("unitframes", nil, "reactive_indicator", "0")
pfUI:UpdateConfig("unitframes", nil, "reactive_size", "28")
pfUI:UpdateConfig("unitframes", nil, "damage_tracking", "0")
+
+ -- UnitXP Settings
pfUI:UpdateConfig("unitframes", nil, "los_indicator", "0")
pfUI:UpdateConfig("unitframes", nil, "behind_indicator", "0")
pfUI:UpdateConfig("unitframes", nil, "unitxp_notify", "0")
pfUI:UpdateConfig("unitframes", nil, "track_group", "0")
- pfUI:UpdateConfig("unitframes", nil, "rangechecki", "4")
- pfUI:UpdateConfig("unitframes", nil, "combowidth", "6")
- pfUI:UpdateConfig("unitframes", nil, "comboheight", "6")
- pfUI:UpdateConfig("unitframes", nil, "abbrevnum", "1")
- pfUI:UpdateConfig("unitframes", nil, "abbrevname", "1")
pfUI:UpdateConfig("unitframes", nil, "selfingroup", "0")
pfUI:UpdateConfig("unitframes", nil, "selfinraid", "0")
@@ -725,8 +729,8 @@ function pfUI:LoadConfig()
pfUI:UpdateConfig("chat", "text", "playerlinks", "1")
pfUI:UpdateConfig("chat", "text", "detecturl", "1")
pfUI:UpdateConfig("chat", "text", "classcolor", "1")
- pfUI:UpdateConfig("chat", "text", "playerlevel", "1")
pfUI:UpdateConfig("chat", "text", "whosearchunknown", "0")
+ pfUI:UpdateConfig("chat", "text", "playerlevel", "1")
pfUI:UpdateConfig("chat", "left", "width", "380")
pfUI:UpdateConfig("chat", "left", "height", "180")
pfUI:UpdateConfig("chat", "right", "enable", "0")
diff --git a/api/unitframes.lua b/api/unitframes.lua
index db4fe46e..e9a4eb81 100644
--- a/api/unitframes.lua
+++ b/api/unitframes.lua
@@ -2405,6 +2405,8 @@ function pfUI.uf:SetupBuffIndicators(config)
if myclass == "WARRIOR" then
-- Battle Shout
table.insert(indicators, "interface\\icons\\ability_warrior_battleshout")
+ -- Commanding Shout (TBC)
+ table.insert(indicators, "interface\\icons\\ability_warrior_rallyingcry")
end
if myclass == "MAGE" then
@@ -2423,6 +2425,14 @@ function pfUI.uf:SetupBuffIndicators(config)
-- Aspect of the Pack
table.insert(indicators, "interface\\icons\\ability_mount_whitetiger")
+
+ -- Misdirection (TBC)
+ table.insert(indicators, "interface\\icons\\ability_hunter_misdirection")
+ end
+
+ if myclass == "SHAMAN" then
+ -- Earth Shield (TBC)
+ table.insert(indicators, "interface\\icons\\spell_nature_skinofearth")
end
end
@@ -2451,6 +2461,8 @@ function pfUI.uf:SetupBuffIndicators(config)
table.insert(indicators, "interface\\icons\\spell_holy_renew")
-- Power Word: Shield
table.insert(indicators, "interface\\icons\\spell_holy_powerwordshield")
+ -- Prayer of Mending (TBC)
+ table.insert(indicators, "interface\\icons\\spell_holy_prayerofmendingtga")
end
if myclass == "DRUID" or config.all_hots == "1" then
diff --git a/init/compat.xml b/init/compat.xml
index 173883ce..7d9f7b2d 100644
--- a/init/compat.xml
+++ b/init/compat.xml
@@ -1,3 +1,4 @@
+
diff --git a/init/modules.xml b/init/modules.xml
index 07f703ff..198ae3b4 100644
--- a/init/modules.xml
+++ b/init/modules.xml
@@ -35,6 +35,7 @@
+
@@ -65,6 +66,7 @@
+
@@ -72,4 +74,5 @@
+
diff --git a/init/skins.xml b/init/skins.xml
index 088c2d55..010e2b96 100644
--- a/init/skins.xml
+++ b/init/skins.xml
@@ -26,6 +26,7 @@
+
@@ -33,4 +34,13 @@
+
+
+
+
+
+
+
+
+
diff --git a/modules/addonbuttons.lua b/modules/addonbuttons.lua
index 319ebf3d..c083163f 100644
--- a/modules/addonbuttons.lua
+++ b/modules/addonbuttons.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("addonbuttons", "vanilla", function ()
+pfUI:RegisterModule("addonbuttons", "vanilla:tbc", function ()
if not pfUI.minimap then return end
if C.abuttons.enable == "0" then return end
diff --git a/modules/addons.lua b/modules/addons.lua
index da35d396..220035c8 100644
--- a/modules/addons.lua
+++ b/modules/addons.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("addons", "vanilla", function ()
+pfUI:RegisterModule("addons", "vanilla:tbc", function ()
local rawborder, border = GetBorderSize()
-- add main menu button
diff --git a/modules/afkcam.lua b/modules/afkcam.lua
index 504ad036..a9d55d0d 100644
--- a/modules/afkcam.lua
+++ b/modules/afkcam.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("afkcam", "vanilla", function ()
+pfUI:RegisterModule("afkcam", "vanilla:tbc", function ()
local MARKED_AFK_CAPTURE = SanitizePattern(MARKED_AFK_MESSAGE)
local social_chats = {
"CHAT_MSG_SAY",
diff --git a/modules/autovendor.lua b/modules/autovendor.lua
index 5dc88369..57c259ab 100644
--- a/modules/autovendor.lua
+++ b/modules/autovendor.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("autovendor", "vanilla", function ()
+pfUI:RegisterModule("autovendor", "vanilla:tbc", function ()
local rawborder, border = GetBorderSize()
local bpad = rawborder > 1 and border - GetPerfectPixel() or GetPerfectPixel()
local processed = {}
diff --git a/modules/bags.lua b/modules/bags.lua
index 49d5a084..d343d98a 100644
--- a/modules/bags.lua
+++ b/modules/bags.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("bags", "vanilla", function ()
+pfUI:RegisterModule("bags", "vanilla:tbc", function ()
local rawborder, default_border = GetBorderSize("bags")
local knownInventorySpellTextures = {
@@ -573,8 +573,8 @@ pfUI:RegisterModule("bags", "vanilla", function ()
SlotLeave()
end)
- -- The OnEvent function of the template scans for framenames,
- -- and doesn't know the pf-Names. Therefore, triggering
+ -- On TBC, the OnEvent function of the template scans for framenames,
+ -- and obviously doesn't know the pf-Names. Therefore, triggering
-- the update function on each frame manually
if frame == pfUI.bag.left and BankFrameItemButton_Update then
local SlotUpdate = frame.bagslots.slots[slot].frame:GetScript("OnUpdate")
diff --git a/modules/bubbles.lua b/modules/bubbles.lua
index 16f4dba6..61f9e991 100644
--- a/modules/bubbles.lua
+++ b/modules/bubbles.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("bubbles", "vanilla", function ()
+pfUI:RegisterModule("bubbles", "vanilla:tbc", function ()
local alpha = tonumber(C.chat.bubbles.alpha)
diff --git a/modules/buff.lua b/modules/buff.lua
index 7dfbabf6..f7114416 100644
--- a/modules/buff.lua
+++ b/modules/buff.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("buff", "vanilla", function ()
+pfUI:RegisterModule("buff", "vanilla:tbc", function ()
-- Hide Blizz
BuffFrame:Hide()
BuffFrame:UnregisterAllEvents()
diff --git a/modules/buffwatch.lua b/modules/buffwatch.lua
index f9c7a154..e9109b2a 100644
--- a/modules/buffwatch.lua
+++ b/modules/buffwatch.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("buffwatch", "vanilla", function ()
+pfUI:RegisterModule("buffwatch", "vanilla:tbc", function ()
local rawborder, border = GetBorderSize("panels")
local scanner = libtipscan:GetScanner("buffwatch")
diff --git a/modules/chat.lua b/modules/chat.lua
index 6268bd4f..5c706824 100644
--- a/modules/chat.lua
+++ b/modules/chat.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("chat", "vanilla", function ()
+pfUI:RegisterModule("chat", "vanilla:tbc", function ()
local panelfont = C.panel.use_unitfonts == "1" and pfUI.font_unit or pfUI.font_default
local panelfont_size = C.panel.use_unitfonts == "1" and C.global.font_unit_size or C.global.font_size
local rawborder, default_border = GetBorderSize("chat")
@@ -753,7 +753,8 @@ pfUI:RegisterModule("chat", "vanilla", function ()
end
-- Remove prat CLINKs
- text = gsub(text, "{CLINK:(%x+):([%d-]-:[%d-]-:[%d-]-:[%d-]-):([^}]-)}", "|c%1|Hitem:%2|h[%3]|h|r")
+ text = gsub(text, "{CLINK:(%x+):([%d-]-:[%d-]-:[%d-]-:[%d-]-:[%d-]-:[%d-]-:[%d-]-:[%d-]-):([^}]-)}", "|c%1|Hitem:%2|h[%3]|h|r") -- tbc
+ text = gsub(text, "{CLINK:(%x+):([%d-]-:[%d-]-:[%d-]-:[%d-]-):([^}]-)}", "|c%1|Hitem:%2|h[%3]|h|r") -- vanilla
-- Remove chatter CLINKs
text = gsub(text, "{CLINK:item:(%x+):([%d-]-:[%d-]-:[%d-]-:[%d-]-:[%d-]-:[%d-]-:[%d-]-:[%d-]-):([^}]-)}", "|c%1|Hitem:%2|h[%3]|h|r")
diff --git a/modules/chatcopy.lua b/modules/chatcopy.lua
index c67b2a01..11da75e0 100644
--- a/modules/chatcopy.lua
+++ b/modules/chatcopy.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("chatcopy", "vanilla", function ()
+pfUI:RegisterModule("chatcopy", "vanilla:tbc", function ()
local limit = 100
local f = CreateFrame("Frame")
f:RegisterEvent("PLAYER_ENTERING_WORLD")
diff --git a/modules/combopoints.lua b/modules/combopoints.lua
index 839f50d7..f874974e 100644
--- a/modules/combopoints.lua
+++ b/modules/combopoints.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("combopoints", "vanilla", function ()
+pfUI:RegisterModule("combopoints", "vanilla:tbc", function ()
local rawborder, border = GetBorderSize()
-- Hide Blizzard combo point frame and unregister all events to prevent it from popping up again
diff --git a/modules/cooldown.lua b/modules/cooldown.lua
index 9561cf83..0a293940 100644
--- a/modules/cooldown.lua
+++ b/modules/cooldown.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("cooldown", "vanilla", function ()
+pfUI:RegisterModule("cooldown", "vanilla:tbc", function ()
-- cache values
local lowcolor = {strsplit(",", C.appearance.cd.lowcolor)}
local normalcolor = {strsplit(",", C.appearance.cd.normalcolor)}
@@ -134,7 +134,14 @@ pfUI:RegisterModule("cooldown", "vanilla", function ()
end
end
- -- vanilla does not have a cooldown frame type, so we hook the
- -- regular SetTimer function that each one is calling.
- hooksecurefunc("CooldownFrame_SetTimer", SetCooldown)
+ if pfUI.expansion == "vanilla" then
+ -- vanilla does not have a cooldown frame type, so we hook the
+ -- regular SetTimer function that each one is calling.
+ hooksecurefunc("CooldownFrame_SetTimer", SetCooldown)
+ else
+ -- tbc and later expansion have a cooldown frametype, so we can
+ -- hook directly into the frame creation and add our function there.
+ local methods = getmetatable(CreateFrame('Cooldown', nil, nil, 'CooldownFrameTemplate')).__index
+ hooksecurefunc(methods, 'SetCooldown', SetCooldown)
+ end
end)
diff --git a/modules/easteregg.lua b/modules/easteregg.lua
index 9c5a7512..35a76c6d 100644
--- a/modules/easteregg.lua
+++ b/modules/easteregg.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("easteregg", "vanilla", function ()
+pfUI:RegisterModule("easteregg", "vanilla:tbc", function ()
-- merry x-mas!
if date("%m%d") == "1224" or date("%m%d") == "1225" then
local title = (UnitFactionGroup("player") == "Horde") and PVP_RANK_18_0 or PVP_RANK_18_1
diff --git a/modules/energytick.lua b/modules/energytick.lua
index cfcffb71..8e966afc 100644
--- a/modules/energytick.lua
+++ b/modules/energytick.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("energytick", "vanilla", function ()
+pfUI:RegisterModule("energytick", "vanilla:tbc", function ()
if not pfUI.uf or not pfUI.uf.player then return end
local energytick = CreateFrame("Frame", nil, pfUI.uf.player.power.bar)
@@ -7,9 +7,6 @@ pfUI:RegisterModule("energytick", "vanilla", function ()
energytick:RegisterEvent("UNIT_DISPLAYPOWER")
energytick:RegisterEvent("UNIT_ENERGY")
energytick:RegisterEvent("UNIT_MANA")
- energytick:RegisterEvent("CHAT_MSG_SPELL_SELF_BUFF")
- energytick:RegisterEvent("CHAT_MSG_SPELL_PERIODIC_SELF_BUFFS")
-
energytick:SetScript("OnEvent", function()
if UnitPowerType("player") == 0 and C.unitframes.player.manatick == "1" then
this.mode = "MANA"
@@ -21,14 +18,6 @@ pfUI:RegisterModule("energytick", "vanilla", function ()
this:Hide()
end
- -- Filter nur eigene Energy-Gewinne von Talents/Buffs
- if event == "CHAT_MSG_SPELL_SELF_BUFF" or event == "CHAT_MSG_SPELL_PERIODIC_SELF_BUFFS" then
- if string.find(arg1, "You gain") and string.find(arg1, "Energy from") then
- this.ignoreNextGain = true
- end
- return
- end
-
if event == "PLAYER_ENTERING_WORLD" then
this.lastMana = UnitMana("player")
end
@@ -49,10 +38,7 @@ pfUI:RegisterModule("energytick", "vanilla", function ()
this.badtick = diff
end
elseif this.mode == "ENERGY" and diff > 0 then
- if not this.ignoreNextGain then
- this.target = 2
- end
- this.ignoreNextGain = false
+ this.target = 2
end
this.lastMana = this.currentMana
end
@@ -83,10 +69,14 @@ pfUI:RegisterModule("energytick", "vanilla", function ()
energytick.spark:SetWidth(C.unitframes.player.pheight + 5)
energytick.spark:SetBlendMode('ADD')
+ -- update spark size on player frame changes
local hookUpdateConfig = pfUI.uf.player.UpdateConfig
function pfUI.uf.player.UpdateConfig()
+ -- update spark sizes
energytick.spark:SetHeight(C.unitframes.player.pheight + 15)
energytick.spark:SetWidth(C.unitframes.player.pheight + 5)
+
+ -- run default unitframe update function
hookUpdateConfig(pfUI.uf.player)
end
-end)
\ No newline at end of file
+end)
diff --git a/modules/farmmode.lua b/modules/farmmode.lua
index 0a1e3bad..19478884 100644
--- a/modules/farmmode.lua
+++ b/modules/farmmode.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("farmmode", "vanilla", function ()
+pfUI:RegisterModule("farmmode", "vanilla:tbc", function ()
local function ToggleFarmMode()
if pfUI.farmmap:IsShown() then
pfUI.farmmap:Hide()
diff --git a/modules/feigndeath.lua b/modules/feigndeath.lua
index 01a5e41f..ba4e5fcd 100644
--- a/modules/feigndeath.lua
+++ b/modules/feigndeath.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("feigndeath", "vanilla", function ()
+pfUI:RegisterModule("feigndeath", "vanilla:tbc", function ()
local cache = { }
local scanner = libtipscan:GetScanner("feigndeath")
local healthbar = scanner:GetChildren()
diff --git a/modules/firstrun.lua b/modules/firstrun.lua
index 582cbe45..f27bd7f2 100644
--- a/modules/firstrun.lua
+++ b/modules/firstrun.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("firstrun", "vanilla", function ()
+pfUI:RegisterModule("firstrun", "vanilla:tbc", function ()
pfUI.firstrun = CreateFrame("Frame", "pfFirstRunWizard", UIParent)
pfUI.firstrun.steps = {}
diff --git a/modules/focus.lua b/modules/focus.lua
index 16f4124a..a2e24582 100644
--- a/modules/focus.lua
+++ b/modules/focus.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("focus", "vanilla", function ()
+pfUI:RegisterModule("focus", "vanilla:tbc", function ()
-- do not go further on disabled UFs
if C.unitframes.disable == "1" then return end
diff --git a/modules/group.lua b/modules/group.lua
index 81684f70..5aa0aaa2 100644
--- a/modules/group.lua
+++ b/modules/group.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("group", "vanilla", function ()
+pfUI:RegisterModule("group", "vanilla:tbc", function ()
-- do not go further on disabled UFs
if C.unitframes.disable == "1" then return end
diff --git a/modules/gryphons.lua b/modules/gryphons.lua
index 287ae5b8..96eba04e 100644
--- a/modules/gryphons.lua
+++ b/modules/gryphons.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("gryphons", "vanilla", function ()
+pfUI:RegisterModule("gryphons", "vanilla:tbc", function ()
pfUI.gryphons = {
frames = {
left = CreateFrame("Frame"),
diff --git a/modules/gui.lua b/modules/gui.lua
index 64785efe..92b2abde 100644
--- a/modules/gui.lua
+++ b/modules/gui.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("gui", "vanilla", function ()
+pfUI:RegisterModule("gui", "vanilla:tbc", function ()
local Reload, U, CreateConfig, CreateTabFrame, CreateArea, CreateGUIEntry, EntryUpdate
-- "searchDB" gets populated when CreateConfig is called. The table holds
@@ -2402,26 +2402,36 @@ pfUI:RegisterModule("gui", "vanilla", function ()
CreateConfig(nil, "ShaguDPS (" .. T["Dock"] .. ")", C.thirdparty.shagudps, "dock", "checkbox")
CreateConfig(nil, "DPSMate (" .. T["Skin"] .. ")", C.thirdparty.dpsmate, "skin", "checkbox")
CreateConfig(nil, "DPSMate (" .. T["Dock"] .. ")", C.thirdparty.dpsmate, "dock", "checkbox")
- CreateConfig(nil, "SWStats (" .. T["Skin"] .. ")", C.thirdparty.swstats, "skin", "checkbox")
- CreateConfig(nil, "SWStats (" .. T["Dock"] .. ")", C.thirdparty.swstats, "dock", "checkbox")
- CreateConfig(nil, "KLH Threat Meter (" .. T["Skin"] .. ")", C.thirdparty.ktm, "skin", "checkbox")
- CreateConfig(nil, "KLH Threat Meter (" .. T["Dock"] .. ")", C.thirdparty.ktm, "dock", "checkbox")
- CreateConfig(nil, "TW Threatmeter (" .. T["Skin"] .. ")", C.thirdparty.twt, "skin", "checkbox")
- CreateConfig(nil, "TW Threatmeter (" .. T["Dock"] .. ")", C.thirdparty.twt, "dock", "checkbox")
- CreateConfig(nil, "WIM", C.thirdparty.wim, "enable", "checkbox")
- CreateConfig(nil, "HealComm", C.thirdparty.healcomm, "enable", "checkbox")
- CreateConfig(nil, "SortBags", C.thirdparty.sortbags, "enable", "checkbox")
+ CreateConfig(nil, "Recount (" .. T["Skin"] .. ")", C.thirdparty.recount, "skin", "checkbox", nil, nil, nil, nil, "tbc")
+ CreateConfig(nil, "Recount (" .. T["Dock"] .. ")", C.thirdparty.recount, "dock", "checkbox", nil, nil, nil, nil, "tbc")
+ CreateConfig(nil, "Omen (" .. T["Skin"] .. ")", C.thirdparty.omen, "skin", "checkbox", nil, nil, nil, nil, "tbc")
+ CreateConfig(nil, "Omen (" .. T["Dock"] .. ")", C.thirdparty.omen, "dock", "checkbox", nil, nil, nil, nil, "tbc")
+ CreateConfig(nil, "SWStats (" .. T["Skin"] .. ")", C.thirdparty.swstats, "skin", "checkbox", nil, nil, nil, nil, "vanilla")
+ CreateConfig(nil, "SWStats (" .. T["Dock"] .. ")", C.thirdparty.swstats, "dock", "checkbox", nil, nil, nil, nil, "vanilla")
+ CreateConfig(nil, "KLH Threat Meter (" .. T["Skin"] .. ")", C.thirdparty.ktm, "skin", "checkbox", nil, nil, nil, nil, "vanilla")
+ CreateConfig(nil, "KLH Threat Meter (" .. T["Dock"] .. ")", C.thirdparty.ktm, "dock", "checkbox", nil, nil, nil, nil, "vanilla")
+ CreateConfig(nil, "TW Threatmeter (" .. T["Skin"] .. ")", C.thirdparty.twt, "skin", "checkbox", nil, nil, nil, nil, "vanilla")
+ CreateConfig(nil, "TW Threatmeter (" .. T["Dock"] .. ")", C.thirdparty.twt, "dock", "checkbox", nil, nil, nil, nil, "vanilla")
+ CreateConfig(nil, "WIM", C.thirdparty.wim, "enable", "checkbox", nil, nil, nil, nil, "vanilla")
+ CreateConfig(nil, "HealComm", C.thirdparty.healcomm, "enable", "checkbox", nil, nil, nil, nil, "vanilla")
+ CreateConfig(nil, "SortBags", C.thirdparty.sortbags, "enable", "checkbox", nil, nil, nil, nil, "vanilla")
+ CreateConfig(nil, "Bag_Sort", C.thirdparty.bag_sort, "enable", "checkbox", nil, nil, nil, nil, "tbc")
CreateConfig(nil, "MrPlow", C.thirdparty.mrplow, "enable", "checkbox")
- CreateConfig(nil, "BetterCharacterStats", C.thirdparty.bcs, "enable", "checkbox")
- CreateConfig(nil, "Crafty", C.thirdparty.crafty, "enable", "checkbox")
- CreateConfig(nil, "CleverMacro", C.thirdparty.clevermacro, "enable", "checkbox")
- CreateConfig(nil, "FlightMap", C.thirdparty.flightmap, "enable", "checkbox")
- CreateConfig(nil, "TheoryCraft", C.thirdparty.theorycraft, "enable", "checkbox")
- CreateConfig(nil, "SuperMacro", C.thirdparty.supermacro, "enable", "checkbox")
- CreateConfig(nil, "AtlasLoot", C.thirdparty.atlasloot, "enable", "checkbox")
- CreateConfig(nil, "MyRolePlay", C.thirdparty.myroleplay, "enable", "checkbox")
- CreateConfig(nil, "DruidManaBar", C.thirdparty.druidmana, "enable", "checkbox")
- CreateConfig(nil, "NoteIt", C.thirdparty.noteit, "enable", "checkbox")
+ CreateConfig(nil, "BetterCharacterStats", C.thirdparty.bcs, "enable", "checkbox", nil, nil, nil, nil, "vanilla")
+ CreateConfig(nil, "Crafty", C.thirdparty.crafty, "enable", "checkbox", nil, nil, nil, nil, "vanilla")
+ CreateConfig(nil, "CleverMacro", C.thirdparty.clevermacro, "enable", "checkbox", nil, nil, nil, nil, "vanilla")
+ CreateConfig(nil, "AckisRecipeList", C.thirdparty.ackis, "enable", "checkbox", nil, nil, nil, nil, "tbc")
+ CreateConfig(nil, "SheepWatch", C.thirdparty.sheepwatch, "enable", "checkbox", nil, nil, nil, nil, "tbc")
+ CreateConfig(nil, "TotemTimers", C.thirdparty.totemtimers, "enable", "checkbox", nil, nil, nil, nil, "tbc")
+ CreateConfig(nil, "DruidBar", C.thirdparty.druidbar, "enable", "checkbox", nil, nil, nil, nil, "tbc")
+ CreateConfig(nil, "BCEPGP", C.thirdparty.bcepgp, "enable", "checkbox", nil, nil, nil, nil, "tbc")
+ CreateConfig(nil, "FlightMap", C.thirdparty.flightmap, "enable", "checkbox", nil, nil, nil, nil, "vanilla")
+ CreateConfig(nil, "TheoryCraft", C.thirdparty.theorycraft, "enable", "checkbox", nil, nil, nil, nil, "vanilla")
+ CreateConfig(nil, "SuperMacro", C.thirdparty.supermacro, "enable", "checkbox", nil, nil, nil, nil, "vanilla")
+ CreateConfig(nil, "AtlasLoot", C.thirdparty.atlasloot, "enable", "checkbox", nil, nil, nil, nil, "vanilla")
+ CreateConfig(nil, "MyRolePlay", C.thirdparty.myroleplay, "enable", "checkbox", nil, nil, nil, nil, "vanilla")
+ CreateConfig(nil, "DruidManaBar", C.thirdparty.druidmana, "enable", "checkbox", nil, nil, nil, nil, "vanilla")
+ CreateConfig(nil, "NoteIt", C.thirdparty.noteit, "enable", "checkbox", nil, nil, nil, nil, "vanilla")
end)
CreateGUIEntry(T["Components"], T["Modules"], function()
diff --git a/modules/hoverbind.lua b/modules/hoverbind.lua
index a838a5c2..00f4a162 100644
--- a/modules/hoverbind.lua
+++ b/modules/hoverbind.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("hoverbind", "vanilla", function ()
+pfUI:RegisterModule("hoverbind", "vanilla:tbc", function ()
local keymap = {
-- buttons to binding association
["pfActionBarMainButton"] = "ACTIONBUTTON",
diff --git a/modules/infight.lua b/modules/infight.lua
index b48b4e88..95531a8e 100644
--- a/modules/infight.lua
+++ b/modules/infight.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("infight", "vanilla", function ()
+pfUI:RegisterModule("infight", "vanilla:tbc", function ()
local function OnUpdate()
if not this.infight and not this.aggro and not this.health then return end
if ( this.tick or 1) > GetTime() then return else this.tick = GetTime() + .1 end
diff --git a/modules/loot.lua b/modules/loot.lua
index bfa2ab1a..a2284398 100644
--- a/modules/loot.lua
+++ b/modules/loot.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("loot", "vanilla", function ()
+pfUI:RegisterModule("loot", "vanilla:tbc", function ()
local rawborder, border = GetBorderSize()
pfUI.loot = CreateFrame("Frame", "pfLootFrame", UIParent)
diff --git a/modules/map.lua b/modules/map.lua
index 247e1150..806f1e17 100644
--- a/modules/map.lua
+++ b/modules/map.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("map", "vanilla", function ()
+pfUI:RegisterModule("map", "vanilla:tbc", function ()
table.insert(UISpecialFrames, "WorldMapFrame")
local function UpdateTooltipScale()
diff --git a/modules/mapreveal.lua b/modules/mapreveal.lua
index c8120a6c..594b0ff3 100644
--- a/modules/mapreveal.lua
+++ b/modules/mapreveal.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("mapreveal", "vanilla", function ()
+pfUI:RegisterModule("mapreveal", "vanilla:tbc", function ()
-- do not load if other map addon is loaded
if Cartographer then return end
if METAMAP_TITLE then return end
diff --git a/modules/minimap.lua b/modules/minimap.lua
index 3ea5f343..53bc3374 100644
--- a/modules/minimap.lua
+++ b/modules/minimap.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("minimap", "vanilla", function ()
+pfUI:RegisterModule("minimap", "vanilla:tbc", function ()
local rawborder, border = GetBorderSize()
local size = tonumber(C.appearance.minimap.size) or 140
@@ -39,7 +39,7 @@ pfUI:RegisterModule("minimap", "vanilla", function ()
Minimap:SetWidth(size)
Minimap:SetHeight(size)
- -- do the best to detect the minimap arrow
+ -- vanilla+tbc: do the best to detect the minimap arrow
local arrowscale = tonumber(C.appearance.minimap.arrowscale)
local minimaparrow = ({Minimap:GetChildren()})[9]
for k, v in pairs({Minimap:GetChildren()}) do
diff --git a/modules/mirrortimers.lua b/modules/mirrortimers.lua
index 311e6683..6b08f395 100644
--- a/modules/mirrortimers.lua
+++ b/modules/mirrortimers.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("mirrortimers", "vanilla", function ()
+pfUI:RegisterModule("mirrortimers", "vanilla:tbc", function ()
local font = pfUI.font_default
local fontsize = tonumber(C.global.font_size)
local height = fontsize * 1.3
diff --git a/modules/panel.lua b/modules/panel.lua
index 8f235776..755cd079 100644
--- a/modules/panel.lua
+++ b/modules/panel.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("panel", "vanilla", function()
+pfUI:RegisterModule("panel", "vanilla:tbc", function()
-- initialize gold cache if not yet happened
pfUI_cache["gold"] = pfUI_cache["gold"] or {}
diff --git a/modules/pet.lua b/modules/pet.lua
index 46a45ede..223c633c 100644
--- a/modules/pet.lua
+++ b/modules/pet.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("pet", "vanilla", function ()
+pfUI:RegisterModule("pet", "vanilla:tbc", function ()
-- do not go further on disabled UFs
if C.unitframes.disable == "1" then return end
pfUI.uf.pet = pfUI.uf:CreateUnitFrame("Pet", nil, C.unitframes.pet)
diff --git a/modules/pettarget.lua b/modules/pettarget.lua
index 1fe945df..017c30c4 100644
--- a/modules/pettarget.lua
+++ b/modules/pettarget.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("pettarget", "vanilla", function ()
+pfUI:RegisterModule("pettarget", "vanilla:tbc", function ()
-- do not go further on disabled UFs
if C.unitframes.disable == "1" then return end
local rawborder, default_border = GetBorderSize("unitframes")
diff --git a/modules/pixelperfect.lua b/modules/pixelperfect.lua
index 16862787..ec4166d4 100644
--- a/modules/pixelperfect.lua
+++ b/modules/pixelperfect.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("pixelperfect", "vanilla", function ()
+pfUI:RegisterModule("pixelperfect", "vanilla:tbc", function ()
-- pre-calculated min values
local statics = {
[4] = 1.4222222222222,
diff --git a/modules/player.lua b/modules/player.lua
index 91302d80..59979fff 100644
--- a/modules/player.lua
+++ b/modules/player.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("player", "vanilla", function ()
+pfUI:RegisterModule("player", "vanilla:tbc", function ()
-- do not go further on disabled UFs
if C.unitframes.disable == "1" then return end
diff --git a/modules/questitem.lua b/modules/questitem.lua
index 290495e2..7a8715c6 100644
--- a/modules/questitem.lua
+++ b/modules/questitem.lua
@@ -96,7 +96,11 @@ pfUI:RegisterModule("questitem", function ()
SelectQuestLogEntry(quest)
-- detect and ignore quest headers
- _, _, _, header = GetQuestLogTitle(quest)
+ if pfUI.client <= 11200 then -- vanilla
+ _, _, _, header = GetQuestLogTitle(quest)
+ elseif pfUI.client > 11200 then -- tbc
+ _, _, _, _, header = GetQuestLogTitle(quest)
+ end
if not header then
text, objective = GetQuestLogQuestText()
diff --git a/modules/raid.lua b/modules/raid.lua
index 6b3577ae..7bda90ba 100644
--- a/modules/raid.lua
+++ b/modules/raid.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("raid", "vanilla", function ()
+pfUI:RegisterModule("raid", "vanilla:tbc", function ()
-- do not go further on disabled UFs
if C.unitframes.disable == "1" then return end
diff --git a/modules/roll.lua b/modules/roll.lua
index 8580e514..7762774c 100644
--- a/modules/roll.lua
+++ b/modules/roll.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("roll", "vanilla", function ()
+pfUI:RegisterModule("roll", "vanilla:tbc", function ()
pfUI.roll = CreateFrame("Frame", "pfLootRoll", UIParent)
pfUI.roll.frames = {}
diff --git a/modules/screenshot.lua b/modules/screenshot.lua
index d6ac5b8f..54bb3425 100644
--- a/modules/screenshot.lua
+++ b/modules/screenshot.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("screenshot", "vanilla", function ()
+pfUI:RegisterModule("screenshot", "vanilla:tbc", function ()
if C.screenshot.interval == "0"
and C.screenshot.levelup == "0"
and C.screenshot.pvprank == "0"
diff --git a/modules/sellvalue.lua b/modules/sellvalue.lua
index a14427f8..f854d089 100644
--- a/modules/sellvalue.lua
+++ b/modules/sellvalue.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("sellvalue", "vanilla", function ()
+pfUI:RegisterModule("sellvalue", "vanilla:tbc", function ()
local function AddVendorPrices(frame, id, count)
if pfSellData[id] then
local _, _, sell, buy = strfind(pfSellData[id], "(.*),(.*)")
diff --git a/modules/share.lua b/modules/share.lua
index d5cc522e..a49841bc 100644
--- a/modules/share.lua
+++ b/modules/share.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("share", "vanilla", function ()
+pfUI:RegisterModule("share", "vanilla:tbc", function ()
local function serialize(tbl, comp, name, ignored, spacing)
local spacing = spacing or ""
local match = nil
diff --git a/modules/socialmod.lua b/modules/socialmod.lua
index a3da0610..e18fea58 100644
--- a/modules/socialmod.lua
+++ b/modules/socialmod.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("socialmod", "vanilla", function ()
+pfUI:RegisterModule("socialmod", "vanilla:tbc", function ()
local playerdb = _G.pfUI_playerDB
pfUI.socialmod = CreateFrame("Frame", "pfSocialMod", UIParent)
pfUI.socialmod:RegisterEvent("CHAT_MSG_SYSTEM")
diff --git a/modules/superwow.lua b/modules/superwow.lua
index 0ffdf4c3..4382d0f6 100644
--- a/modules/superwow.lua
+++ b/modules/superwow.lua
@@ -439,70 +439,6 @@ pfUI:RegisterModule("superwow", "vanilla", function ()
end
end
- -- Config Import/Export API using ImportFile/ExportFile
- if ImportFile and ExportFile then
- pfUI.api.ExportConfig = function(filename)
- filename = filename or "pfUI_config_backup.txt"
- local configStr = ""
-
- -- Serialize config to string
- local function serialize(tbl, indent)
- indent = indent or ""
- local result = "{\n"
- for k, v in pairs(tbl) do
- local keyStr = type(k) == "string" and '["' .. k .. '"]' or "[" .. tostring(k) .. "]"
- if type(v) == "table" then
- result = result .. indent .. " " .. keyStr .. " = " .. serialize(v, indent .. " ") .. ",\n"
- elseif type(v) == "string" then
- result = result .. indent .. " " .. keyStr .. ' = "' .. v .. '",\n'
- else
- result = result .. indent .. " " .. keyStr .. " = " .. tostring(v) .. ",\n"
- end
- end
- return result .. indent .. "}"
- end
-
- if pfUI_config then
- configStr = "pfUI_config = " .. serialize(pfUI_config)
- ExportFile(filename, configStr)
- DEFAULT_CHAT_FRAME:AddMessage("|cff33ffccpfUI|r: Config exported to imports/" .. filename)
- return true
- end
- return false
- end
-
- pfUI.api.ImportConfig = function(filename)
- filename = filename or "pfUI_config_backup.txt"
- local content = ImportFile(filename)
- if content and content ~= "" then
- -- Load the config string
- local func, err = loadstring(content)
- if func then
- func()
- DEFAULT_CHAT_FRAME:AddMessage("|cff33ffccpfUI|r: Config imported from imports/" .. filename)
- DEFAULT_CHAT_FRAME:AddMessage("|cff33ffccpfUI|r: Please /reload to apply changes")
- return true
- else
- DEFAULT_CHAT_FRAME:AddMessage("|cff33ffccpfUI|r: Error parsing config: " .. (err or "unknown"))
- end
- else
- DEFAULT_CHAT_FRAME:AddMessage("|cff33ffccpfUI|r: Could not read imports/" .. filename)
- end
- return false
- end
-
- -- Slash commands for config backup
- SLASH_PFEXPORT1 = "/pfexport"
- SlashCmdList["PFEXPORT"] = function(msg)
- pfUI.api.ExportConfig(msg ~= "" and msg or nil)
- end
-
- SLASH_PFIMPORT1 = "/pfimport"
- SlashCmdList["PFIMPORT"] = function(msg)
- pfUI.api.ImportConfig(msg ~= "" and msg or nil)
- end
- end
-
-- GetPlayerBuffID wrapper
if GetPlayerBuffID then
pfUI.api.GetPlayerBuffSpellId = function(buffIndex)
@@ -559,7 +495,7 @@ pfUI:RegisterModule("superwow", "vanilla", function ()
end
end
- -- Enhance libcast with SuperWoW data for NPCs and other players only
+ -- Enhance libcast with SuperWoW data for NPCs and other players
-- Player casts use SPELLCAST_* events for proper pushback handling
local supercast = CreateFrame("Frame")
local playerGuid = nil
@@ -622,6 +558,9 @@ pfUI:RegisterModule("superwow", "vanilla", function ()
-- skip on buff procs during cast
if event_type == "CAST" then
if not libcast.db[guid] or libcast.db[guid].cast ~= spell then
+ -- ignore casts without 'START' event, while there is already another cast.
+ -- those events can be for example a frost shield proc while casting frostbolt.
+ -- we want to keep the cast itself, so we simply skip those.
return
end
end
@@ -639,7 +578,10 @@ pfUI:RegisterModule("superwow", "vanilla", function ()
libcast.db[dbKey].icon = icon
libcast.db[dbKey].channel = event_type == "CHANNEL" or false
elseif arg3 == "FAIL" then
+ -- For player: use playerName, for others: use GUID
local dbKey = isPlayer and UnitName("player") or guid
+
+ -- delete all cast entries
if libcast.db[dbKey] then
libcast.db[dbKey].cast = nil
libcast.db[dbKey].rank = nil
diff --git a/modules/target.lua b/modules/target.lua
index 11104094..9522b8d0 100644
--- a/modules/target.lua
+++ b/modules/target.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("target", "vanilla", function ()
+pfUI:RegisterModule("target", "vanilla:tbc", function ()
-- do not go further on disabled UFs
if C.unitframes.disable == "1" then return end
diff --git a/modules/targettarget.lua b/modules/targettarget.lua
index e8310065..893ad670 100644
--- a/modules/targettarget.lua
+++ b/modules/targettarget.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("targettarget", "vanilla", function ()
+pfUI:RegisterModule("targettarget", "vanilla:tbc", function ()
-- do not go further on disabled UFs
if C.unitframes.disable == "1" then return end
diff --git a/modules/targettargettarget.lua b/modules/targettargettarget.lua
index ec31d90c..6e912b3b 100644
--- a/modules/targettargettarget.lua
+++ b/modules/targettargettarget.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("targettargettarget", "vanilla", function ()
+pfUI:RegisterModule("targettargettarget", "vanilla:tbc", function ()
-- do not go further on disabled UFs
if C.unitframes.disable == "1" then return end
diff --git a/modules/thirdparty.lua b/modules/thirdparty.lua
index f84037f7..f480df7f 100644
--- a/modules/thirdparty.lua
+++ b/modules/thirdparty.lua
@@ -1,7 +1,10 @@
-pfUI:RegisterModule("thirdparty", "vanilla", function()
+pfUI:RegisterModule("thirdparty", "vanilla:tbc", function()
-- This module includes the core logic of thirdparty modules.
-- Right now, in particular the functions to register addons to the
-- dockframe of the chat panel aswell as the thirdparty root-table.
+ -- This module is supposed to be loaded on all expansions, so only
+ -- addons that can share the same glue code across expansions will go here.
+ -- For expansion related code, see: thirdparty-vanilla and thirdparty-tbc.
pfUI.thirdparty = {}
@@ -193,7 +196,8 @@ pfUI:RegisterModule("thirdparty", "vanilla", function()
end
-- MrPlow Bag Sorting Addon.
- -- https://www.wowace.com/projects/mr-plow/files/288059
+ -- Vanilla: https://www.wowace.com/projects/mr-plow/files/288059
+ -- TBC: https://www.wowace.com/projects/mr-plow/files/136162
HookAddonOrVariable("MrPlow", function()
if C.thirdparty.mrplow.enable == "0" then return end
@@ -228,7 +232,8 @@ pfUI:RegisterModule("thirdparty", "vanilla", function()
end)
-- ShaguDPS Damage Meter
- -- https://github.com/shagu/ShaguDPS
+ -- Vanilla: https://github.com/shagu/ShaguDPS
+ -- TBC: https://github.com/shagu/ShaguDPS
HookAddonOrVariable("ShaguDPS", function()
local docktable = { "shagudps", "ShaguDPS", "ShaguDPSWindow",
function() -- single
@@ -328,7 +333,8 @@ pfUI:RegisterModule("thirdparty", "vanilla", function()
end)
-- DPSMate Damage Meter
- -- https://github.com/Geigerkind/DPSMate
+ -- Vanilla: https://github.com/Geigerkind/DPSMate
+ -- TBC: https://github.com/Geigerkind/DPSMateTBC
HookAddonOrVariable("DPSMate_DPSMate", function()
local docktable = { "dpsmate", "DPSMate", "DPSMate_DPSMate",
function() -- single
diff --git a/modules/totems.lua b/modules/totems.lua
index 56ab9480..59eab973 100644
--- a/modules/totems.lua
+++ b/modules/totems.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("totems", "vanilla", function ()
+pfUI:RegisterModule("totems", "vanilla:tbc", function ()
local _, class = UnitClass("player")
local slots = {
@@ -42,6 +42,9 @@ pfUI:RegisterModule("totems", "vanilla", function ()
-- Try to recast totem on left click in vanilla
local active, name, start, duration, icon = GetTotemInfo(this.id)
if name then CastSpellByName(name) end
+ elseif pfUI.client > 11200 and this.id and arg1 and arg1 == "RightButton" then
+ -- Try to cancel totem on right click in tbc+
+ DestroyTotem(this.id)
end
end
diff --git a/modules/uf_tukui.lua b/modules/uf_tukui.lua
index e798043c..b48e3829 100644
--- a/modules/uf_tukui.lua
+++ b/modules/uf_tukui.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("uf_tukui", "vanilla", function ()
+pfUI:RegisterModule("uf_tukui", "vanilla:tbc", function ()
if C.unitframes.disable == "1" or C.unitframes.layout ~= "tukui" then return end
-- update player layout
diff --git a/modules/unlock.lua b/modules/unlock.lua
index 629097d4..59fcd473 100644
--- a/modules/unlock.lua
+++ b/modules/unlock.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("unlock", "vanilla", function ()
+pfUI:RegisterModule("unlock", "vanilla:tbc", function ()
local rawborder, default_border = GetBorderSize()
-- grouped frames
diff --git a/modules/unusable.lua b/modules/unusable.lua
index f51c2b6b..73a9d992 100644
--- a/modules/unusable.lua
+++ b/modules/unusable.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("unusable", "vanilla", function ()
+pfUI:RegisterModule("unusable", "vanilla:tbc", function ()
if not pfUI.bag then return end
if C.appearance.bags.unusable ~= "1" then return end
diff --git a/modules/updatenotify.lua b/modules/updatenotify.lua
index 31aa9cdc..a88730dd 100644
--- a/modules/updatenotify.lua
+++ b/modules/updatenotify.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("updatenotify", "vanilla", function ()
+pfUI:RegisterModule("updatenotify", "vanilla:tbc", function ()
local alreadyshown = false
local localversion = tonumber(pfUI.version.major*10000 + pfUI.version.minor*100 + pfUI.version.fix)
local remoteversion = tonumber(pfUI_init.updateavailable) or 0
diff --git a/modules/xpbar.lua b/modules/xpbar.lua
index 54ca6a7d..7b1ed36f 100644
--- a/modules/xpbar.lua
+++ b/modules/xpbar.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterModule("xpbar", "vanilla", function ()
+pfUI:RegisterModule("xpbar", "vanilla:tbc", function ()
local rawborder, default_border = GetBorderSize()
local parse_faction = SanitizePattern(FACTION_STANDING_INCREASED)
diff --git a/pfUI-tbc.toc b/pfUI-tbc.toc
new file mode 100644
index 00000000..a55f4b82
--- /dev/null
+++ b/pfUI-tbc.toc
@@ -0,0 +1,17 @@
+## Interface: 20400
+## Title: |cff33ffccpf|cffffffffUI
+## Author: Shagu
+## Notes: A complete user interface replacement.
+## Notes-ruRU: Полная замена пользовательского интерфейса.
+## Version: 6.0.0
+## SavedVariables: pfUI_profiles, pfUI_addon_profiles, pfUI_cache
+## SavedVariablesPerCharacter: pfUI_config, pfUI_init, pfUI_playerDB
+
+pfUI.lua
+
+init\env.xml
+init\compat.xml
+init\api.xml
+init\libs.xml
+init\skins.xml
+init\modules.xml
diff --git a/pfUI.lua b/pfUI.lua
index b8229436..606919f8 100644
--- a/pfUI.lua
+++ b/pfUI.lua
@@ -77,9 +77,17 @@ end})
local _, _, _, client = GetBuildInfo()
client = client or 11200
--- set expansion to vanilla
-pfUI.expansion = "vanilla"
-pfUI.client = client
+-- detect client expansion
+if client >= 20000 and client <= 20400 then
+ pfUI.expansion = "tbc"
+ pfUI.client = client
+elseif client >= 30000 and client <= 30300 then
+ pfUI.expansion = "wotlk"
+ pfUI.client = client
+else
+ pfUI.expansion = "vanilla"
+ pfUI.client = client
+end
-- setup pfUI namespace
setmetatable(pfUI.env, {__index = getfenv(0)})
@@ -111,20 +119,34 @@ function pfUI:UpdateFonts()
-- load font configuration
local default, tooltip, unit, unit_name, combat
- if pfUI_config.global.force_region == "1" and GetLocale() == "zhCN" then
+ if pfUI_config.global.force_region == "1" and GetLocale() == "zhCN" and pfUI.expansion == "vanilla" then
-- force locale compatible fonts (zhCN 1.12)
default = "Fonts\\FZXHLJW.TTF"
tooltip = "Fonts\\FZXHLJW.TTF"
combat = "Fonts\\FZXHLJW.TTF"
unit = "Fonts\\FZXHLJW.TTF"
unit_name = "Fonts\\FZXHLJW.TTF"
- elseif pfUI_config.global.force_region == "1" and GetLocale() == "zhTW" then
+ elseif pfUI_config.global.force_region == "1" and GetLocale() == "zhCN" and pfUI.expansion == "tbc" then
+ -- force locale compatible fonts (zhCN 2.4.3)
+ default = "Fonts\\ZYHei.ttf"
+ tooltip = "Fonts\\ZYHei.ttf"
+ combat = "Fonts\\ZYKai_C.ttf"
+ unit = "Fonts\\ZYKai_T.ttf"
+ unit_name = "Fonts\\ZYHei.ttf"
+ elseif pfUI_config.global.force_region == "1" and GetLocale() == "zhTW" and pfUI.expansion == "vanilla" then
-- force locale compatible fonts (zhTW 1.12)
default = "Fonts\\FZXHLJW.ttf"
tooltip = "Fonts\\FZXHLJW.ttf"
combat = "Fonts\\FZXHLJW.ttf"
unit = "Fonts\\FZXHLJW.ttf"
unit_name = "Fonts\\FZXHLJW.ttf"
+ elseif pfUI_config.global.force_region == "1" and GetLocale() == "zhTW" and pfUI.expansion == "tbc" then
+ -- force locale compatible fonts (zhTW 2.4.3)
+ default = "Fonts\\bHEI01B.ttf"
+ tooltip = "Fonts\\bHEI01B.ttf"
+ combat = "Fonts\\bHEI01B.ttf"
+ unit = "Fonts\\bHEI01B.ttf"
+ unit_name = "Fonts\\bHEI01B.ttf"
elseif pfUI_config.global.force_region == "1" and GetLocale() == "koKR" then
-- force locale compatible fonts (koKR)
default = "Fonts\\2002.TTF"
@@ -222,7 +244,7 @@ end
function pfUI:RegisterModule(name, a2, a3)
if pfUI.module[name] then return end
local hasv = type(a2) == "string"
- local func, version = hasv and a3 or a2, hasv and a2 or "vanilla"
+ local func, version = hasv and a3 or a2, hasv and a2 or "vanilla:tbc:wotlk"
-- check for client compatibility
if not strfind(version, pfUI.expansion) then return end
@@ -237,7 +259,7 @@ end
function pfUI:RegisterSkin(name, a2, a3)
if pfUI.skin[name] then return end
local hasv = type(a2) == "string"
- local func, version = hasv and a3 or a2, hasv and a2 or "vanilla"
+ local func, version = hasv and a3 or a2, hasv and a2 or "vanilla:tbc:wotlk"
-- check for client compatibility
if not strfind(version, pfUI.expansion) then return end
diff --git a/pfUI.toc b/pfUI.toc
index 187f4a22..7b448484 100644
--- a/pfUI.toc
+++ b/pfUI.toc
@@ -3,7 +3,7 @@
## Author: Shagu
## Notes: A complete user interface replacement.
## Notes-ruRU: Полная замена пользовательского интерфейса.
-## Version: 5.5.5
+## Version: 6.0.0
## SavedVariables: pfUI_profiles, pfUI_addon_profiles, pfUI_cache
## SavedVariablesPerCharacter: pfUI_config, pfUI_init, pfUI_playerDB
diff --git a/skins/blizzard/auction.lua b/skins/blizzard/auction.lua
index f94c3e3a..0cd64855 100644
--- a/skins/blizzard/auction.lua
+++ b/skins/blizzard/auction.lua
@@ -1,11 +1,16 @@
-pfUI:RegisterSkin("Auctionhouse", "vanilla", function ()
+pfUI:RegisterSkin("Auctionhouse", "vanilla:tbc", function ()
local rawborder, border = GetBorderSize()
local bpad = rawborder > 1 and border - GetPerfectPixel() or GetPerfectPixel()
HookAddonOrVariable("Blizzard_AuctionUI", function()
- SkinArrowButton(BidPrevPageButton, "left", 18)
- SkinArrowButton(BidNextPageButton, "right", 18)
- SkinArrowButton(AuctionsPrevPageButton, "left", 18)
- SkinArrowButton(AuctionsNextPageButton, "right", 18)
+ -- Compatibility
+ if BrowseResetButton then -- tbc
+ SkinButton(BrowseResetButton)
+ else -- vanilla
+ SkinArrowButton(BidPrevPageButton, "left", 18)
+ SkinArrowButton(BidNextPageButton, "right", 18)
+ SkinArrowButton(AuctionsPrevPageButton, "left", 18)
+ SkinArrowButton(AuctionsNextPageButton, "right", 18)
+ end
hooksecurefunc("AuctionFrame_OnShow", function()
AuctionFrame:ClearAllPoints()
diff --git a/skins/blizzard/battlefield.lua b/skins/blizzard/battlefield.lua
index f8dcb283..7ff50008 100644
--- a/skins/blizzard/battlefield.lua
+++ b/skins/blizzard/battlefield.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterSkin("Battlefield", "vanilla", function ()
+pfUI:RegisterSkin("Battlefield", "vanilla:tbc", function ()
local rawborder, border = GetBorderSize()
local bpad = rawborder > 1 and border - GetPerfectPixel() or GetPerfectPixel()
diff --git a/skins/blizzard/battlefield_minimap.lua b/skins/blizzard/battlefield_minimap.lua
index e2eb12b7..e0a21d5e 100644
--- a/skins/blizzard/battlefield_minimap.lua
+++ b/skins/blizzard/battlefield_minimap.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterSkin("Battlefield Minimap", "vanilla", function ()
+pfUI:RegisterSkin("Battlefield Minimap", "vanilla:tbc", function ()
local rawborder, border = GetBorderSize()
HookAddonOrVariable("Blizzard_BattlefieldMinimap", function()
diff --git a/skins/blizzard/character.lua b/skins/blizzard/character.lua
index fea07800..88d4775f 100644
--- a/skins/blizzard/character.lua
+++ b/skins/blizzard/character.lua
@@ -1,13 +1,26 @@
-pfUI:RegisterSkin("Character", "vanilla", function ()
+pfUI:RegisterSkin("Character", "vanilla:tbc", function ()
local rawborder, border = GetBorderSize()
local bpad = rawborder > 1 and border - GetPerfectPixel() or GetPerfectPixel()
- -- Honor Tab
- StripTextures(HonorFrame)
+ -- Compatibility
+ if PlayerTitleDropDown then -- tbc, wotlk
+ -- Character Tab
+ SkinDropDown(PlayerTitleDropDown)
+ PlayerTitleDropDown:SetPoint("TOP", CharacterLevelText, "BOTTOM", 0, -2)
+ PlayerTitleDropDownText:SetPoint("LEFT", PlayerTitleDropDown.backdrop, "LEFT", 6, 2)
+ SkinDropDown(PlayerStatFrameLeftDropDown)
+ SkinDropDown(PlayerStatFrameRightDropDown)
- HonorFrameProgressBar:SetStatusBarTexture(pfUI.media["img:bar"])
- CreateBackdrop(HonorFrameProgressBar)
- HonorFrameProgressBar:SetHeight(24)
+ -- Honor Tab
+ StripTextures(PVPFrame)
+ else -- vanilla
+ -- Honor Tab
+ StripTextures(HonorFrame)
+
+ HonorFrameProgressBar:SetStatusBarTexture(pfUI.media["img:bar"])
+ CreateBackdrop(HonorFrameProgressBar)
+ HonorFrameProgressBar:SetHeight(24)
+ end
local magicResTextureCords = {
{0.21875, 0.78125, 0.25, 0.3203125},
diff --git a/skins/blizzard/dressup.lua b/skins/blizzard/dressup.lua
index cf5c0ffe..d618a36c 100644
--- a/skins/blizzard/dressup.lua
+++ b/skins/blizzard/dressup.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterSkin("Dress Up Frame", "vanilla", function ()
+pfUI:RegisterSkin("Dress Up Frame", "vanilla:tbc", function ()
local rawborder, border = GetBorderSize()
local bpad = rawborder > 1 and border - GetPerfectPixel() or GetPerfectPixel()
diff --git a/skins/blizzard/friends.lua b/skins/blizzard/friends.lua
index 26b21ce3..fe6080e6 100644
--- a/skins/blizzard/friends.lua
+++ b/skins/blizzard/friends.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterSkin("Friends", "vanilla", function ()
+pfUI:RegisterSkin("Friends", "vanilla:tbc", function ()
local rawborder, border = GetBorderSize()
local bpad = rawborder > 1 and border - GetPerfectPixel() or GetPerfectPixel()
local maxtab = pfUI.expansion == "vanilla" and 4 or 5
@@ -336,6 +336,24 @@ pfUI:RegisterSkin("Friends", "vanilla", function ()
GuildInfoCancelButton:ClearAllPoints()
GuildInfoCancelButton:SetPoint("BOTTOMRIGHT", GuildInfoFrame, "BOTTOMRIGHT", -10, 8)
+ if GuildInfoGuildEventButton then -- log button (tbc+)
+ SkinButton(GuildInfoGuildEventButton)
+ GuildInfoGuildEventButton:ClearAllPoints()
+ GuildInfoGuildEventButton:SetPoint("BOTTOM", GuildInfoFrame, "BOTTOM", 0, 8)
+ end
+
+ if GuildEventLogFrame then -- guild log frame (tbc+)
+ StripTextures(GuildEventFrame)
+ CreateBackdrop(GuildEventFrame, nil, true, .75)
+ StripTextures(GuildEventLogFrame)
+ CreateBackdrop(GuildEventLogFrame, nil, true, .75)
+ StripTextures(GuildEventLogScrollFrame)
+ SkinScrollbar(GuildEventLogScrollFrameScrollBar)
+ SkinCloseButton(GuildEventLogCloseButton)
+ GuildEventLogCancelButton:SetPoint("BOTTOMRIGHT", -9, 8)
+ SkinButton(GuildEventLogCancelButton)
+ end
+
-- guild control
StripTextures(GuildControlPopupFrame)
CreateBackdrop(GuildControlPopupFrame, nil, true, .75)
@@ -374,6 +392,46 @@ pfUI:RegisterSkin("Friends", "vanilla", function ()
GuildControlPopupAcceptButton:SetPoint("RIGHT", GuildControlPopupFrameCancelButton, "LEFT", -2*bpad, 0)
end
+ if ChannelFrameVerticalBar then -- Channel Tab (TBC+)
+ StripTextures(ChannelFrameVerticalBar)
+ SkinButton(ChannelFrameNewButton)
+ ChannelFrameNewButton:SetPoint("BOTTOMRIGHT", -15, 82)
+
+ StripTextures(ChannelListScrollFrame)
+ SkinScrollbar(ChannelListScrollFrameScrollBar)
+
+ for i = 1, MAX_DISPLAY_CHANNEL_BUTTONS do
+ StripTextures(_G["ChannelButton"..i])
+ SkinButton(_G["ChannelButton"..i])
+ end
+
+ for i = 1, 22 do
+ StripTextures(_G["ChannelMemberButton"..i])
+ end
+
+ CreateBackdrop(ChannelMemberButton1)
+ ChannelMemberButton1.backdrop:SetPoint("BOTTOMRIGHT", ChannelMemberButton22, "BOTTOMRIGHT", -1, 0)
+
+ StripTextures(ChannelRosterScrollFrame)
+ SkinScrollbar(ChannelRosterScrollFrameScrollBar)
+
+ StripTextures(ChannelFrameDaughterFrame)
+ CreateBackdrop(ChannelFrameDaughterFrame)
+
+ StripTextures(ChannelFrameDaughterFrameChannelName)
+ CreateBackdrop(ChannelFrameDaughterFrameChannelName, nil, true)
+ ChannelFrameDaughterFrameChannelName:SetTextInsets(5,5,5,5)
+
+ StripTextures(ChannelFrameDaughterFrameChannelPassword)
+ CreateBackdrop(ChannelFrameDaughterFrameChannelPassword, nil, true)
+ ChannelFrameDaughterFrameChannelPassword:SetTextInsets(5,5,5,5)
+
+ SkinCloseButton(ChannelFrameDaughterFrameDetailCloseButton)
+
+ SkinButton(ChannelFrameDaughterFrameCancelButton)
+ SkinButton(ChannelFrameDaughterFrameOkayButton)
+ end
+
do -- Raid Tab
StripTextures(RaidInfoFrame)
CreateBackdrop(RaidInfoFrame, nil, true, .75)
diff --git a/skins/blizzard/game_menu.lua b/skins/blizzard/game_menu.lua
index 9e202c7a..9b6d440b 100644
--- a/skins/blizzard/game_menu.lua
+++ b/skins/blizzard/game_menu.lua
@@ -1,10 +1,14 @@
-pfUI:RegisterSkin("Game Menu", "vanilla", function ()
+pfUI:RegisterSkin("Game Menu", "vanilla:tbc", function ()
StripTextures(GameMenuFrame)
CreateBackdrop(GameMenuFrame, nil, true, .75)
CreateBackdropShadow(GameMenuFrame)
GameMenuFrame:SetWidth(GameMenuFrame:GetWidth() - 30)
- GameMenuFrame:SetHeight(GameMenuFrame:GetHeight() + 6)
+ if pfUI.expansion == 'tbc' then
+ GameMenuFrame:SetHeight(GameMenuFrame:GetHeight() + 10)
+ elseif pfUI.expansion == 'vanilla' then
+ GameMenuFrame:SetHeight(GameMenuFrame:GetHeight() + 6)
+ end
local title = GetNoNameObject(GameMenuFrame, "FontString", "ARTWORK", MAIN_MENU)
title:SetTextColor(1,1,1,1)
diff --git a/skins/blizzard/gossipquest.lua b/skins/blizzard/gossipquest.lua
index dec691a6..183347d7 100644
--- a/skins/blizzard/gossipquest.lua
+++ b/skins/blizzard/gossipquest.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterSkin("Gossip and Quest", "vanilla", function ()
+pfUI:RegisterSkin("Gossip and Quest", "vanilla:tbc", function ()
local frames = {'Quest', 'Gossip'}
local panels = {'Greeting', 'Detail', 'Progress', 'Reward'}
local buttons = {
diff --git a/skins/blizzard/guild_registrar.lua b/skins/blizzard/guild_registrar.lua
index 62955cf4..44c1459d 100644
--- a/skins/blizzard/guild_registrar.lua
+++ b/skins/blizzard/guild_registrar.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterSkin("Guild Registrar", "vanilla", function ()
+pfUI:RegisterSkin("Guild Registrar", "vanilla:tbc", function ()
StripTextures(GuildRegistrarFrame)
StripTextures(GuildRegistrarGreetingFrame)
CreateBackdrop(GuildRegistrarFrame, nil, nil, .75)
diff --git a/skins/blizzard/help.lua b/skins/blizzard/help.lua
index b47060b7..54413aa1 100644
--- a/skins/blizzard/help.lua
+++ b/skins/blizzard/help.lua
@@ -1,7 +1,19 @@
-pfUI:RegisterSkin("Help", "vanilla", function ()
+pfUI:RegisterSkin("Help", "vanilla:tbc", function ()
local rawborder, border = GetBorderSize()
local bpad = rawborder > 1 and border - GetPerfectPixel() or GetPerfectPixel()
+ -- not much here for tbc yet
+ if pfUI.client > 11200 then
+ local ticket, background = TicketStatusFrame:GetChildren()
+ CreateBackdrop(background, nil, true, .75)
+ TicketStatusFrame:SetHeight(40)
+ TicketStatusFrame:ClearAllPoints()
+ TicketStatusFrame:SetPoint("TOP", 0, -5)
+
+ UpdateMovable(TicketStatusFrame)
+ return
+ end
+
StripTextures(HelpFrame)
CreateBackdrop(HelpFrame, nil, nil, .75)
CreateBackdropShadow(HelpFrame)
diff --git a/skins/blizzard/inspect.lua b/skins/blizzard/inspect.lua
index cbbc39b4..b81609c3 100644
--- a/skins/blizzard/inspect.lua
+++ b/skins/blizzard/inspect.lua
@@ -20,6 +20,111 @@ local slots = {
"RangedSlot",
}
+pfUI:RegisterSkin("Inspect", "tbc", function ()
+ local rawborder, border = GetBorderSize()
+ local bpad = rawborder > 1 and border - GetPerfectPixel() or GetPerfectPixel()
+
+ HookAddonOrVariable("Blizzard_InspectUI", function()
+ CreateBackdrop(InspectFrame, nil, nil, .75)
+ CreateBackdropShadow(InspectFrame)
+
+ InspectFrame.backdrop:SetPoint("TOPLEFT", 10, -10)
+ InspectFrame.backdrop:SetPoint("BOTTOMRIGHT", -30, 72)
+ InspectFrame:SetHitRectInsets(10,30,10,72)
+ EnableMovable("InspectFrame", "Blizzard_InspectUI", INSPECTFRAME_SUBFRAMES)
+
+ SkinCloseButton(InspectFrameCloseButton, InspectFrame.backdrop, -6, -6)
+
+ InspectFrame:DisableDrawLayer("ARTWORK")
+
+ InspectNameText:ClearAllPoints()
+ InspectNameText:SetPoint("TOP", InspectFrame.backdrop, "TOP", 0, -10)
+ InspectGuildText:Show()
+ InspectGuildText:ClearAllPoints()
+ InspectGuildText:SetPoint("TOP", InspectLevelText, "BOTTOM", 0, -1)
+
+ for i = 1, 3 do
+ local tab = _G["InspectFrameTab"..i]
+ local lastTab = _G["InspectFrameTab"..(i-1)]
+ tab:ClearAllPoints()
+ if lastTab then
+ tab:SetPoint("LEFT", lastTab, "RIGHT", border*2 + 1, 0)
+ else
+ tab:SetPoint("TOPLEFT", InspectFrame.backdrop, "BOTTOMLEFT", bpad, -(border + (border == 1 and 1 or 2)))
+ end
+ SkinTab(tab)
+ end
+
+ do -- Character Tab
+ StripTextures(InspectPaperDollFrame)
+
+ EnableClickRotate(InspectModelFrame)
+ InspectModelRotateLeftButton:Hide()
+ InspectModelRotateRightButton:Hide()
+
+ for _, slot in pairs(slots) do
+ local frame = _G["Inspect"..slot]
+ SkinButton(frame, nil, nil, nil, _G["Inspect"..slot.."IconTexture"], true)
+ end
+
+ hooksecurefunc("InspectPaperDollFrame_OnShow", function()
+ local guild, title = GetGuildInfo(InspectFrame.unit)
+ local text = guild and format(TEXT(GUILD_TITLE_TEMPLATE), title, guild) or ""
+ InspectGuildText:SetText(text)
+ end)
+
+ hooksecurefunc("InspectPaperDollItemSlotButton_Update", function(button)
+ local unit = InspectFrame.unit
+ local link = GetInventoryItemLink(unit, button:GetID())
+ if link then
+ local quality = select(3, GetItemInfo(link))
+ button:SetBackdropBorderColor(GetItemQualityColor(quality))
+ else
+ button:SetBackdropBorderColor(pfUI.cache.er, pfUI.cache.eg, pfUI.cache.eb, pfUI.cache.ea)
+ end
+ end)
+ end
+
+ do -- PVP Tab
+ StripTextures(InspectPVPFrame)
+ end
+
+ do -- Talent Tab
+ StripTextures(InspectTalentFrame)
+ InspectTalentFrameCancelButton:Hide()
+ InspectTalentFrameCloseButton:Hide()
+
+ InspectTalentFrameSpentPoints:ClearAllPoints()
+ InspectTalentFrameSpentPoints:SetPoint("BOTTOMRIGHT", InspectTalentFrame, "BOTTOMRIGHT", 0, 83)
+
+ StripTextures(InspectTalentFrameScrollFrame)
+ SkinScrollbar(InspectTalentFrameScrollFrameScrollBar)
+
+ for i = 1, MAX_NUM_TALENTS do
+ local talent = _G["InspectTalentFrameTalent"..i]
+ if talent then
+ StripTextures(talent)
+ SkinButton(talent, nil, nil, nil, _G["InspectTalentFrameTalent"..i.."IconTexture"])
+
+ _G["InspectTalentFrameTalent"..i.."Rank"]:SetFont(pfUI.font_default, C.global.font_size, "OUTLINE")
+ end
+ end
+
+ for i = 1, 3 do
+ local tab = _G["InspectTalentFrameTab"..i]
+ local lastTab = _G["InspectTalentFrameTab"..(i-1)]
+ tab:ClearAllPoints()
+ if lastTab then
+ tab:SetPoint("LEFT", lastTab, "RIGHT", border*2 + 1, 0)
+ else
+ tab:SetPoint("TOPLEFT", 70, -50)
+ end
+ SkinTab(tab)
+ end
+ end
+ end)
+end)
+
pfUI:RegisterSkin("Inspect", "vanilla", function ()
local rawborder, border = GetBorderSize()
local bpad = rawborder > 1 and border - GetPerfectPixel() or GetPerfectPixel()
diff --git a/skins/blizzard/itemtext.lua b/skins/blizzard/itemtext.lua
index 568901d9..2455919a 100644
--- a/skins/blizzard/itemtext.lua
+++ b/skins/blizzard/itemtext.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterSkin("Books", "vanilla", function ()
+pfUI:RegisterSkin("Books", "vanilla:tbc", function ()
StripTextures(ItemTextFrame)
CreateBackdrop(ItemTextFrame, nil, nil, .75)
CreateBackdropShadow(ItemTextFrame)
diff --git a/skins/blizzard/keybindings.lua b/skins/blizzard/keybindings.lua
index 9b570b88..049aac20 100644
--- a/skins/blizzard/keybindings.lua
+++ b/skins/blizzard/keybindings.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterSkin("KeyBindings", "vanilla", function ()
+pfUI:RegisterSkin("KeyBindings", "vanilla:tbc", function ()
local rawborder, border = GetBorderSize()
local bpad = rawborder > 1 and border - GetPerfectPixel() or GetPerfectPixel()
diff --git a/skins/blizzard/macro.lua b/skins/blizzard/macro.lua
index efe4c582..890ad6bc 100644
--- a/skins/blizzard/macro.lua
+++ b/skins/blizzard/macro.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterSkin("Macro", "vanilla", function ()
+pfUI:RegisterSkin("Macro", "vanilla:tbc", function ()
local rawborder, border = GetBorderSize()
local bpad = rawborder > 1 and border - GetPerfectPixel() or GetPerfectPixel()
diff --git a/skins/blizzard/mail.lua b/skins/blizzard/mail.lua
index 8830e0fe..861c7d1f 100644
--- a/skins/blizzard/mail.lua
+++ b/skins/blizzard/mail.lua
@@ -1,10 +1,53 @@
-pfUI:RegisterSkin("Mailbox", "vanilla", function ()
+pfUI:RegisterSkin("Mailbox", "vanilla:tbc", function ()
local rawborder, border = GetBorderSize()
local bpad = rawborder > 1 and border - GetPerfectPixel() or GetPerfectPixel()
+ -- Compatibility
local StationeryBackgroundLeft, StationeryBackgroundRight
+ if ATTACHMENTS_MAX_SEND then -- tbc
+ do -- SendMailFrame
+ for i = 1, ATTACHMENTS_MAX_SEND do
+ local btn = _G["SendMailAttachment"..i]
+ StripTextures(btn)
+ SkinButton(btn, nil, nil, nil, nil, true)
+ end
- do -- SendMailFrame
+ hooksecurefunc("SendMailFrame_Update", function()
+ for i = 1, ATTACHMENTS_MAX_SEND do
+ local btn = _G["SendMailAttachment"..i]
+ HandleIcon(btn, btn:GetNormalTexture())
+
+ local link = GetSendMailItemLink(i)
+ if link then
+ local r,g,b = GetItemQualityColor(select(3, GetItemInfo(link)))
+ btn:SetBackdropBorderColor(r,g,b,1)
+ else
+ btn:SetBackdropBorderColor(GetStringColor(pfUI_config.appearance.border.color))
+ end
+ end
+ end)
+
+ StationeryBackgroundLeft, StationeryBackgroundRight = SendStationeryBackgroundLeft, SendStationeryBackgroundRight
+ end
+
+ do -- OpenMailFrame
+ for i = 1, ATTACHMENTS_MAX_RECEIVE do
+ SkinButton(_G["OpenMailAttachmentButton"..i], nil, nil, nil, _G["OpenMailAttachmentButton"..i.."IconTexture"], true)
+ end
+
+ hooksecurefunc("InboxFrame_OnClick", function(index)
+ for i=1, ATTACHMENTS_MAX_RECEIVE do
+ local link = GetInboxItemLink(index, i)
+ if not link then return end
+ local r,g,b = GetItemQualityColor(select(3, GetItemInfo(link)))
+ _G["OpenMailAttachmentButton"..i]:SetBackdropBorderColor(r,g,b,1)
+ end
+ end)
+
+ SkinButton(OpenMailReportSpamButton)
+ end
+ else -- vanilla
+ do -- SendMailFrame
local skin = CreateFrame("Frame")
skin:SetScript("OnEvent", function()
this:UnregisterEvent("MAIL_SHOW")
@@ -79,6 +122,7 @@ pfUI:RegisterSkin("Mailbox", "vanilla", function ()
end
end)
end
+ end
StripTextures(MailFrame, true)
CreateBackdrop(MailFrame, nil, nil, .75)
diff --git a/skins/blizzard/merchant.lua b/skins/blizzard/merchant.lua
index 084285cf..ccceba7e 100644
--- a/skins/blizzard/merchant.lua
+++ b/skins/blizzard/merchant.lua
@@ -1,9 +1,21 @@
-pfUI:RegisterSkin("Merchant", "vanilla", function ()
+pfUI:RegisterSkin("Merchant", "vanilla:tbc", function ()
local rawborder, border = GetBorderSize()
local bpad = rawborder > 1 and border - GetPerfectPixel() or GetPerfectPixel()
- MerchantRepairAllButton:ClearAllPoints()
- MerchantRepairAllButton:SetPoint("RIGHT", MerchantBuyBackItemItemButton, "LEFT", -6, 0)
+ -- Compatibility
+ if MerchantGuildBankRepairButton then -- tbc
+ SkinButton(MerchantGuildBankRepairButton, nil, nil, nil, MerchantGuildBankRepairButtonIcon)
+ MerchantGuildBankRepairButtonIcon:SetTexCoord(.59, .82, .06, .54)
+ hooksecurefunc("MerchantFrame_UpdateRepairButtons", function()
+ MerchantGuildBankRepairButton:ClearAllPoints()
+ MerchantGuildBankRepairButton:SetPoint("RIGHT", MerchantBuyBackItemItemButton, "LEFT", -14, 0)
+ MerchantRepairAllButton:ClearAllPoints()
+ MerchantRepairAllButton:SetPoint("RIGHT", MerchantGuildBankRepairButton, "LEFT", -6, 0)
+ end)
+ else -- vanilla
+ MerchantRepairAllButton:ClearAllPoints()
+ MerchantRepairAllButton:SetPoint("RIGHT", MerchantBuyBackItemItemButton, "LEFT", -6, 0)
+ end
StripTextures(MerchantFrame)
CreateBackdrop(MerchantFrame, nil, nil, .75)
diff --git a/skins/blizzard/miscellaneous.lua b/skins/blizzard/miscellaneous.lua
index 2af1e4de..ea67ac3b 100644
--- a/skins/blizzard/miscellaneous.lua
+++ b/skins/blizzard/miscellaneous.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterSkin("Stack Split", "vanilla", function ()
+pfUI:RegisterSkin("Stack Split", "vanilla:tbc", function ()
StripTextures(StackSplitFrame)
CreateBackdrop(StackSplitFrame, nil, nil, .75)
CreateBackdropShadow(StackSplitFrame)
@@ -7,7 +7,7 @@ pfUI:RegisterSkin("Stack Split", "vanilla", function ()
SkinButton(StackSplitCancelButton)
end)
-pfUI:RegisterSkin("Coin Pickup", "vanilla", function ()
+pfUI:RegisterSkin("Coin Pickup", "vanilla:tbc", function ()
StripTextures(CoinPickupFrame)
CreateBackdrop(CoinPickupFrame, nil, nil, .75)
CreateBackdropShadow(CoinPickupFrame)
@@ -16,7 +16,7 @@ pfUI:RegisterSkin("Coin Pickup", "vanilla", function ()
SkinButton(CoinPickupCancelButton)
end)
-pfUI:RegisterSkin("Color Picker", "vanilla", function ()
+pfUI:RegisterSkin("Color Picker", "vanilla:tbc", function ()
CreateBackdrop(ColorPickerFrame)
CreateBackdropShadow(ColorPickerFrame)
@@ -32,7 +32,7 @@ pfUI:RegisterSkin("Color Picker", "vanilla", function ()
SkinSlider(OpacitySliderFrame)
end)
-pfUI:RegisterSkin("Opacity", "vanilla", function ()
+pfUI:RegisterSkin("Opacity", "vanilla:tbc", function ()
CreateBackdrop(OpacityFrame, nil, true, .75)
CreateBackdropShadow(OpacityFrame)
@@ -41,7 +41,7 @@ pfUI:RegisterSkin("Opacity", "vanilla", function ()
OpacityFrameSlider:SetPoint("CENTER", 0, 0)
end)
-pfUI:RegisterSkin("Tutorial", "vanilla", function ()
+pfUI:RegisterSkin("Tutorial", "vanilla:tbc", function ()
CreateBackdrop(TutorialFrame, nil, true, .75)
CreateBackdropShadow(TutorialFrame)
@@ -49,7 +49,7 @@ pfUI:RegisterSkin("Tutorial", "vanilla", function ()
SkinButton(TutorialFrameOkayButton)
end)
-pfUI:RegisterSkin("Quest Timer", "vanilla", function ()
+pfUI:RegisterSkin("Quest Timer", "vanilla:tbc", function ()
CreateBackdrop(QuestTimerFrame, nil, nil, .75)
CreateBackdropShadow(QuestTimerFrame)
UpdateMovable(QuestTimerFrame, true)
diff --git a/skins/blizzard/options-sound.lua b/skins/blizzard/options-sound.lua
index 257d4023..341486ab 100644
--- a/skins/blizzard/options-sound.lua
+++ b/skins/blizzard/options-sound.lua
@@ -1,18 +1,40 @@
-pfUI:RegisterSkin("Options - Sound", "vanilla", function ()
+pfUI:RegisterSkin("Options - Sound", "vanilla:tbc", function ()
local rawborder, border = GetBorderSize()
local bpad = rawborder > 1 and border - GetPerfectPixel() or GetPerfectPixel()
- local SoundOptionsFrameHeaderText = GetNoNameObject(SoundOptionsFrame, "FontString", "ARTWORK", SOUNDOPTIONS_MENU)
- local NUM_CHECKBOXES = 8
- local NUM_SLIDERS = 4
+ -- Compatibility
+ local SoundOptionsFrameHeaderText, NUM_CHECKBOXES, NUM_SLIDERS
+ if SOUND_OPTIONS then -- tbc
+ SoundOptionsFrameHeaderText = GetNoNameObject(SoundOptionsFrame, "FontString", "BACKGROUND", SOUND_OPTIONS)
+ NUM_CHECKBOXES = 11
+ NUM_SLIDERS = 6
- SoundOptionsFrameOkay:ClearAllPoints()
- SoundOptionsFrameOkay:SetPoint("RIGHT", SoundOptionsFrameCancel, "LEFT", -2*bpad, 0)
- SoundOptionsFrameSlider1:ClearAllPoints()
- SoundOptionsFrameSlider1:SetPoint("TOPRIGHT", SoundOptionsFrame, "TOPRIGHT", -18, -43)
- for i=2, NUM_SLIDERS do
- _G["SoundOptionsFrameSlider"..i]:ClearAllPoints()
- _G["SoundOptionsFrameSlider"..i]:SetPoint("TOP", _G["SoundOptionsFrameSlider"..i-1], "BOTTOM", 0, -30)
+ StripTextures(AudioOptionsFrame)
+ CreateBackdrop(SoundOptionsFramePlayback, nil, true, .75)
+ CreateBackdrop(SoundOptionsFrameHardware, nil, true, .75)
+ CreateBackdrop(SoundOptionsFrameVolume, nil, true, .75)
+
+ SkinDropDown(SoundOptionsOutputDropDown)
+
+ SoundOptionsFrameDefaults:ClearAllPoints()
+ SoundOptionsFrameDefaults:SetPoint("TOPLEFT", SoundOptionsFramePlayback, "BOTTOMLEFT", 0, -10)
+ SoundOptionsFrameCancel:ClearAllPoints()
+ SoundOptionsFrameCancel:SetPoint("TOPRIGHT", SoundOptionsFrameVolume, "BOTTOMRIGHT", 0, -10)
+ SoundOptionsFrameOkay:ClearAllPoints()
+ SoundOptionsFrameOkay:SetPoint("RIGHT", SoundOptionsFrameCancel, "LEFT", -2*bpad, 0)
+ else -- vanilla
+ SoundOptionsFrameHeaderText = GetNoNameObject(SoundOptionsFrame, "FontString", "ARTWORK", SOUNDOPTIONS_MENU)
+ NUM_CHECKBOXES = 8
+ NUM_SLIDERS = 4
+
+ SoundOptionsFrameOkay:ClearAllPoints()
+ SoundOptionsFrameOkay:SetPoint("RIGHT", SoundOptionsFrameCancel, "LEFT", -2*bpad, 0)
+ SoundOptionsFrameSlider1:ClearAllPoints()
+ SoundOptionsFrameSlider1:SetPoint("TOPRIGHT", SoundOptionsFrame, "TOPRIGHT", -18, -43)
+ for i=2, NUM_SLIDERS do
+ _G["SoundOptionsFrameSlider"..i]:ClearAllPoints()
+ _G["SoundOptionsFrameSlider"..i]:SetPoint("TOP", _G["SoundOptionsFrameSlider"..i-1], "BOTTOM", 0, -30)
+ end
end
StripTextures(SoundOptionsFrame)
diff --git a/skins/blizzard/options-video.lua b/skins/blizzard/options-video.lua
index 853bdcb0..70c7e325 100644
--- a/skins/blizzard/options-video.lua
+++ b/skins/blizzard/options-video.lua
@@ -1,19 +1,45 @@
-pfUI:RegisterSkin("Options - Video", "vanilla", function ()
+pfUI:RegisterSkin("Options - Video", "vanilla:tbc", function ()
local rawborder, border = GetBorderSize()
local bpad = rawborder > 1 and border - GetPerfectPixel() or GetPerfectPixel()
- local MAX_SLIDERS = 9
- local MAX_CHECKBOXES = 18
+ -- Compatibility
+ local MAX_SLIDERS, MAX_CHECKBOXES
+ if OptionsFrameSlider10 then -- tbc
+ MAX_SLIDERS = 11
+ MAX_CHECKBOXES = 19
- for i=1, MAX_SLIDERS do
- local slider = _G["OptionsFrameSlider"..i]
- local shift = 0
- if i == 1 or i == 6 then shift = 4
- elseif i == 4 or i == 8 then shift = 10
+ for i=1, MAX_SLIDERS do
+ local slider = _G["OptionsFrameSlider"..i]
+ local shift = 0
+ if i == 4 or i == 5 or i == 7 or i == 8 or i == 10 or i == 11 then shift = 10 end
+ local point, anchor, anchorPoint, x, y = slider:GetPoint()
+ slider:ClearAllPoints()
+ slider:SetPoint(point, anchor, anchorPoint, x, y - shift)
+ end
+
+ hooksecurefunc("OptionsFrame_Load", function()
+ OptionsFramePixelShaders:SetWidth(230)
+ OptionsFrameMiscellaneous:ClearAllPoints()
+ OptionsFrameMiscellaneous:SetPoint("LEFT", OptionsFramePixelShaders, "RIGHT", 6, 0)
+ end)
+ OptionsFrameDefaults:ClearAllPoints()
+ OptionsFrameDefaults:SetPoint("TOPLEFT", OptionsFramePixelShaders, "BOTTOMLEFT", 0, -10)
+ OptionsFrameCancel:ClearAllPoints()
+ OptionsFrameCancel:SetPoint("TOPRIGHT", OptionsFrameMiscellaneous, "BOTTOMRIGHT", 0, -10)
+ else -- vanilla
+ MAX_SLIDERS = 9
+ MAX_CHECKBOXES = 18
+
+ for i=1, MAX_SLIDERS do
+ local slider = _G["OptionsFrameSlider"..i]
+ local shift = 0
+ if i == 1 or i == 6 then shift = 4
+ elseif i == 4 or i == 8 then shift = 10
+ end
+ local point, anchor, anchorPoint, x, y = slider:GetPoint()
+ slider:ClearAllPoints()
+ slider:SetPoint(point, anchor, anchorPoint, x, y - shift)
end
- local point, anchor, anchorPoint, x, y = slider:GetPoint()
- slider:ClearAllPoints()
- slider:SetPoint(point, anchor, anchorPoint, x, y - shift)
end
CreateBackdrop(OptionsFrame, nil, nil, .75)
diff --git a/skins/blizzard/popup_dialogs.lua b/skins/blizzard/popup_dialogs.lua
index fc3aed02..d795a7bf 100644
--- a/skins/blizzard/popup_dialogs.lua
+++ b/skins/blizzard/popup_dialogs.lua
@@ -1,5 +1,12 @@
-pfUI:RegisterSkin("Popup Dialogs", "vanilla", function ()
+pfUI:RegisterSkin("Popup Dialogs", "vanilla:tbc", function ()
for i = 1, STATICPOPUP_NUMDIALOGS do
+ -- Compatibility
+ local money = _G["StaticPopup"..i.."MoneyInputFrame"]
+ if money then -- tbc
+ SkinMoneyInputFrame(money)
+ end
+
+
local dialog = _G["StaticPopup"..i]
CreateBackdrop(dialog, nil, true, .75)
CreateBackdropShadow(dialog)
diff --git a/skins/blizzard/professions.lua b/skins/blizzard/professions.lua
index bbd266d1..eab6d31e 100644
--- a/skins/blizzard/professions.lua
+++ b/skins/blizzard/professions.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterSkin("Profession", "vanilla", function ()
+pfUI:RegisterSkin("Profession", "vanilla:tbc", function ()
local rawborder, border = GetBorderSize()
local bpad = rawborder > 1 and border - GetPerfectPixel() or GetPerfectPixel()
@@ -219,7 +219,37 @@ pfUI:RegisterSkin("Profession", "vanilla", function ()
end)
end
- _G[displayed] = 23
+ -- Compatibility
+ if search then -- tbc
+ _G[displayed] = 21
+ scrollframe:SetHeight(338)
+
+ local rank = _G[name.."RankFrameSkillRank"]
+ rank:ClearAllPoints()
+ rank:SetPoint("CENTER", rankbar, "CENTER", 0, 0)
+
+ local available = _G[frame:GetName().."AvailableFilterCheckButton"]
+ SkinCheckbox(available)
+ available:ClearAllPoints()
+ available:SetPoint("TOPLEFT", scrollframe.backdrop, "BOTTOMLEFT", -4, -5)
+
+ search:DisableDrawLayer("BACKGROUND")
+ CreateBackdrop(search, nil, nil, 1)
+ search.backdrop:SetAllPoints(search)
+ search:SetTextInsets(5, 5, 5, 5)
+ search:SetHeight(22)
+ search:ClearAllPoints()
+ search:SetPoint("TOPRIGHT", scrollframe.backdrop, "BOTTOMRIGHT", 0, -5)
+
+ local craft_filter = CraftFrameFilterDropDown
+ if craft_filter then
+ SkinDropDown(craft_filter)
+ craft_filter:ClearAllPoints()
+ craft_filter:SetPoint("BOTTOMRIGHT", scrollframe.backdrop, "TOPRIGHT", 15, 0)
+ end
+ else -- vanilla
+ _G[displayed] = 23
+ end
-- build remaining tradeskills
for i = 9, _G[displayed] do
local button = _G[template..i] or CreateFrame("Button", template..i, frame, template.."ButtonTemplate")
diff --git a/skins/blizzard/questlog.lua b/skins/blizzard/questlog.lua
index 748b2fb9..23b4d0e8 100644
--- a/skins/blizzard/questlog.lua
+++ b/skins/blizzard/questlog.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterSkin("Quest Log", "vanilla", function ()
+pfUI:RegisterSkin("Quest Log", "vanilla:tbc", function ()
local rawborder, border = GetBorderSize()
local bpad = rawborder > 1 and border - GetPerfectPixel() or GetPerfectPixel()
@@ -6,10 +6,23 @@ pfUI:RegisterSkin("Quest Log", "vanilla", function ()
_G.MAX_WATCHABLE_QUESTS = 20 -- TODO
do -- quest log frame
- local QUEST_COUNT = QuestLogQuestCount
+ -- Compatibility
+ local QUEST_COUNT
+ if QuestLogCount then -- tbc
+ QUEST_COUNT = QuestLogCount
- QUEST_COUNT:ClearAllPoints()
- QUEST_COUNT:SetPoint("TOPRIGHT", -10, -30)
+ StripTextures(QUEST_COUNT)
+ QUEST_COUNT:ClearAllPoints()
+ hooksecurefunc("QuestLogUpdateQuestCount", function(numQuests)
+ QUEST_COUNT:ClearAllPoints()
+ QUEST_COUNT:SetPoint("BOTTOMRIGHT", QuestLogFrame, "TOPRIGHT", 0, -50)
+ end)
+ else -- vanilla
+ QUEST_COUNT = QuestLogQuestCount
+
+ QUEST_COUNT:ClearAllPoints()
+ QUEST_COUNT:SetPoint("TOPRIGHT", -10, -30)
+ end
hooksecurefunc("QuestLog_OnShow", function()
QuestLogFrame:ClearAllPoints()
diff --git a/skins/blizzard/readycheck.lua b/skins/blizzard/readycheck.lua
index 0d21ec89..51ec176b 100644
--- a/skins/blizzard/readycheck.lua
+++ b/skins/blizzard/readycheck.lua
@@ -1,6 +1,12 @@
-pfUI:RegisterSkin("Readycheck", "vanilla", function ()
+pfUI:RegisterSkin("Readycheck", "vanilla:tbc", function ()
HookAddonOrVariable("Blizzard_RaidUI", function()
- local update_func = "ReadyCheck_OnUpdate"
+ -- Compatibility
+ local update_func
+ if ReadyCheckFrame_OnUpdate then -- tbc
+ update_func = "ReadyCheckFrame_OnUpdate"
+ else -- vanilla
+ update_func = "ReadyCheck_OnUpdate"
+ end
StripTextures(ReadyCheckFrame, true)
CreateBackdrop(ReadyCheckFrame, nil, nil, .75)
diff --git a/skins/blizzard/spellbook.lua b/skins/blizzard/spellbook.lua
index db5bf427..e28383c3 100644
--- a/skins/blizzard/spellbook.lua
+++ b/skins/blizzard/spellbook.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterSkin("Spellbook", "vanilla", function ()
+pfUI:RegisterSkin("Spellbook", "vanilla:tbc", function ()
local rawborder, border = GetBorderSize()
local bpad = rawborder > 1 and border - GetPerfectPixel() or GetPerfectPixel()
diff --git a/skins/blizzard/stable.lua b/skins/blizzard/stable.lua
index fdf6f7f1..9e6e7a52 100644
--- a/skins/blizzard/stable.lua
+++ b/skins/blizzard/stable.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterSkin("Pet Stable Master", "vanilla", function ()
+pfUI:RegisterSkin("Pet Stable Master", "vanilla:tbc", function ()
StripTextures(PetStableFrame)
CreateBackdrop(PetStableFrame, nil, nil, .75)
CreateBackdropShadow(PetStableFrame)
diff --git a/skins/blizzard/tabard.lua b/skins/blizzard/tabard.lua
index 46efde05..e8e48c21 100644
--- a/skins/blizzard/tabard.lua
+++ b/skins/blizzard/tabard.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterSkin("Guild Tabard", "vanilla", function ()
+pfUI:RegisterSkin("Guild Tabard", "vanilla:tbc", function ()
local rawborder, border = GetBorderSize()
local bpad = rawborder > 1 and border - GetPerfectPixel() or GetPerfectPixel()
diff --git a/skins/blizzard/talents.lua b/skins/blizzard/talents.lua
index 11c9370a..f26e5a4c 100644
--- a/skins/blizzard/talents.lua
+++ b/skins/blizzard/talents.lua
@@ -1,10 +1,16 @@
-pfUI:RegisterSkin("Talents", "vanilla", function ()
+pfUI:RegisterSkin("Talents", "vanilla:tbc", function ()
local rawborder, border = GetBorderSize()
local bpad = rawborder > 1 and border - GetPerfectPixel() or GetPerfectPixel()
HookAddonOrVariable("Blizzard_TalentUI", function()
- local TALENT_FRAME = _G.TalentFrame
- local TALENT_FRAME_NAME = TALENT_FRAME:GetName()
+ -- Compatibility
+ local TALENT_FRAME, TALENT_FRAME_NAME
+ if PlayerTalentFrame then -- tbc
+ TALENT_FRAME = _G.PlayerTalentFrame
+ else -- vanilla
+ TALENT_FRAME = _G.TalentFrame
+ end
+ TALENT_FRAME_NAME = TALENT_FRAME:GetName()
StripTextures(TALENT_FRAME)
diff --git a/skins/blizzard/taxi.lua b/skins/blizzard/taxi.lua
index 79a7bc36..fac03ade 100644
--- a/skins/blizzard/taxi.lua
+++ b/skins/blizzard/taxi.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterSkin("Flightmaster", "vanilla", function ()
+pfUI:RegisterSkin("Flightmaster", "vanilla:tbc", function ()
StripTextures(TaxiFrame)
CreateBackdrop(TaxiFrame, nil, nil, .75)
CreateBackdropShadow(TaxiFrame)
diff --git a/skins/blizzard/tooltips.lua b/skins/blizzard/tooltips.lua
index d1195ee8..c050c541 100644
--- a/skins/blizzard/tooltips.lua
+++ b/skins/blizzard/tooltips.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterSkin("Tooltips", "vanilla", function ()
+pfUI:RegisterSkin("Tooltips", "vanilla:tbc", function ()
local rawborder, border = GetBorderSize()
local alpha = tonumber(C.tooltip.alpha)
diff --git a/skins/blizzard/trade.lua b/skins/blizzard/trade.lua
index fe0a9e4c..fd6237d6 100644
--- a/skins/blizzard/trade.lua
+++ b/skins/blizzard/trade.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterSkin("Trade", "vanilla", function ()
+pfUI:RegisterSkin("Trade", "vanilla:tbc", function ()
local rawborder, border = GetBorderSize()
local bpad = rawborder > 1 and border - GetPerfectPixel() or GetPerfectPixel()
diff --git a/skins/blizzard/trainer.lua b/skins/blizzard/trainer.lua
index e752f7bb..62df6005 100644
--- a/skins/blizzard/trainer.lua
+++ b/skins/blizzard/trainer.lua
@@ -1,4 +1,4 @@
-pfUI:RegisterSkin("Trainer", "vanilla", function ()
+pfUI:RegisterSkin("Trainer", "vanilla:tbc", function ()
local rawborder, border = GetBorderSize()
local bpad = rawborder > 1 and border - GetPerfectPixel() or GetPerfectPixel()
From 14ae74f1c384a9c7764e19dc005360ad995dfd3b Mon Sep 17 00:00:00 2001
From: Meow <30401521+me0wg4ming@users.noreply.github.com>
Date: Mon, 5 Jan 2026 09:09:56 +0100
Subject: [PATCH 19/40] Update README.md
---
README.md | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/README.md b/README.md
index eedf2846..acf4ac1f 100644
--- a/README.md
+++ b/README.md
@@ -308,5 +308,4 @@ Same as original pfUI - free to use and modify.
**Version:** 6.0.0
**Release Date:** January 5, 2026
-**Compatibility:** World of Warcraft 1.12.1 (Vanilla) & 2.4.3 (TBC)
-**Status:** Stable & Production-Ready
+**Compatibility:** World of Warcraft 1.12.1 (Vanilla)
From 5b9730eeb845df0704c9691ea633a8d1c3bfd0b4 Mon Sep 17 00:00:00 2001
From: Meow <30401521+me0wg4ming@users.noreply.github.com>
Date: Mon, 5 Jan 2026 09:10:38 +0100
Subject: [PATCH 20/40] Update version badge link in README.md
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index acf4ac1f..bc141d31 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
# pfUI
-[](https://github.com/shagu/pfUI)
+[](https://github.com/me0wg4ming/pfUI#)
[](#)
[](#)
[](https://github.com/balakethelock/SuperWoW)
From af0cd5ea7df2ec89424642709995af1e84312c9e Mon Sep 17 00:00:00 2001
From: Meow <30401521+me0wg4ming@users.noreply.github.com>
Date: Mon, 5 Jan 2026 09:16:27 +0100
Subject: [PATCH 21/40] readme update
readme update
---
README.md | 25 ++++++++++++++++++-------
1 file changed, 18 insertions(+), 7 deletions(-)
diff --git a/README.md b/README.md
index bc141d31..dd7c52bb 100644
--- a/README.md
+++ b/README.md
@@ -1,9 +1,11 @@
# pfUI
-[](https://github.com/me0wg4ming/pfUI#)
+[](https://github.com/me0wg4ming/pfUI)
[](#)
[](#)
[](https://github.com/balakethelock/SuperWoW)
+[](https://gitea.com/avitasia/nampower)
+[](https://codeberg.org/konaka/UnitXP_SP3)
An AddOn for World of Warcraft: Vanilla (1.12.1) and The Burning Crusade (2.4.3), which aims to be a full replacement for the original interface. The design is inspired by several screenshots I've seen from TukUI, ElvUI and others. This addon delivers modern features and a minimalistic style that's easy to use right from the start. It is entirely written from scratch without any inclusion of third-party addons or libraries.
@@ -60,7 +62,7 @@ This is **not** an addon-pack like [ShaguUI](http://shagu.org/ShaguUI/), however
- Behind Indicator on target frame
- OS Notifications for combat events
- Distance-based features
- - Requires [UnitXP_SP3 DLL](https://github.com/allfoxwy/UnitXP_SP3)
+ - Requires [UnitXP_SP3 DLL](https://codeberg.org/konaka/UnitXP_SP3)
- ✅ **bgscore.lua** - Battleground Score frame positioning:
- Movable BG score frame
@@ -145,6 +147,13 @@ All TBC-specific features remain intact:
---
+## Screenshots
+
+
+
+
+
+
## Installation (Vanilla)
1. Download **[Latest Version](https://github.com/shagu/pfUI/archive/master.zip)**
2. Unpack the Zip file
@@ -182,7 +191,7 @@ Provides:
- Enhanced cast information
### UnitXP_SP3
-**Repository:** [https://github.com/allfoxwy/UnitXP_SP3](https://github.com/allfoxwy/UnitXP_SP3)
+**Repository:** [https://codeberg.org/konaka/UnitXP_SP3](https://codeberg.org/konaka/UnitXP_SP3)
Provides:
- Line of Sight detection
@@ -292,10 +301,11 @@ Most probably, yes.
## 🤝 Credits & Acknowledgments
-- **Shagu** - Original pfUI creator and maintainer
+- **Shagu** - Original pfUI creator ([https://github.com/shagu/pfUI](https://github.com/shagu/pfUI))
+- **me0wg4ming** - pfUI fork maintainer and enhancements
- **SuperWoW Team** - SuperWoW framework development
-- **Nampower Team** - Nampower DLL development
-- **UnitXP Team** - UnitXP_SP3 DLL development
+- **avitasia** - Nampower DLL development
+- **konaka** - UnitXP_SP3 DLL development
- **Community** - Bug reports, feature suggestions, and testing
---
@@ -308,4 +318,5 @@ Same as original pfUI - free to use and modify.
**Version:** 6.0.0
**Release Date:** January 5, 2026
-**Compatibility:** World of Warcraft 1.12.1 (Vanilla)
+**Compatibility:** World of Warcraft 1.12.1 (Vanilla) & 2.4.3 (TBC)
+**Status:** Stable & Production-Ready
From 1f08a72b16e239f0e692171da24ed487bf8dffdd Mon Sep 17 00:00:00 2001
From: Meow <30401521+me0wg4ming@users.noreply.github.com>
Date: Mon, 5 Jan 2026 09:19:01 +0100
Subject: [PATCH 22/40] readme update
readme update
---
README.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/README.md b/README.md
index dd7c52bb..4a38c507 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,7 @@
[](https://github.com/me0wg4ming/pfUI)
[](#)
-[](#)
+[](https://github.com/shagu/pfUI/)
[](https://github.com/balakethelock/SuperWoW)
[](https://gitea.com/avitasia/nampower)
[](https://codeberg.org/konaka/UnitXP_SP3)
@@ -318,5 +318,5 @@ Same as original pfUI - free to use and modify.
**Version:** 6.0.0
**Release Date:** January 5, 2026
-**Compatibility:** World of Warcraft 1.12.1 (Vanilla) & 2.4.3 (TBC)
+**Compatibility:** World of Warcraft 1.12.1 (Vanilla)
**Status:** Stable & Production-Ready
From 0b1f93e25ef42cb038b5a01eed915247c374a3c7 Mon Sep 17 00:00:00 2001
From: Meow <30401521+me0wg4ming@users.noreply.github.com>
Date: Mon, 5 Jan 2026 09:21:09 +0100
Subject: [PATCH 23/40] readme update
readme update
---
README.md | 8 --------
1 file changed, 8 deletions(-)
diff --git a/README.md b/README.md
index 4a38c507..12495cc8 100644
--- a/README.md
+++ b/README.md
@@ -7,14 +7,6 @@
[](https://gitea.com/avitasia/nampower)
[](https://codeberg.org/konaka/UnitXP_SP3)
-An AddOn for World of Warcraft: Vanilla (1.12.1) and The Burning Crusade (2.4.3), which aims to be a full replacement for the original interface. The design is inspired by several screenshots I've seen from TukUI, ElvUI and others. This addon delivers modern features and a minimalistic style that's easy to use right from the start. It is entirely written from scratch without any inclusion of third-party addons or libraries.
-
-This is **not** an addon-pack like [ShaguUI](http://shagu.org/ShaguUI/), however, there is support for external addons like MobHealth3, DPSMate and others, but they will never be shipped within the package.
-
-**Please do not re-upload or distribute outdated versions of this project. However, you are more than welcome to fork or link to the official github page.**
-
----
-
## What's New in Version 6.0.0 (January 5, 2026)
### 🚀 Major Performance Improvements
From 55e0b6e8ae863298b85b088c39214acdb8501177 Mon Sep 17 00:00:00 2001
From: Meow <30401521+me0wg4ming@users.noreply.github.com>
Date: Mon, 5 Jan 2026 09:22:35 +0100
Subject: [PATCH 24/40] more readme updates
removed non-working jpg`s
---
README.md | 7 -------
1 file changed, 7 deletions(-)
diff --git a/README.md b/README.md
index 12495cc8..88938139 100644
--- a/README.md
+++ b/README.md
@@ -139,13 +139,6 @@ All TBC-specific features remain intact:
---
-## Screenshots
-
-
-
-
-
-
## Installation (Vanilla)
1. Download **[Latest Version](https://github.com/shagu/pfUI/archive/master.zip)**
2. Unpack the Zip file
From aa645aed9fa279103cea7bd37472e14bfea7064a Mon Sep 17 00:00:00 2001
From: Meow <30401521+me0wg4ming@users.noreply.github.com>
Date: Mon, 5 Jan 2026 09:23:47 +0100
Subject: [PATCH 25/40] wim link change
wim link change
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 88938139..44420853 100644
--- a/README.md
+++ b/README.md
@@ -216,7 +216,7 @@ pfUI supports and contains language specific code for the following gameclients.
## Recommended Addons
* [pfQuest](https://shagu.org/pfQuest) A simple database and quest helper
-* [WIM](http://addons.us.to/addon/wim), [WIM (continued)](https://github.com/shirsig/WIM) Give whispers an instant messenger feel
+* [WIM](http://addons.us.to/addon/wim), [WIM (continued)](https://github.com/me0wg4ming/WIM/) Give whispers an instant messenger feel
## Plugins
* [pfUI-eliteoverlay](https://shagu.org/pfUI-eliteoverlay) Add elite dragons to unitframes
From d83b90f55a734ec5dc2f957ceccdf4d382cfb3c3 Mon Sep 17 00:00:00 2001
From: Meow <30401521+me0wg4ming@users.noreply.github.com>
Date: Mon, 5 Jan 2026 09:25:47 +0100
Subject: [PATCH 26/40] deletes dead links
deletes dead links
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 44420853..ad11d742 100644
--- a/README.md
+++ b/README.md
@@ -216,7 +216,7 @@ pfUI supports and contains language specific code for the following gameclients.
## Recommended Addons
* [pfQuest](https://shagu.org/pfQuest) A simple database and quest helper
-* [WIM](http://addons.us.to/addon/wim), [WIM (continued)](https://github.com/me0wg4ming/WIM/) Give whispers an instant messenger feel
+* [WIM (continued)](https://github.com/me0wg4ming/WIM/) Give whispers an instant messenger feel
## Plugins
* [pfUI-eliteoverlay](https://shagu.org/pfUI-eliteoverlay) Add elite dragons to unitframes
From d24115623b1e9752eaaa40159a013af3304abcb4 Mon Sep 17 00:00:00 2001
From: Meow <30401521+me0wg4ming@users.noreply.github.com>
Date: Mon, 5 Jan 2026 09:33:06 +0100
Subject: [PATCH 27/40] readme update
readme update
---
README.md | 48 +++++++++++++++++++++++-------------------------
1 file changed, 23 insertions(+), 25 deletions(-)
diff --git a/README.md b/README.md
index ad11d742..1c6da861 100644
--- a/README.md
+++ b/README.md
@@ -1,12 +1,19 @@
-# pfUI
+# pfUI - Turtle WoW Edition
[](https://github.com/me0wg4ming/pfUI)
-[](#)
-[](https://github.com/shagu/pfUI/)
+[](https://turtle-wow.org/)
[](https://github.com/balakethelock/SuperWoW)
[](https://gitea.com/avitasia/nampower)
[](https://codeberg.org/konaka/UnitXP_SP3)
+**A pfUI fork specifically optimized for [Turtle WoW](https://turtle-wow.org/) with full SuperWoW, Nampower, and UnitXP_SP3 DLL integration.**
+
+This version includes significant performance improvements, DLL-enhanced features, and TBC spell indicators that work with Turtle WoW's expanded spell library.
+
+> **Looking for TBC support?** Visit the original pfUI by Shagu: [https://github.com/shagu/pfUI](https://github.com/shagu/pfUI)
+
+---
+
## What's New in Version 6.0.0 (January 5, 2026)
### 🚀 Major Performance Improvements
@@ -122,9 +129,9 @@ All new features are configurable via `/pfui`:
- ✅ **Unitmap Race Condition** - Fixed HP/Mana not updating when raid members swap positions
- ✅ **Friendly Nameplate Color** - Fixed friendly players using NPC color instead of player color
-### 🔄 TBC Compatibility Preserved
+### 🐢 Turtle WoW TBC Spell Indicators
-All TBC-specific features remain intact:
+Turtle WoW includes TBC spells in the Vanilla client. This version includes all TBC buff indicators:
- ✅ Commanding Shout indicator
- ✅ Misdirection indicator
- ✅ Earth Shield indicator
@@ -134,28 +141,21 @@ All TBC-specific features remain intact:
**Version:** 6.0.0
**Release Date:** January 5, 2026
-**Compatibility:** World of Warcraft 1.12.1 (Vanilla) & 2.4.3 (TBC)
+**Compatibility:** Turtle WoW 1.18.0
**Optional DLLs:** SuperWoW, Nampower, UnitXP_SP3 (enhanced features when available)
---
-## Installation (Vanilla)
-1. Download **[Latest Version](https://github.com/shagu/pfUI/archive/master.zip)**
+## Installation
+1. Download **[Latest Version](https://github.com/me0wg4ming/pfUI/archive/master.zip)**
2. Unpack the Zip file
3. Rename the folder "pfUI-master" to "pfUI"
4. Copy "pfUI" into Wow-Directory\Interface\AddOns
5. Restart Wow
-## Installation (The Burning Crusade)
-1. Download **[Latest Version](https://github.com/shagu/pfUI/archive/master.zip)**
-2. Unpack the Zip file
-3. Rename the folder "pfUI-master" to "pfUI-tbc"
-4. Copy "pfUI-tbc" into Wow-Directory\Interface\AddOns
-5. Restart Wow
-
## Optional DLL Enhancements
-pfUI 6.0.0 includes optional integrations with client-side DLLs for enhanced functionality:
+pfUI 6.0.0 includes optional integrations with client-side DLLs for enhanced functionality. These DLLs are fully supported on Turtle WoW:
### SuperWoW
**Repository:** [https://github.com/balakethelock/SuperWoW](https://github.com/balakethelock/SuperWoW)
@@ -234,14 +234,14 @@ big fan of creating configuration UI's, especially not via the Wow-API
You can donate via [GitHub](https://github.com/sponsors/shagu) or [Ko-fi](https://ko-fi.com/shagu)
**How do I report a Bug?**
-Please provide as much information as possible in the [Bugtracker](https://github.com/shagu/pfUI/issues).
+Please provide as much information as possible in the [Bugtracker](https://github.com/me0wg4ming/pfUI/issues).
If there is an error message, provide the full content of it. Just telling that "there is an error" won't help any of us.
Please consider adding additional information such as: since when did you got the error,
does it still happen using a clean configuration, what other addons are loaded and which version you're running.
When playing with a non-english client, the language might be relevant too. If possible, explain how people can reproduce the issue.
**How can I contribute?**
-Report errors and issues in the [Bugtracker](https://github.com/shagu/pfUI/issues).
+Report errors and issues in the [Bugtracker](https://github.com/me0wg4ming/pfUI/issues).
Please make sure to have the latest version installed and check for conflicting addons beforehand.
**I have bad performance, what can I do?**
@@ -249,7 +249,7 @@ Version 6.0.0 includes significant performance optimizations. If you still exper
1. Disable "Frame Shadows" in Settings → Appearance → Enable Frame Shadows
2. Check `/pfdll` to see which DLLs are active (some features require DLLs)
3. Disable all AddOns but pfUI and enable one-by-one to identify conflicts
-4. Report issues via the [Bugtracker](https://github.com/shagu/pfUI/issues)
+4. Report issues via the [Bugtracker](https://github.com/me0wg4ming/pfUI/issues)
**Where is the happiness indicator for pets?**
The pet happiness is shown as the color of your pet's frame. Depending on your skin, this can either be the text or the background color of your pet's healthbar:
@@ -274,10 +274,7 @@ This happens if "Simple Chat" is enabled in blizzards interface settings (Advanc
Paste the following command into your chat to disable that option: `/run SIMPLE_CHAT="0"; pfUI.chat.SetupPositions(); ReloadUI()`
**How can I enable mouseover cast?**
-On Vanilla, create a macro with "/pfcast SPELLNAME". If you also want to see the cooldown, You might want to add "/run if nil then CastSpellByName("SPELLNAME") end" on top of the macro. For The Burning Crusade, just use the regular mouseover macros.
-
-**Will there be pfUI for Activision's "Classic" remakes?**
-No, it would require an entire rewrite of the AddOn since the game is now a different one. The AddOn-API has evolved during the last 15 years and the new "Classic" versions are based on a current retail gameclient. I don't plan to play any of those new versions, so I won't be porting any of my addons to it.
+On Vanilla, create a macro with "/pfcast SPELLNAME". If you also want to see the cooldown, You might want to add "/run if nil then CastSpellByName("SPELLNAME") end" on top of the macro.
**Everything from scratch?! Are you insane?**
Most probably, yes.
@@ -287,10 +284,11 @@ Most probably, yes.
## 🤝 Credits & Acknowledgments
- **Shagu** - Original pfUI creator ([https://github.com/shagu/pfUI](https://github.com/shagu/pfUI))
-- **me0wg4ming** - pfUI fork maintainer and enhancements
+- **me0wg4ming** - pfUI fork maintainer and Turtle WoW enhancements
- **SuperWoW Team** - SuperWoW framework development
- **avitasia** - Nampower DLL development
- **konaka** - UnitXP_SP3 DLL development
+- **Turtle WoW Team** - For the amazing Vanilla+ experience
- **Community** - Bug reports, feature suggestions, and testing
---
@@ -303,5 +301,5 @@ Same as original pfUI - free to use and modify.
**Version:** 6.0.0
**Release Date:** January 5, 2026
-**Compatibility:** World of Warcraft 1.12.1 (Vanilla)
+**Compatibility:** Turtle WoW 1.18.0
**Status:** Stable & Production-Ready
From 7184a2baa03f7644fdbad8bd5671d6b04d6372c4 Mon Sep 17 00:00:00 2001
From: Meow <30401521+me0wg4ming@users.noreply.github.com>
Date: Mon, 5 Jan 2026 09:33:56 +0100
Subject: [PATCH 28/40] Update README.md
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 1c6da861..64ce72fa 100644
--- a/README.md
+++ b/README.md
@@ -6,7 +6,7 @@
[](https://gitea.com/avitasia/nampower)
[](https://codeberg.org/konaka/UnitXP_SP3)
-**A pfUI fork specifically optimized for [Turtle WoW](https://turtle-wow.org/) with full SuperWoW, Nampower, and UnitXP_SP3 DLL integration.**
+**A pfUI fork specifically optimized for [Turtle WoW](https://turtlecraft.gg/) with full SuperWoW, Nampower, and UnitXP_SP3 DLL integration.**
This version includes significant performance improvements, DLL-enhanced features, and TBC spell indicators that work with Turtle WoW's expanded spell library.
From f8ed0531c17e310cee5cf5aa153ec9e3d0869f69 Mon Sep 17 00:00:00 2001
From: Meow <30401521+me0wg4ming@users.noreply.github.com>
Date: Mon, 5 Jan 2026 09:37:05 +0100
Subject: [PATCH 29/40] readme update once more
readme update once more
---
README.md | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 64ce72fa..23d3b33a 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
# pfUI - Turtle WoW Edition
[](https://github.com/me0wg4ming/pfUI)
-[](https://turtle-wow.org/)
+[](https://turtlecraft.gg/)
[](https://github.com/balakethelock/SuperWoW)
[](https://gitea.com/avitasia/nampower)
[](https://codeberg.org/konaka/UnitXP_SP3)
@@ -285,6 +285,7 @@ Most probably, yes.
- **Shagu** - Original pfUI creator ([https://github.com/shagu/pfUI](https://github.com/shagu/pfUI))
- **me0wg4ming** - pfUI fork maintainer and Turtle WoW enhancements
+- **jrc13245** - Nampower, UnitXP, and BGScore module integration ([https://github.com/jrc13245/](https://github.com/jrc13245/))
- **SuperWoW Team** - SuperWoW framework development
- **avitasia** - Nampower DLL development
- **konaka** - UnitXP_SP3 DLL development
From 74012a2b5eba027de15d1e552fd50d0059345ade Mon Sep 17 00:00:00 2001
From: Meow <30401521+me0wg4ming@users.noreply.github.com>
Date: Mon, 5 Jan 2026 09:38:46 +0100
Subject: [PATCH 30/40] readme
readme
---
README.md | 2 ++
1 file changed, 2 insertions(+)
diff --git a/README.md b/README.md
index 23d3b33a..f2634497 100644
--- a/README.md
+++ b/README.md
@@ -49,6 +49,8 @@ This version includes significant performance improvements, DLL-enhanced feature
### 🆕 New Modules
+*Modules by [jrc13245](https://github.com/jrc13245/)*
+
- ✅ **nampower.lua** - Nampower DLL integration module:
- Spell Queue Indicator (shows queued spell icon near castbar)
- GCD Indicator
From 25eda806279e74f369fe4e941d9ab8fe0232d1aa Mon Sep 17 00:00:00 2001
From: Meow <30401521+me0wg4ming@users.noreply.github.com>
Date: Mon, 5 Jan 2026 10:24:03 +0100
Subject: [PATCH 31/40] removed false command
removed false command
---
README.md | 1 -
1 file changed, 1 deletion(-)
diff --git a/README.md b/README.md
index f2634497..b27c7b83 100644
--- a/README.md
+++ b/README.md
@@ -82,7 +82,6 @@ This version includes significant performance improvements, DLL-enhanced feature
- ✅ **/pfdll** - Shows DLL status for SuperWoW, Nampower, and UnitXP with detailed diagnostics
- ✅ **/pfbehind** - Test command for Behind/LOS detection on current target
-- ✅ **/clickthrough** or **/ct** - Toggle clickthrough mode (click through corpses)
### 🎮 SuperWoW API Wrappers
From f0e1fe8cd5817a79cc2c954159dd4bb700a4b1cb Mon Sep 17 00:00:00 2001
From: Meow <30401521+me0wg4ming@users.noreply.github.com>
Date: Mon, 5 Jan 2026 10:27:57 +0100
Subject: [PATCH 32/40] had to remove that,
had to remove that,
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index b27c7b83..cadc5814 100644
--- a/README.md
+++ b/README.md
@@ -304,4 +304,4 @@ Same as original pfUI - free to use and modify.
**Version:** 6.0.0
**Release Date:** January 5, 2026
**Compatibility:** Turtle WoW 1.18.0
-**Status:** Stable & Production-Ready
+**Status:** Stable
From 74e6add89edb0edd2b43891e664fd6ca254d560a Mon Sep 17 00:00:00 2001
From: Meow <30401521+me0wg4ming@users.noreply.github.com>
Date: Mon, 5 Jan 2026 14:51:26 +0100
Subject: [PATCH 33/40] removed unecessaary actionbar file
removed unecessaary actionbar file
---
modules/actionbar.lua | 72 +-
modules/actionbar_nodebug.lua | 1738 ---------------------------------
2 files changed, 51 insertions(+), 1759 deletions(-)
delete mode 100644 modules/actionbar_nodebug.lua
diff --git a/modules/actionbar.lua b/modules/actionbar.lua
index 10e542dc..9edd0469 100644
--- a/modules/actionbar.lua
+++ b/modules/actionbar.lua
@@ -395,6 +395,14 @@ pfUI:RegisterModule("actionbar", "vanilla", function ()
for line in gfind(body, "[^%\n]+") do
_, _, match = string.find(line, '^#showtooltip (.+)')
+ -- skip any further manual macro scanning on
+ -- gameclients with native macro spell detection
+ if pfUI.client > 11200 and match then
+ self.spellslot = nil
+ self.booktype = nil
+ return
+ end
+
-- allow the user to disable the scan
if match and strfind(match, "disable") then
return
@@ -972,17 +980,25 @@ pfUI:RegisterModule("actionbar", "vanilla", function ()
pageswitch:SetScript("OnEvent", function()
if class ~= "DRUID" then return end
- -- UNIT_CASTEVENT: detect Cat Form and Prowl cast instantly
- -- Cat Form: 768 | Prowl: 5215 (R1), 6783 (R2), 9913 (R3)
+ -- On login/reload: full scan
+ if event == "PLAYER_ENTERING_WORLD" then
+ prowling = FullScan()
+ return
+ end
+
+ -- UNIT_CASTEVENT: detect Prowl cast instantly
+ -- Prowl Spell IDs: 5215 (Rank 1), 6783 (Rank 2), 9913 (Rank 3)
if event == "UNIT_CASTEVENT" then
local guid, target, cEvent, spellId = arg1, arg2, arg3, arg4
local _, playerGuid = UnitExists("player")
if guid == playerGuid and cEvent == "CAST" then
if spellId == 5215 or spellId == 6783 or spellId == 9913 then
+ -- Prowl cast detected
inCatForm = true
prowlActive = true
prowling = true
elseif spellId == 768 then
+ -- Cat Form cast (Spell ID 768)
inCatForm = true
end
end
@@ -1294,26 +1310,40 @@ pfUI:RegisterModule("actionbar", "vanilla", function ()
if enable == "1" then
-- handle pet bar
if i == 12 then
- -- only show when pet actions exists
- if PetHasActionBar() or pfUI.unlock and pfUI.unlock:IsShown() then
- bars[i]:Show()
- else
- bars[i]:Hide()
- end
-
- -- show/hide petbar on petbar updates
- if init then
- bars[i]:RegisterEvent("PET_BAR_UPDATE")
- bars[i]:SetScript("OnEvent", function()
- -- hide obsolete buttons
- for i=1, NUM_PET_ACTION_SLOTS do
- if not PetHasActionBar() and bars[12][i] then
- bars[12][i]:Hide()
- end
+ if pfUI.client > 11200 then
+ if InCombatLockdown and InCombatLockdown() then
+ -- don't process those events during combat
+ else
+ -- set state driver for pet bars
+ bars[i]:SetAttribute("unit", "pet")
+ local visibility = pfUI.unlock and pfUI.unlock:IsShown() and "show" or petvisibility
+ if bars[i].visibility ~= visibility then
+ RegisterStateDriver(bars[i], 'visibility', visibility)
+ bars[i].visibility = visibility
end
- -- refresh layout
- CreateActionBar(12)
- end)
+ end
+ else
+ -- only show when pet actions exists
+ if PetHasActionBar() or pfUI.unlock and pfUI.unlock:IsShown() then
+ bars[i]:Show()
+ else
+ bars[i]:Hide()
+ end
+
+ -- show/hide petbar on petbar updates
+ if init then
+ bars[i]:RegisterEvent("PET_BAR_UPDATE")
+ bars[i]:SetScript("OnEvent", function()
+ -- hide obsolete buttons
+ for i=1, NUM_PET_ACTION_SLOTS do
+ if not PetHasActionBar() and bars[12][i] then
+ bars[12][i]:Hide()
+ end
+ end
+ -- refresh layout
+ CreateActionBar(12)
+ end)
+ end
end
-- handle shapeshift bar
diff --git a/modules/actionbar_nodebug.lua b/modules/actionbar_nodebug.lua
deleted file mode 100644
index 9edd0469..00000000
--- a/modules/actionbar_nodebug.lua
+++ /dev/null
@@ -1,1738 +0,0 @@
-pfUI:RegisterModule("actionbar", "vanilla", function ()
- local _, class = UnitClass("player")
- local color = RAID_CLASS_COLORS[class]
- local cr, cg, cb = color.r , color.g, color.b
- local er, eg, eb, ea = GetStringColor(pfUI_config.appearance.border.color)
-
- local backdrop_highlight = { edgeFile = pfUI.media["img:glow"], edgeSize = 8 }
- local showgrid = 0
- local showgrid_pet = 0
- local rawborder, border = GetBorderSize("actionbars")
- local bpad = rawborder > 1 and border - GetPerfectPixel() or GetPerfectPixel()
-
- local eventcache = { } -- contains a list of events that shall be processed later -> [event] = true
- local updatecache = { } -- contains a list of buttons slots that shall be refreshed later -> [slot] = true
- local buttoncache = { } -- contains a list of all buttons ever created -> [slot] = frame
-
- local petvisibility = "[pet] show; hide"
-
- -- try to assume based on the current mouse positions if a button drag
- -- should happen even if action-on-key-down is used. By that replace the
- -- cast events by reverting the active buttons to the old mouse-up state.
- local drag_await
- local drag_active
- local function AssumeButtonDrag()
- -- skip during combat
- if InCombatLockdown and InCombatLockdown() then return end
-
- -- skip if keydown press is not enabled
- if C.bars.keydown ~= "1" then return end
-
- -- skip if always shift-drag is not enabled
- if C.bars.shiftdrag ~= "1" then return end
-
- if drag_await and not drag_active and IsShiftKeyDown() then
- drag_active = true
- -- set all buttons to regular on release clicks
- for id, button in pairs(buttoncache) do
- button:RegisterForClicks("LeftButtonUp", "RightButtonUp")
- end
- elseif drag_active and not IsShiftKeyDown() then
- drag_active = nil
- -- set all buttons back to their defaults
- for id, button in pairs(buttoncache) do
- button:RegisterForClicks("LeftButtonDown", "RightButtonDown")
- end
- end
- end
-
- -- hide blizzard bars
- local function kill(f, killshow)
- if f.Show and killshow then f.Show = function() return end end
- if f.UnregisterAllEvents then f:UnregisterAllEvents() end
- if f.Hide then f:Hide() end
- end
-
- -- also abbreviate mouse buttons
- local OrigGetBindingText = GetBindingText
- local function GetBindingText(msg, mod, abbrev)
- local txt = OrigGetBindingText(msg, mod, abbrev)
- if abbrev then
- txt = string.gsub(txt, _G[string.format("%s%s", mod, "BUTTON3")], "MB3")
- txt = string.gsub(txt, _G[string.format("%s%s", mod, "BUTTON4")], "MB4")
- txt = string.gsub(txt, _G[string.format("%s%s", mod, "BUTTON5")], "MB5")
- txt = string.gsub(txt, _G[string.format("%s%s", mod, "MOUSEWHEELDOWN")], "MWD")
- txt = string.gsub(txt, _G[string.format("%s%s", mod, "MOUSEWHEELUP")], "MWU")
- end
- return txt
- end
-
- kill(MainMenuBar)
-
- local blizzard_elements = { MultiBarBottomLeft,
- MultiBarBottomRight, MultiBarLeft, MultiBarRight }
- for _, f in pairs(blizzard_elements) do
- kill(f, true)
- end
-
- -- enable all possible actionbar pages
- SetActionBarToggles(0, 0, 0, 0)
- _G.SHOW_MULTI_ACTIONBAR_1 = nil
- _G.SHOW_MULTI_ACTIONBAR_2 = nil
- _G.SHOW_MULTI_ACTIONBAR_3 = nil
- _G.SHOW_MULTI_ACTIONBAR_4 = nil
-
- -- events that provide special updater functions
- local special_events = {
- ["ACTIONBAR_UPDATE_COOLDOWN"] = true,
- ["ACTIONBAR_UPDATE_USABLE"] = true,
- ["ACTIONBAR_UPDATE_STATE"] = true,
- }
-
- -- events that are shared across all buttons
- local global_events = {
- -- slot/button updates
- ["PLAYER_ENTERING_WORLD"] = true,
- ["ACTIONBAR_SLOT_CHANGED"] = true,
- ["UPDATE_BINDINGS"] = true,
- ["ACTIONBAR_PAGE_CHANGED"] = true,
- ["UPDATE_BONUS_ACTIONBAR"] = true,
- ["CRAFT_SHOW"] = true,
- ["CRAFT_CLOSE"] = true,
- ["TRADE_SKILL_SHOW"] = true,
- ["TRADE_SKILL_CLOSE"] = true,
- ["PLAYER_ENTER_COMBAT"] = true,
- ["PLAYER_LEAVE_COMBAT"] = true,
- -- cooldown updates
- ["UNIT_INVENTORY_CHANGED"] = true,
- -- auto repeat action
- ["START_AUTOREPEAT_SPELL"] = true,
- ["STOP_AUTOREPEAT_SPELL"] = true,
- }
-
- -- events that are used for the aura/shapeshift bar
- local aura_events = {
- ["UPDATE_SHAPESHIFT_FORMS"] = true,
- ["PLAYER_AURAS_CHANGED"] = true,
- }
-
- -- events that are used for the pet bar
- local pet_events = {
- ["PLAYER_CONTROL_LOST"] = true,
- ["PLAYER_CONTROL_GAINED"] = true,
- ["PLAYER_FARSIGHT_FOCUS_CHANGED"] = true,
- ["UNIT_PET"] = true,
- ["PET_BAR_UPDATE"] = true,
- ["PET_BAR_UPDATE_COOLDOWN"] = true,
- }
-
- local buttontypes = {
- -- blizzard keybinds
- [3] = "MULTIACTIONBAR3BUTTON",
- [4] = "MULTIACTIONBAR4BUTTON",
- [5] = "MULTIACTIONBAR2BUTTON",
- [6] = "MULTIACTIONBAR1BUTTON",
- [11] = "SHAPESHIFTBUTTON",
- [12] = "BONUSACTIONBUTTON",
- -- additional keybinds
- [2] = "PFPAGING",
- [7] = "PFSTANCEONE",
- [8] = "PFSTANCETWO",
- [9] = "PFSTANCETHREE",
- [10] = "PFSTANCEFOUR",
- }
-
- local blizzbarmapping = {
- ["MultiBarRight"] = 3,
- ["MultiBarLeft"] = 4,
- ["MultiBarBottomRight"] = 5,
- ["MultiBarBottomLeft"] = 6,
- ["ShapeShiftBar"] = 11,
- ["BonusActionBar"] = 12,
- }
-
- local barnames = {
- [1] = "Main",
- [2] = "Paging",
- [3] = "Right",
- [4] = "Vertical",
- [5] = "Left",
- [6] = "Top",
- [7] = "StanceBar1",
- [8] = "StanceBar2",
- [9] = "StanceBar3",
- [10] = "StanceBar4",
- [11] = "Stances",
- [12] = "Pet",
- }
-
- local button_animations = {
- ["none"] = function()
- this.active = nil
- this:Hide()
- end,
- ["zoomfade"] = function()
- if this.active == 0 then
- -- init animation
- this:SetWidth(this.parent:GetWidth())
- this:SetHeight(this.parent:GetHeight())
- this:SetScale(this.parent:GetScale())
- this.tex:SetTexture(this.parent.icon:GetTexture())
- this.tex:SetVertexColor(this.parent.icon:GetVertexColor())
- this:SetAlpha(1)
- this.active = 1
- return
- elseif this.active == 1 then
- -- run animation
- local fade = 30/GetFramerate()*0.05
- this:SetAlpha(this:GetAlpha() - fade)
- this:SetScale(this:GetScale() + fade)
- if this:GetAlpha() > 0 then return end
- end
-
- -- stop animation
- this.active = nil
- this:Hide()
- end,
- ["shrinkreturn"] = function()
- if this.active == 0 then
- -- init animation
- this:SetWidth(this.parent:GetWidth())
- this:SetHeight(this.parent:GetHeight())
- this:SetScale(this.parent:GetScale())
- this.tex:SetTexture(this.parent.icon:GetTexture())
- this.tex:SetVertexColor(this.parent.icon:GetVertexColor())
- this:SetAlpha(1)
- this.parent.icon:Hide()
- this.active = 1
- this.time = 0
- return
- elseif this.active == 1 then
- -- run animation
- this.time = this.time + 30/GetFramerate()*0.1
- local fade = 1 -math.exp(-this.time)*math.sin(this.time*math.pi)
- this:SetAlpha(fade)
- this:SetScale(fade)
- if this.time < 1 then return end
- end
-
- -- stop animation
- this.active = nil
- this:Hide()
- this.parent.icon:Show()
- end,
- ["elasticzoom"] = function()
- if this.active == 0 then
- -- init animation
- this:SetWidth(this.parent:GetWidth())
- this:SetHeight(this.parent:GetHeight())
- this:SetScale(this.parent:GetScale())
- this.tex:SetTexture(this.parent.icon:GetTexture())
- this.tex:SetVertexColor(this.parent.icon:GetVertexColor())
- this:SetAlpha(1)
- this.parent.icon:Hide()
- this.active = 1
- this.time = 0
- return
- elseif this.active == 1 then
- -- run animation
- this.time = this.time + 30/GetFramerate()*0.03
- local fade = 1 -math.exp(-this.time*6)*math.sin(this.time*4*math.pi)
- this:SetAlpha(fade)
- this:SetScale(fade)
- if this.time < 1 then return end
- end
-
- -- stop animation
- this.active = nil
- this:Hide()
- this.parent.icon:Show()
- end,
- ["wobblezoom"] = function()
- if this.active == 0 then
- -- init animation
- this:SetWidth(this.parent:GetWidth())
- this:SetHeight(this.parent:GetHeight())
- this:SetScale(this.parent:GetScale())
- this.tex:SetTexture(this.parent.icon:GetTexture())
- this.tex:SetVertexColor(this.parent.icon:GetVertexColor())
- this:SetAlpha(1)
- this.parent.icon:Hide()
- this.active = 1
- this.time = 0
- return
- elseif this.active == 1 then
- -- run animation
- this.time = this.time + 30/GetFramerate()*0.02
- local fade = 1 -math.exp(-this.time*6)*math.sin(this.time*10*math.pi)
- this:SetAlpha(fade)
- this:SetScale(fade)
- if this.time < 1 then return end
- end
-
- -- stop animation
- this.active = nil
- this:Hide()
- this.parent.icon:Show()
- end,
- }
-
- local function GetActiveBar()
- if CURRENT_ACTIONBAR_PAGE == 1 and GetBonusBarOffset() ~= 0 then
- return NUM_ACTIONBAR_PAGES + GetBonusBarOffset()
- else
- return CURRENT_ACTIONBAR_PAGE
- end
- end
-
- local function ButtonDrag(self)
- -- skip during combat
- if InCombatLockdown and InCombatLockdown() then return end
-
- local self = self or this
-
- if _G.LOCK_ACTIONBAR == "1" and not (pfUI_config.bars.shiftdrag == "1" and IsShiftKeyDown()) then return end
-
- if self.bar == 12 then
- PickupPetAction(self.id)
- else
- PickupAction(self.id)
- end
- end
-
- local function ButtonDragStop(self)
- -- skip during combat
- if InCombatLockdown and InCombatLockdown() then return end
-
- local self = self or this
-
- if MacroFrame_SaveMacro then
- MacroFrame_SaveMacro()
- end
-
- if self.bar == 12 then
- PickupPetAction(self.id)
- else
- PlaceAction(self.id)
- end
- end
-
- local mouse
- local function ButtonAnimate(self)
- local self = self or this
- mouse = arg1 and not keystate
-
- -- trigger action animation
- if ( pfUI_config.bars.keydown == "1" and keystate == "down" ) or (pfUI_config.bars.keydown == "0" and keystate == "up" ) or self.bar == 11 or mouse then
- if C.bars.animmode == "keypress" and ( self:GetAlpha() > .1 or C.bars.animalways == "1" ) then
- self.animation.active = 0
- self.animation:Show()
- end
- end
-
- -- handle button highlight
- if keystate == "down" then
- self.highlight:Show()
- elseif not MouseIsOver(self) then
- self.highlight:Hide()
- end
- end
-
- local function ButtonClick(self)
- local self = self or this
-
- local grid = self.bar == 12 and showgrid_pet or showgrid
- local mouse = arg1 and not keystate
- local keystate = keystate
- local slfcast = C.bars.altself == "1" and IsAltKeyDown() and true or self.slfcast
- slfcast = C.bars.rightself == "1" and arg1 and arg1 == "RightButton" and true or slfcast
- self.slfcast = nil
-
- if ( pfUI_config.bars.keydown == "1" and keystate == "down" and not drag_active ) or (pfUI_config.bars.keydown == "0" and keystate == "up" or drag_active ) or self.bar == 11 or mouse then
- if self.bar == 11 then
- CastShapeshiftForm(self.id)
- elseif grid == 1 then
- if self.bar == 12 then
- PickupPetAction(self.id)
- else
- PickupAction(self.id)
- end
- elseif self.bar == 12 then
- if arg1 == "LeftButton" then
- if IsPetAttackActive(self.id) then
- PetStopAttack()
- else
- CastPetAction(self.id)
- end
- else
- TogglePetAutocast(self.id)
- end
- else
- if MacroFrame_SaveMacro then
- MacroFrame_SaveMacro()
- end
-
- UseAction(self.id, nil, slfcast)
- end
- end
- end
-
- local function ButtonMacroScan(self)
- if self.bar > 10 then return end
- if not self.scanmacro then return end
- if pfUI.bars.skip_macro then return end
-
- local macro = GetActionText(self.id)
- self.spellslot = nil
- self.booktype = nil
- if macro then
- local slot = GetMacroIndexByName(macro)
- local name, _, body = GetMacroInfo(slot)
-
- if name and body then
- local match
-
- for line in gfind(body, "[^%\n]+") do
- _, _, match = string.find(line, '^#showtooltip (.+)')
-
- -- skip any further manual macro scanning on
- -- gameclients with native macro spell detection
- if pfUI.client > 11200 and match then
- self.spellslot = nil
- self.booktype = nil
- return
- end
-
- -- allow the user to disable the scan
- if match and strfind(match, "disable") then
- return
- end
-
- if not match then
- -- add support to specify custom tooltips via:
- -- /run --showtooltip SPELLNAME
- _, _, match = string.find(line, '%-%-showtooltip (.+)')
- end
-
- if not match then
- _, _, match = string.find(line, '^/cast (.+)')
- end
-
- if not match then
- _, _, match = string.find(line, '^/pfcast (.+)')
- end
-
- if not match then
- _, _, match = string.find(line, '^/pfmouse (.+)')
- end
-
- if not match then
- _, _, match = string.find(line, 'CastSpellByName%(%"(.+)%"%)')
- end
-
- if match then
- local _, _, spell, rank = string.find(match, '(.+)%((.+)%)')
- spell = spell or match
- self.spellslot, self.booktype = libspell.GetSpellIndex(spell, rank)
-
- if self.spellslot and self.spellslot > 0 then return end
- end
- end
- end
- end
- end
-
- local function ButtonEnter(self)
- local self = self or this
-
- -- indicate that dragging could get enabled
- drag_await = true
-
- GameTooltip:ClearLines()
- GameTooltip_SetDefaultAnchor(GameTooltip, self)
-
- if self.bar == 11 then
- GameTooltip:SetShapeshift(self.id)
- elseif self.bar == 12 then
- local name, _, _, token = GetPetActionInfo(self.id)
- if token then
- GameTooltip:AddLine(_G[name])
- GameTooltip:Show()
- else
- GameTooltip:SetPetAction(self.id)
- end
- elseif self.spellslot and self.booktype then
- GameTooltip:SetSpell(self.spellslot, self.booktype)
- else
- GameTooltip:SetAction(self.id)
- end
-
- self.highlight:Show()
- end
-
- local function ButtonLeave(self)
- local self = self or this
-
- -- no longer wait for a drag event
- drag_await = nil
-
- self.highlight:Hide()
- GameTooltip:Hide()
- end
-
- local start, duration, enable, castable, autocast, token
- local grid, sid, id, bar, active, texture, _
- local function ButtonSlotUpdate(self)
- if not self then return end
- local self = self or this
- sid = self.id -- 1 to 120
-
- -- reset shared variables
- castable, autocast, token = nil, nil, nil
-
- -- set the own ID for compatibility to some vanilla addons
- if pfUI.client <= 11200 then self:SetID(self.id) end
-
- grid = self.bar == 12 and showgrid_pet or showgrid
-
- if self.bar == 11 then
- -- stance button
- bar = self.bar
- id = sid
- texture, _, active = GetShapeshiftFormInfo(id)
- elseif self.bar == 12 then
- -- pet button
- bar = self.bar
- id = sid
- _, _, texture, token, active, castable, autocast = GetPetActionInfo(id)
- texture = token and _G[texture] or texture
- else
- active = IsCurrentAction(sid) or IsAutoRepeatAction(sid)
- texture = GetActionTexture(sid)
- bar = GetActiveBar()
- id = self.bar == 1 and self.slot or sid-((self.bar)-1)*12
- end
-
- -- overwrite with spell macro texture where possible
- if self.spellslot and self.booktype then
- texture = GetSpellTexture(self.spellslot, self.booktype)
- end
-
- if not self.showempty and self.backdrop and not texture and grid == 0 then
- self.backdrop:Hide()
- self.hide = true
- else
- self.backdrop:Show()
- self.hide = nil
- end
-
- -- active border
- if active then
- if C.bars.animmode == "statechange" and not self.active:IsShown() then
- self.animation.active = 0
- self.animation:Show()
- end
-
- self.backdrop:SetBackdropBorderColor(cr,cg,cb,1)
- self.active:Show()
- else
- self.backdrop:SetBackdropBorderColor(er,eg,eb,ea)
- self.active:Hide()
- end
-
- if self.bar ~= 11 and self.bar ~= 12 then
- -- update consumables
- if IsConsumableAction(sid) then
- self.count:SetText(GetActionCount(sid))
- elseif IsReagentAction and IsReagentAction(sid) then
- self.count:SetText(GetReagentCount(sid))
- else
- self.count:SetText(nil)
- end
-
- -- equipped item
- if IsEquippedAction(sid) and C.bars.showequipped == "1" then
- self.equipped:Show()
- else
- self.equipped:Hide()
- end
-
- -- update macro text
- if C.bars["bar"..self.bar] and C.bars["bar"..self.bar].showmacro == "1" then
- self.macro:SetText(GetActionText(sid))
- else
- self.macro:SetText("")
- end
- end
-
- -- icon
- if texture ~= self.texture then
- self.icon:SetTexture(texture)
- self.texture = texture
- end
-
- -- handle pet bar quirks
- if self.bar == 12 then
- -- desaturate disabled petbar
- self.icon:SetDesaturated(not GetPetActionsUsable())
-
- -- display autocast
- if autocast then
- self.autocast:Show()
- self.autocast:SetAlpha(self:GetAlpha() * 0.10)
- else
- self.autocast:Hide()
- end
-
- if castable and C.bars.showcastable == "1" then
- self.autocastable:Show()
- else
- self.autocastable:Hide()
- end
- end
-
- -- keybinds
- if not self.hide and self.bar == 1 and self.bar ~= 11 and self.bar ~= 12 then
- self.keybind:SetText(GetBindingText(GetBindingKey("ACTIONBUTTON"..id), "KEY_", 1))
- elseif not self.hide and buttontypes[self.bar] then
- self.keybind:SetText(GetBindingText(GetBindingKey(buttontypes[self.bar]..id), "KEY_", 1))
- else
- self.keybind:SetText("")
- end
- end
-
- local sid, usable, oom, _
- local function ButtonUsableUpdate(self)
- local self = self or this
- sid = self.id -- 1 to 120
-
- if self.bar == 11 then
- _, _, _, usable = GetShapeshiftFormInfo(sid)
- elseif self.bar == 12 then
- usable = true
- else
- usable, oom = IsUsableAction(sid)
- end
-
- -- update usable [out-of-range = 1, oom = 2, not-usable = 3, default = 0]
- if self.outofrange and C.bars.glowrange == "1" then
- if self.vertexstate ~= 1 then
- self.icon:SetVertexColor(self.rangeColor[1], self.rangeColor[2], self.rangeColor[3], self.rangeColor[4])
- self.vertexstate = 1
- end
- elseif oom and C.bars.showoom == "1" then
- if self.vertexstate ~= 2 then
- self.icon:SetVertexColor(self.oomColor[1], self.oomColor[2], self.oomColor[3], self.oomColor[4])
- self.vertexstate = 2
- end
- elseif not usable and C.bars.showna == "1" then
- if self.vertexstate ~= 3 then
- self.icon:SetVertexColor(self.naColor[1], self.naColor[2], self.naColor[3], self.naColor[4])
- self.vertexstate = 3
- end
- else
- if self.vertexstate ~= 0 then
- self.icon:SetVertexColor(1, 1, 1, 1)
- self.vertexstate = 0
- end
- end
- end
-
- local function ButtonRangeUpdate(self)
- local self = self or this
-
- -- update range display
- if C.bars.glowrange == "1" and self.bar ~= 11 and self.bar ~= 12 and HasAction(self.id) and ActionHasRange(self.id) and IsActionInRange(self.id) == 0 then
- if not self.outofrange then
- self.outofrange = true
- ButtonUsableUpdate(self)
- end
- elseif self.outofrange then
- self.outofrange = nil
- ButtonUsableUpdate(self)
- end
- end
-
- local start, duration, enable
- local function ButtonCooldownUpdate(button)
- if not button then return end
-
- if button.bar == 11 then
- start, duration, enable = GetShapeshiftFormCooldown(button.id)
- elseif button.bar == 12 then
- start, duration, enable = GetPetActionCooldown(button.id)
- elseif button.spellslot and button.booktype then
- start, duration = GetSpellCooldown(button.spellslot, button.booktype)
- enable = 1
- else
- start, duration, enable = GetActionCooldown(button.id)
- end
-
- CooldownFrame_SetTimer(button.cd, start, duration, enable)
- end
-
- local _, active
- local function ButtonIsActiveUpdate(button)
- if not button then return end
-
- if button.bar == 11 then
- _, _, active, _ = GetShapeshiftFormInfo(button.id)
- elseif button.bar == 12 then
- _, _, _, _, active, _, _ = GetPetActionInfo(button.id)
- else
- active = IsCurrentAction(button.id) or IsAutoRepeatAction(button.id)
- end
-
- -- active border
- if active then
- if not button.border_active then
- button.backdrop:SetBackdropBorderColor(cr,cg,cb,1)
- button.border_active = true
- end
-
- button.active:Show()
- else
- if button.border_active then
- button.backdrop:SetBackdropBorderColor(er,eg,eb,ea)
- button.border_active = nil
- end
-
- button.active:Hide()
- end
- end
-
-
- local function ButtonFullUpdate(button)
- if not button then return end
-
- ButtonMacroScan(button)
- ButtonSlotUpdate(button)
- ButtonRangeUpdate(button)
- ButtonUsableUpdate(button)
- ButtonCooldownUpdate(button)
- ButtonIsActiveUpdate(button)
- end
-
- local function BarsEvent(self)
- local self = self or this
-
- -- refresh only specific slots
- if event == "ACTIONBAR_SLOT_CHANGED" and arg1 and arg1 ~= 0 then
- updatecache[arg1] = true
- return
- end
-
- -- run special refresh functions on next update
- if special_events[event] then
- eventcache[event] = true
- return
- end
-
- -- handle aura events
- if aura_events[event] then
- for j=1,12 do
- if self[11] and self[11][j] then
- updatecache[self[11][j].slot] = true
- end
- end
- return
- end
-
- -- handle pet events
- if pet_events[event] then
- for j=1,12 do
- if self[12] and self[12][j] then
- updatecache[self[12][j].slot] = true
- end
- end
- return
- end
-
- -- handle global events
- for id in pairs(buttoncache) do
- updatecache[id] = true
- end
- end
-
- local self, button, unlock
- local function BarsUpdate(self)
- self = self or this
-
- -- update buttons whenever a button drag is assumed
- AssumeButtonDrag()
-
- if pfUI.unlock then
- -- update all bars when entering unlock
- if pfUI.unlock:IsShown() ~= unlock then
- pfUI.bars:UpdateConfig()
- unlock = pfUI.unlock:IsShown()
- end
- end
-
- -- run cached usable usable actions
- if eventcache["ACTIONBAR_UPDATE_USABLE"] then
- eventcache["ACTIONBAR_UPDATE_USABLE"] = nil
- for id, button in pairs(buttoncache) do
- ButtonUsableUpdate(button)
- end
- end
-
- -- run cached cooldown events
- if eventcache["ACTIONBAR_UPDATE_COOLDOWN"] then
- eventcache["ACTIONBAR_UPDATE_COOLDOWN"] = nil
- for id, button in pairs(buttoncache) do
- ButtonCooldownUpdate(button)
- end
- end
-
- -- run cached action state events
- if eventcache["ACTIONBAR_UPDATE_STATE"] then
- eventcache["ACTIONBAR_UPDATE_STATE"] = nil
- for id, button in pairs(buttoncache) do
- ButtonIsActiveUpdate(button)
- end
- end
-
- for id in pairs(updatecache) do
- -- run updates based on slot
- pfUI.bars.ButtonFullUpdate(buttoncache[id])
-
- -- run updates on paging actionbar if required
- for i=1,12 do
- if pfUI.bars[1][i].id == id then
- pfUI.bars.ButtonFullUpdate(pfUI.bars[1][i])
- end
- end
-
- -- clear update cache
- updatecache[id] = nil
- end
-
- if ( this.tick or .2) > GetTime() then return else this.tick = GetTime() + .2 end
-
- for id, button in pairs(buttoncache) do
- if button:IsShown() then ButtonRangeUpdate(button) end
- end
- end
-
- -- create the main event and update handler for pfUI actionbars
- local bars = CreateFrame("Frame", "pfActionBar", UIParent)
- for event in pairs(special_events) do bars:RegisterEvent(event) end
- for event in pairs(global_events) do bars:RegisterEvent(event) end
- for event in pairs(aura_events) do bars:RegisterEvent(event) end
- for event in pairs(pet_events) do bars:RegisterEvent(event) end
-
- -- refresh actionbar buttons on event
- bars:SetScript("OnEvent", BarsEvent)
-
- -- update actionbar buttons
- bars:SetScript("OnUpdate", BarsUpdate)
-
- -- enable bar paging via secure functions
- local function ButtonSwitch(self, att, value)
- if att == "state-parent" then
- local action = SecureButton_GetModifiedAttribute(self, "action", SecureStateChild_GetEffectiveButton(self)) or self.id
- if self.id == action then return end
- updatecache[self.slot] = true
- self.id = action
- end
- end
-
- local function EnablePaging(bar)
- if pfUI.client <= 11200 then
- if not bar.pager then
- bar.pager = CreateFrame("Frame")
- bar.pager:RegisterEvent("PLAYER_ENTERING_WORLD")
- bar.pager:RegisterEvent("UPDATE_BONUS_ACTIONBAR")
- bar.pager:RegisterEvent("ACTIONBAR_PAGE_CHANGED")
- bar.pager:SetScript("OnEvent", function()
- for i=1, 10 do -- reload pageable bars
- local pageable = C.bars["bar"..i] and C.bars["bar"..i].pageable == "1" and true or nil
- _G.VIEWABLE_ACTION_BAR_PAGES[i] = pageable
- end
-
- local active = GetActiveBar()
- for i=1,12 do
- local id = i + (active-1)*12
- bar[i].id = id
- updatecache[i] = true
- end
- end)
- end
- else
- -- append paging enabled bars to the filter list
- for i=1,12 do bar[i]:SetScript("OnAttributeChanged", ButtonSwitch) end
-
- -- fill all possible page states
- local page, pages = nil, {}
- while not pages[6] do
- for i=1, 6 do
- page = i == 1 and 1 or C.bars["bar"..i] and C.bars["bar"..i].pageable == "1" and i
- if page then table.insert(pages, page) end
- end
- end
-
- bar:SetAttribute("statemap-page", "$input")
- bar:SetAttribute("state", (bar:GetAttribute("state-page") or 1))
-
- -- prio posses bar
- bar.filter = "[bonusbar: 5] 11;"
-
- -- set bar 8 for druid stealth if enabled
- local prowl = class == "DRUID" and C.bars["druidstealth"] == "1" and "8" or "7"
-
- -- write default pages
- for state, page in pairs(pages) do
- if page ~= 1 then -- skip page 1 as it is supposed to stay dynamic for stances
- bar.filter = string.format("%s[actionbar: %s] %s; ", bar.filter, state, page)
- end
- end
-
- -- write page driver conditions
- bar.filter = string.format("%s[bonusbar:1,nostealth] 7; [bonusbar:1,stealth] %s; [bonusbar:2] 10; [bonusbar:3] 9; [bonusbar:4] 10; 1", bar.filter, prowl)
-
- -- prepend pagemaster states if enabled
- if C.bars.pagemaster == "1" then
- for mod, page in pairs({ ["shift"] = "6", ["ctrl"] = "5", ["alt"] = "3" }) do
- bar.filter = string.format("[modifier:%s] %s;", mod, page) .. bar.filter
- end
- end
-
- -- enable page driver conditions
- RegisterStateDriver(bar, "page", bar.filter)
- SecureStateHeader_Refresh(bar)
- end
- end
-
- local function SwitchBar(bar)
- if _G.CURRENT_ACTIONBAR_PAGE ~= bar then
- _G.CURRENT_ACTIONBAR_PAGE = bar
- ChangeActionBarPage(bar)
- end
- end
-
- local cat, stealth
- local inCatForm = nil -- cached from buff scan
- local prowlActive = nil -- tracks if prowl is active
-
- -- Full scan for cat form and prowl (only on login/reload)
- local function FullScan()
- if class ~= "DRUID" then return nil end
-
- local foundCat, foundStealth = nil, nil
-
- for i = 0, 31 do
- local texture = GetPlayerBuffTexture(i)
- if not texture then break end
-
- if strfind(texture, "Ability_Druid_CatForm") then
- foundCat = true
- end
-
- if strfind(texture, "Ability_Ambush") then
- foundStealth = true
- end
- end
-
- inCatForm = foundCat
- prowlActive = foundCat and foundStealth
- return prowlActive
- end
-
- -- Quick scan only for prowl (when we know we're in cat form)
- local function HasProwlBuff()
- for i = 0, 31 do
- local texture = GetPlayerBuffTexture(i)
- if not texture then break end
- if strfind(texture, "Ability_Ambush") then
- return true
- end
- end
- return nil
- end
-
- -- pagemaster / meta page switch
- if pfUI.expansion == "vanilla" then
- local prowl, shift, ctrl, alt, default = 8, 6, 5, 3, 1
-
- -- set temporary pagemaster bindings keybinds
- if C.bars.pagemaster == "1" then
- local modifier = { "ALT", "SHIFT", "CTRL" }
- local buttons = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "-", "+", "=", "´" }
- local current = CURRENT_ACTIONBAR_PAGE
- bars.pagemaster = bars.pagemaster or CreateFrame("Frame", "pfPageMaster", UIParent)
- bars.pagemaster:RegisterEvent("PLAYER_ENTERING_WORLD")
- bars.pagemaster:SetScript("OnEvent", function()
- for _,mod in pairs(modifier) do
- for _,but in pairs(buttons) do
- SetBinding(mod.."-"..but)
- end
- end
- end)
- end
-
- -- setup page switch frame
- local prowling = nil
- local pageswitch = CreateFrame("Frame", "pfActionBarPageSwitch", UIParent)
- pageswitch:RegisterEvent("PLAYER_AURAS_CHANGED")
- pageswitch:RegisterEvent("PLAYER_ENTERING_WORLD")
- pageswitch:RegisterEvent("UNIT_CASTEVENT")
- pageswitch:SetScript("OnEvent", function()
- if class ~= "DRUID" then return end
-
- -- On login/reload: full scan
- if event == "PLAYER_ENTERING_WORLD" then
- prowling = FullScan()
- return
- end
-
- -- UNIT_CASTEVENT: detect Prowl cast instantly
- -- Prowl Spell IDs: 5215 (Rank 1), 6783 (Rank 2), 9913 (Rank 3)
- if event == "UNIT_CASTEVENT" then
- local guid, target, cEvent, spellId = arg1, arg2, arg3, arg4
- local _, playerGuid = UnitExists("player")
- if guid == playerGuid and cEvent == "CAST" then
- if spellId == 5215 or spellId == 6783 or spellId == 9913 then
- -- Prowl cast detected
- inCatForm = true
- prowlActive = true
- prowling = true
- elseif spellId == 768 then
- -- Cat Form cast (Spell ID 768)
- inCatForm = true
- end
- end
- return
- end
-
- -- PLAYER_AURAS_CHANGED: smart scanning
- if event == "PLAYER_AURAS_CHANGED" then
- if prowlActive then
- -- We were prowling, check if still prowling
- if HasProwlBuff() then
- prowling = true
- else
- -- Prowl ended
- prowlActive = nil
- prowling = nil
- -- Also check if still in cat form
- inCatForm = nil
- for i = 0, 31 do
- local texture = GetPlayerBuffTexture(i)
- if not texture then break end
- if strfind(texture, "Ability_Druid_CatForm") then
- inCatForm = true
- break
- end
- end
- end
- elseif not inCatForm then
- -- Not in cat form, do a full scan (might have just shifted)
- prowling = FullScan()
- end
- -- If inCatForm but not prowlActive, no scan needed (wait for UNIT_CASTEVENT)
- end
- end)
- pageswitch:SetScript("OnUpdate", function()
- -- switch actionbar page depending on meta key that is pressed
- if C.bars.pagemastershift == "1" and IsShiftKeyDown() then
- SwitchBar(shift)
- return
- elseif C.bars.pagemasterctrl == "1" and IsControlKeyDown() then
- SwitchBar(ctrl)
- return
- elseif C.bars.pagemasteralt == "1" and IsAltKeyDown() then
- SwitchBar(alt)
- return
- elseif C.bars.pagemasteralt == "1" or C.bars.pagemasterctrl == "1" or C.bars.pagemastershift == "1" then
- SwitchBar(default)
- end
-
- -- switch actionbar page if druid stealth is detected
- if C.bars.druidstealth == "1" then
- if prowling and _G.CURRENT_ACTIONBAR_PAGE == 1 then
- SwitchBar(prowl)
- elseif not prowling and _G.CURRENT_ACTIONBAR_PAGE == 8 then
- SwitchBar(default)
- end
- end
- end)
- end
-
- local function CreateActionButton(parent, bar, button)
- -- load config
- local size = C.bars["bar"..bar].icon_size
- local font = pfUI.media[C.bars.font]
- local font_offset = tonumber(C.bars.font_offset)
-
- local macro_size = tonumber(C.bars.macro_size)
- local macro_color = { strsplit(",", C.bars.macro_color) }
-
- local count_size = tonumber(C.bars.count_size)
- local count_color = { strsplit(",", C.bars.count_color) }
-
- local bind_size = tonumber(C.bars.bind_size)
- local bind_color = { strsplit(",", C.bars.bind_color) }
-
- local cd_size = tonumber(C.bars.cd_size)
-
- local showempty = C.bars["bar"..bar].showempty
- local showmacro = C.bars["bar"..bar].showmacro
- local showkybind = C.bars["bar"..bar].showkeybind
- local showcount = C.bars["bar"..bar].showcount
-
- -- sanitize font sizes
- if macro_size == 0 then macro_size = 1 end
- if count_size == 0 then macro_size = 1 end
- if bind_size == 0 then macro_size = 1 end
- if cd_size == 0 then cd_size = nil end
-
- local button_name = "pfActionBar" .. barnames[bar] .. "Button" .. button
-
- local id = (bar-1)*12+button
- local exists = _G[button_name] and true or nil
- local f = _G[button_name] or CreateFrame("Button", button_name, parent, ACTIONBAR_SECURE_TEMPLATE_BUTTON)
-
- -- no button available, create a new one
- if not exists then
- -- prepare the button for vanilla
- if not f.HookScript then
- f.HookScript = HookScript
- f:SetScript("OnClick", ButtonClick)
- end
-
- if bar ~= 11 then
- f:RegisterForDrag("LeftButton", "RightButton")
- f:SetScript("OnDragStart", ButtonDrag)
- f:SetScript("OnReceiveDrag", ButtonDragStop)
- end
-
- -- add mouseovers
- f:SetScript("OnEnter", ButtonEnter)
- f:SetScript("OnLeave", ButtonLeave)
-
- -- add click animation handler
- f:HookScript("OnClick", ButtonAnimate)
- f.id = id
-
- -- set a static slot
- f.slot = id
-
- -- cooldown
- f.cd = CreateFrame(COOLDOWN_FRAME_TYPE, f:GetName() .. "Cooldown", f, "CooldownFrameTemplate")
- f.cd.pfCooldownStyleAnimation = 1
- f.cd.pfCooldownType = "NOGCD"
- f.cd.pfCooldownSize = cd_size
-
- -- icon
- f.icon = f:CreateTexture(button_name .. "Icon", "BACKGROUND")
- f.icon:SetTexCoord(.08, .92, .08, .92)
- f.icon:SetAllPoints()
-
- -- animation
- f.animation = CreateFrame("Frame", button_name .. "Animation", f)
- f.animation.parent = f
- f.animation:SetPoint("CENTER", 0, 0)
- f.animation:Hide()
- f.animation.tex = f.animation:CreateTexture(button_name .. "AnimationTexture", "BACKGROUND")
- f.animation.tex:SetTexCoord(.08, .92, .08, .92)
- f.animation.tex:SetAllPoints()
-
- if bar ~= 11 and bar ~= 12 then
- -- equipped item
- f.equipped = f:CreateTexture(nil, "BORDER")
- f.equipped:SetAllPoints()
- f.equipped:Hide()
- elseif bar == 12 then
- f.autocast = CreateFrame("Model", nil, f)
- f.autocast:SetAllPoints()
- f.autocast:SetModel("Interface\\Buttons\\UI-AutoCastButton.mdx")
- f.autocast:SetSequence(0)
- f.autocast:SetSequenceTime(0, 0)
- f.autocast:Hide()
-
- f.autocastable = f:CreateTexture(nil, "BORDER")
- f.autocastable:SetAllPoints()
- f.autocastable:SetTexture("Interface\\Buttons\\UI-AutoCastableOverlay")
- f.autocastable:SetTexCoord(.25, .75, .25, .75)
- end
-
- -- macro
- f.macro = f:CreateFontString(button_name .. "Name", "LOW", "GameFontNormal")
-
- -- keybind
- f.keybind = f:CreateFontString(nil, "LOW", "GameFontNormal")
-
- -- itemcount
- f.count = f:CreateFontString(button_name .. "Count", "LOW", "GameFontNormal")
-
- -- highlight
- f.highlight = CreateFrame("Frame", nil, f)
- f.highlight:SetBackdrop(backdrop_highlight)
- f.highlight:SetBackdropBorderColor(1,1,1,.8)
- f.highlight:SetAllPoints()
- f.highlight:Hide()
-
- -- active
- f.active = CreateFrame("Frame", nil, f)
- f.active:SetBackdrop(backdrop_highlight)
- f.active:SetBackdropBorderColor(1,1,.5,1)
- f.active:SetAllPoints()
- f.active:Hide()
-
- -- add to buttoncache
- buttoncache[id] = f
- end
-
- -- set keydown option
- if C.bars.keydown == "1" then
- f:RegisterForClicks("LeftButtonDown", "RightButtonDown")
- else
- f:RegisterForClicks("LeftButtonUp", "RightButtonUp")
- end
-
- -- set animation
- f.animation:SetScript("OnUpdate", button_animations[C.bars.animation])
-
- -- pet autocast
- if bar == 12 then
- f.autocast:SetScale(C.bars["bar"..bar].icon_size / 25)
- f.autocast:SetAlpha(.10)
- end
-
- -- macro options
- if showmacro == "1" then f.macro:Show() else f.macro:Hide() end
- SetAllPointsOffset(f.macro, f, font_offset, -font_offset)
- f.macro:SetFont(font, macro_size, "OUTLINE")
- f.macro:SetTextColor(unpack(macro_color))
- f.macro:SetJustifyH("LEFT")
- f.macro:SetJustifyV("BOTTOM")
-
- -- keybind options
- if showkybind == "1" then f.keybind:Show() else f.keybind:Hide() end
- SetAllPointsOffset(f.keybind, f, font_offset, -font_offset)
- f.keybind:SetFont(font, bind_size, "OUTLINE")
- f.keybind:SetTextColor(unpack(bind_color))
- f.keybind:SetJustifyH("RIGHT")
- f.keybind:SetJustifyV("TOP")
- f.keybind:SetNonSpaceWrap(false)
-
- -- item count options
- if showcount == "1" then f.count:Show() else f.count:Hide() end
- SetAllPointsOffset(f.count, f, font_offset, -font_offset)
- f.count:SetFont(font, count_size, "OUTLINE")
- f.count:SetTextColor(unpack(count_color))
- f.count:SetJustifyH("RIGHT")
- f.count:SetJustifyV("BOTTOM")
-
- -- macro spell scan
- if C.bars.macroscan == "0" then
- f.scanmacro, f.spellslot, f.booktype = nil, nil, nil
- else
- f.scanmacro = true
- end
-
- -- range glow color
- f.rangeColor = { strsplit(",", C.bars.rangecolor) }
-
- -- out of mana color
- f.oomColor = { strsplit(",", C.bars.oomcolor) }
-
- -- not usable color
- f.naColor = { strsplit(",", C.bars.nacolor) }
-
- -- equipped color
- if f.equipped then
- f.equipped:SetTexture(strsplit(",", C.bars.eqcolor))
- end
-
- -- general appearance
- f.showempty = showempty == "1" and true or nil
- f:SetHeight(size)
- f:SetWidth(size)
- CreateBackdrop(f, border)
-
- return f
- end
-
- local function CreateActionBar(i)
- -- load config
- local buttonbasename = "pfActionBar" .. barnames[i] .. "Button"
- local enable = C.bars["bar"..i].enable
- local size = C.bars["bar"..i].icon_size
- local spacing = C.bars["bar"..i].spacing
- local background = C.bars["bar"..i].background
- local formfactor = C.bars["bar"..i].formfactor
- local autohide = C.bars["bar"..i].autohide
- local hide_time = C.bars["bar"..i].hide_time
- local hide_combat = C.bars["bar"..i].hide_combat == "1" and true or nil
-
- local buttons = tonumber(C.bars["bar"..i].buttons) or 12
- if i == 11 and bars[i] then -- shapeshift buttons
- buttons = GetNumShapeshiftForms()
- elseif i == 12 and bars[i] then -- pet buttons
- buttons = NUM_PET_ACTION_SLOTS
- elseif i == 12 or i == 11 then
- -- Fallback to 10 buttons on shapeshift and petbar during initialization.
- -- This lets us load bars that aren't yet available for your class or level.
- buttons = 10
- end
-
- -- don't process empty bars
- if buttons == 0 then
- bars[i]:Hide()
- return
- end
-
- -- the stored layout is invalid, temporary fallback
- if not pfGridmath[buttons][BarLayoutFormfactor(formfactor)] then
- formfactor = BarLayoutOptions(buttons)[1]
- end
-
- local font = pfUI.font_unit
- local font_size = C.global.font_unit_size
-
- local realsize = size+border*2
-
- -- create frame
- local init = not bars[i]
- bars[i] = bars[i] or CreateFrame("Frame", "pfActionBar" .. barnames[i], UIParent, ACTIONBAR_SECURE_TEMPLATE_BAR)
- bars[i]:SetID(i)
-
- -- autohide
- if autohide == "1" then
- EnableAutohide(bars[i], tonumber(hide_time), hide_combat)
- else
- DisableAutohide(bars[i])
- end
-
- -- apply visible settings
- if enable == "1" then
- -- handle pet bar
- if i == 12 then
- if pfUI.client > 11200 then
- if InCombatLockdown and InCombatLockdown() then
- -- don't process those events during combat
- else
- -- set state driver for pet bars
- bars[i]:SetAttribute("unit", "pet")
- local visibility = pfUI.unlock and pfUI.unlock:IsShown() and "show" or petvisibility
- if bars[i].visibility ~= visibility then
- RegisterStateDriver(bars[i], 'visibility', visibility)
- bars[i].visibility = visibility
- end
- end
- else
- -- only show when pet actions exists
- if PetHasActionBar() or pfUI.unlock and pfUI.unlock:IsShown() then
- bars[i]:Show()
- else
- bars[i]:Hide()
- end
-
- -- show/hide petbar on petbar updates
- if init then
- bars[i]:RegisterEvent("PET_BAR_UPDATE")
- bars[i]:SetScript("OnEvent", function()
- -- hide obsolete buttons
- for i=1, NUM_PET_ACTION_SLOTS do
- if not PetHasActionBar() and bars[12][i] then
- bars[12][i]:Hide()
- end
- end
- -- refresh layout
- CreateActionBar(12)
- end)
- end
- end
-
- -- handle shapeshift bar
- elseif i == 11 then
- -- only show when shapeshifts exist
- if GetNumShapeshiftForms() > 0 then
- bars[i]:Show()
- else
- bars[i]:Hide()
- end
-
- -- update shapeshift bar when amount of spells changes
- if init then
- bars[i]:RegisterEvent("PLAYER_ENTERING_WORLD")
- bars[i]:RegisterEvent("UPDATE_BONUS_ACTIONBAR")
- bars[i]:RegisterEvent("UPDATE_SHAPESHIFT_FORMS")
- bars[i]:SetScript("OnEvent", function()
- local count = GetNumShapeshiftForms()
- if count ~= this.lastCount then
- this.lastCount = count
-
- -- hide obsolete buttons
- for i=1, NUM_SHAPESHIFT_SLOTS do
- if i > GetNumShapeshiftForms() and bars[11][i] then
- bars[11][i]:Hide()
- end
- end
-
- -- create new buttons and refresh layout
- CreateActionBar(11)
- end
- end)
- end
-
- -- regular bars
- else
- bars[i]:Show()
- end
-
- elseif enable == "0" then
- bars[i]:UnregisterAllEvents()
- bars[i]:Hide()
- end
-
- -- create action buttons
- local maxbuttons = (i == 11 or i == 12) and 10 or 12
- for j=1,maxbuttons do
- bars[i][j] = CreateActionButton(bars[i], i, j)
- bars[i][j].bar = i
-
- BarButtonAnchor(bars[i][j], buttonbasename, j, buttons, formfactor, size, border, spacing)
- bars[i][j]:ClearAllPoints()
- bars[i][j]:SetPoint(unpack(bars[i][j]._anchor))
- bars[i][j]:Show()
-
- if i > 10 then
- bars[i][j].id = j
- end
-
- -- refresh button
- updatecache[bars[i][j].slot] = true
- end
-
- for j=buttons+1,12 do
- if bars[i][j] then
- bars[i][j]:Hide()
- end
- end
-
- -- add up to 0-11 button parent states to each bar
- if i <= 10 and pfUI.client > 11200 then
- bars[i]:SetAttribute("statebutton", "0:S0;1:S1;2:S2;3:S3;4:S4;5:S5;6:S6;7:S7;8:S8;9:S9;10:S10;11:S11;")
- bars[i]:SetAttribute("statebutton2", "0:S0Right;1:S1Right;2:S2Right;3:S3Right;4:S4Right;5:S5Right;6:S6Right;7:S7Right;8:S8Right;9:S9Right;10:S10Right;11:S11Right;")
- end
-
- -- enable paging for the first actionbar
- if i == 1 then
- EnablePaging(bars[i])
- end
-
- -- adjust actionbar size
- BarLayoutSize(bars[i], buttons, formfactor, size, border, spacing)
- bars[i]:SetWidth(bars[i]._size[1])
- bars[i]:SetHeight(bars[i]._size[2])
- bars[i]:ClearAllPoints()
- if i == 1 then -- main
- bars[i]:SetPoint("BOTTOM", 0, 2*border)
- elseif i == 3 then -- left
- bars[i]:SetPoint("BOTTOMLEFT", bars[1], "BOTTOMRIGHT", 3*border, 0)
- elseif i == 4 then -- vertical
- bars[i]:SetPoint("RIGHT", -2*border, 0)
- elseif i == 5 then -- right
- bars[i]:SetPoint("BOTTOMRIGHT", bars[1], "BOTTOMLEFT", -3*border, 0)
- elseif i == 6 then -- top
- bars[i]:SetPoint("BOTTOM", bars[1], "TOP", 0, -spacing)
- elseif i == 11 then -- stances
- bars[i]:SetPoint("BOTTOM", bars[6], "TOP", 0, 3*border)
- elseif i == 12 then -- pet
- bars[i]:SetPoint("BOTTOM", bars[6], "TOP", 0, 3*border)
-
- -- make stance bar dodge by default
- bars[i]:SetScript("OnShow", function()
- if bars[11] and bars[11]:IsShown() then
- bars[11]:ClearAllPoints()
- bars[11]:SetPoint("BOTTOM", bars[12], "TOP", 0, 3*border)
- UpdateMovable(bars[11], true)
- end
- end)
-
- -- restore old stance bar position
- bars[i]:SetScript("OnHide", function()
- if bars[11] and bars[11]:IsShown() then
- bars[11]:ClearAllPoints()
- bars[11]:SetPoint("BOTTOM", bars[6], "TOP", 0, 3*border)
- UpdateMovable(bars[11], true)
- end
- end)
- else -- others
- bars[i]:SetPoint("TOP", 0, -i*50)
- end
-
- UpdateMovable(bars[i])
-
- -- apply backdrop settings
- if background == "1" then
- CreateBackdrop(bars[i], border)
- CreateBackdropShadow(bars[i])
- bars[i].backdrop:Show()
- elseif bars[i].backdrop then
- bars[i].backdrop:Hide()
- end
-
- -- share backdrop of main and top actionbar
- if bars[6] and bars[1] then
- bars[6].OnMove = bars[6].OnMove or function()
- bars[1].mergedBackdrop = bars[1].mergedBackdrop or CreateFrame("Frame", nil, UIParent)
- bars[1].mergedBackdrop:SetPoint("TOPLEFT", bars[6], "TOPLEFT", 0, 0)
- bars[1].mergedBackdrop:SetPoint("BOTTOMRIGHT", bars[1], "BOTTOMRIGHT", 0, 0)
- CreateBackdrop(bars[1].mergedBackdrop)
-
- local _, anchor, _ = bars[6]:GetPoint()
- if anchor == bars[1] and C.bars.bar1.enable == "1"
- and C.bars.bar1.enable == "1" and C.bars.bar6.enable == "1"
- and C.bars.bar1.background == "1" and C.bars.bar6.background == "1"
- and C.bars.bar1.autohide == "0" and C.bars.bar6.autohide == "0"
- and C.bars.bar1.icon_size == C.bars.bar6.icon_size
- and C.bars.bar1.spacing == C.bars.bar6.spacing
- and C.bars.bar1.formfactor == C.bars.bar6.formfactor
- and C.bars.bar1.buttons == C.bars.bar6.buttons
- then
- bars[1].mergedBackdrop:Show()
-
- if C.bars.bar1.background == "1" and bars[1].backdrop then
- bars[1].backdrop:Hide()
- end
-
- if C.bars.bar6.background == "1" and bars[6].backdrop then
- bars[6].backdrop:Hide()
- end
- else
- bars[1].mergedBackdrop:Hide()
-
- if C.bars.bar1.background == "1" and bars[1].backdrop then
- bars[1].backdrop:Show()
- end
-
- if C.bars.bar6.background == "1" and bars[6].backdrop then
- bars[6].backdrop:Show()
- end
- end
- end
- bars[6].OnMove()
- end
- end
-
- -- create actionbars
- pfUI.bars = bars
- pfUI.bars.update = updatecache
- pfUI.bars.buttons = buttoncache
- pfUI.bars.ButtonFullUpdate = ButtonFullUpdate
- pfUI.bars.ButtonEnter = ButtonEnter
- pfUI.bars.ButtonLeave = ButtonLeave
-
- pfUI.bars.UpdateGrid = function(self, state, typ)
- if not typ then
- showgrid = state
-
- for id in pairs(buttoncache) do
- updatecache[id] = true
- end
- elseif typ == "PET" then
- showgrid_pet = state
- for slot=133,142 do
- updatecache[slot] = true
- end
- end
- end
-
- pfUI.bars.UpdateConfig = function(self)
- for i=1,12 do
- CreateActionBar(i)
- end
- end
-
- pfUI.bars:UpdateConfig()
-
- -- Localize custom keybinds for additional actionbars (see Bindings.xml)
- local names = {
- ["PAGING"] = T["Paging Actionbar"],
- ["STANCEONE"] = T["Stance Bar 1"],
- ["STANCETWO"] = T["Stance Bar 2"],
- ["STANCETHREE"] = T["Stance Bar 3"],
- ["STANCEFOUR"] = T["Stance Bar 4"],
- }
-
- for name, loc in pairs(names) do
- _G["BINDING_HEADER_PFBAR"..name] = T["Action Bar"] .. " " .. loc
- for i=1,12 do
- _G["BINDING_NAME_PF" .. name .. i] = loc .. " " .. T["Button"] .. " " .. i
- end
- end
-
- -- Map Keybinds to button clicks
- function _G.pfActionButton(slot, slfcast, opt)
- if ChatFrameEditBox:IsShown() then return end
-
- local bar, button = 1, slot
-
- -- determine the proper bar and button
- if opt and blizzbarmapping[opt] then
- bar = blizzbarmapping[opt]
- elseif slot > 12 then
- bar, button = ceil(slot/12), mod(slot, 12)
- button = button == 0 and 12 or button
- end
-
- local frame = bars[bar][button]
- if frame then
- frame.slfcast = slfcast
- frame:Click()
- end
- end
-
- -- Set keybinds to all actionbuttons
- if pfUI.client <= 11200 then
- -- In order to be able to reuse already defined keybinds, we need to remap
- -- existing button functions to pfUI. We need to get rid of the blizzard calls
- -- to avoid having them call texture changes and errors due to missing buttons
- _G.ActionButtonDown = pfActionButton
- _G.ActionButtonUp = pfActionButton
- _G.BonusActionButtonDown = function(slot) pfActionButton(slot, nil, "BonusActionBar") end
- _G.BonusActionButtonUp = function(slot) pfActionButton(slot, nil, "BonusActionBar") end
- _G.MultiActionButtonDown = function(bar, slot, slf) pfActionButton(slot, slf, bar) end
- _G.MultiActionButtonUp = function(bar, slot, slf) pfActionButton(slot, slf, bar) end
- _G.ShapeshiftBar_ChangeForm = function(slot) pfActionButton(slot, nil, "ShapeShiftBar") end
- else
- local bindwraps = {
- ["ACTIONBUTTON%d"] = 1,
- ["SHAPESHIFTBUTTON%d"] = 11, -- ShapeShiftBar
- ["BONUSACTIONBUTTON%d"] = 12, -- BonusActionBar
- ["MULTIACTIONBAR1BUTTON%d"] = 6, -- MultiBarBottomLeft
- ["MULTIACTIONBAR2BUTTON%d"] = 5, -- MultiBarBottomRight
- ["MULTIACTIONBAR3BUTTON%d"] = 3, -- MultiBarRight
- ["MULTIACTIONBAR4BUTTON%d"] = 4, -- MultiBarLeft
- ["PFPAGING%d"] = 2,
- ["PFSTANCEONE%d"] = 7,
- ["PFSTANCETWO%d"] = 8,
- ["PFSTANCETHREE%d"] = 9,
- ["PFSTANCEFOUR%d"] = 10,
- }
-
- -- rebind all existing bindings to our own buttons
- local keybinder = CreateFrame("Frame")
- keybinder:RegisterEvent("UPDATE_BINDINGS")
- keybinder:SetScript("OnEvent", function()
- for name, bar in pairs(bindwraps) do
- for i=1,12 do
- local key = GetBindingKey(format(name, i))
- local button = bars[bar][i]
- if key and button then
- SetOverrideBindingClick(button, false, key, button:GetName(), 'LeftButton')
- end
- end
- end
- end)
- end
-
- -- handle drag-drop grid
- local grid = CreateFrame("Frame")
- grid:RegisterEvent("ACTIONBAR_SHOWGRID")
- grid:RegisterEvent("ACTIONBAR_HIDEGRID")
- grid:RegisterEvent("PET_BAR_SHOWGRID")
- grid:RegisterEvent("PET_BAR_HIDEGRID")
-
- grid:SetScript("OnEvent", function()
- if event == "ACTIONBAR_SHOWGRID" then
- pfUI.bars:UpdateGrid(1)
- elseif event == "ACTIONBAR_HIDEGRID" then
- pfUI.bars:UpdateGrid(0)
- elseif event == "PET_BAR_SHOWGRID" then
- pfUI.bars:UpdateGrid(1, "PET")
- elseif event == "PET_BAR_HIDEGRID" then
- pfUI.bars:UpdateGrid(0, "PET")
- end
- end)
-
- -- reagent counter
- if C.bars.reagents == "1" then
- local reagent_slots = { }
- local reagent_counts = { }
- local reagent_capture = SPELL_REAGENTS.."(.+)"
- local scanner = libtipscan:GetScanner("actionbar")
-
- local UpdateSlot = function(slot)
- local texture = GetActionTexture(slot)
-
- -- update buttons that previously had an reagent
- if reagent_slots[slot] and not HasAction(slot) then
- reagent_slots[slot] = nil
- updatecache[slot] = true
- end
-
- -- search for reagent requirements
- if HasAction(slot) then
- scanner:SetAction(slot)
- local _, reagents = scanner:Find(reagent_capture)
-
- -- remove reagent counts if existing
- reagents = reagents and string.gsub(reagents, " %((.+)%)", "")
-
- -- update on reagent requirement changes
- if reagents and reagent_slots[slot] ~= reagents then
- reagent_counts[reagents] = reagent_counts[reagents] or 0
- reagent_slots[slot] = reagents
- updatecache[slot] = true
- end
- end
- end
-
- local reagentcounter = CreateFrame("Frame", "pfReagentCounter", UIParent)
- reagentcounter:RegisterEvent("PLAYER_ENTERING_WORLD")
- reagentcounter:RegisterEvent("ACTIONBAR_SLOT_CHANGED")
- reagentcounter:RegisterEvent("BAG_UPDATE")
- reagentcounter:SetScript("OnEvent", function()
- if event == "BAG_UPDATE" then
- this.event = true
- else
- this.scan = 1
- end
- end)
-
- -- limit events to one per second and smoothen action scanning
- reagentcounter:SetScript("OnUpdate", function()
- -- scan one action slot per frame
- if this.scan and this.scan <= 120 then
- UpdateSlot(this.scan)
- this.scan = this.scan + 1
- end
-
- -- trigger reagent count updates after action scans
- if this.scan and this.scan >= 120 then
- this.event = true
- this.scan = nil
- end
-
- -- queue events to fire only once per second
- if not this.event then return end
- if ( this.tick or 1) > GetTime() then return else this.tick = GetTime() + 1 end
-
- -- scan for all reagent item counts
- for item in pairs(reagent_counts) do
- reagent_counts[item] = GetItemCount(item)
- end
-
- -- update all actionbar buttons
- for slot in pairs(reagent_slots) do
- updatecache[slot] = true
- end
-
- -- remove event trigger
- this.event = nil
- end)
-
- function IsReagentAction(slot)
- return reagent_slots[slot] and true or nil
- end
-
- function GetReagentCount(slot)
- return reagent_counts[reagent_slots[slot]]
- end
- end
-end)
From bf20d3ea33218923d198ed62231628e87a0122a4 Mon Sep 17 00:00:00 2001
From: Meow <30401521+me0wg4ming@users.noreply.github.com>
Date: Tue, 6 Jan 2026 17:10:40 +0100
Subject: [PATCH 34/40] Module nil check fix
Please if you create modules, make sure you have failsafe checks for nil values. thanks...
---
modules/nampower.lua | 169 ++++++++++++++++++++++---------------------
1 file changed, 88 insertions(+), 81 deletions(-)
diff --git a/modules/nampower.lua b/modules/nampower.lua
index 8e71ecc5..a8d62dfc 100644
--- a/modules/nampower.lua
+++ b/modules/nampower.lua
@@ -111,7 +111,7 @@ pfUI:RegisterModule("nampower", "vanilla", function ()
if SpellInfo then
spellName, spellRank, texture = SpellInfo(spellId)
end
- if GetSpellNameAndRankForId then
+ if not spellName and GetSpellNameAndRankForId then
spellName, spellRank = GetSpellNameAndRankForId(spellId)
end
@@ -123,9 +123,9 @@ pfUI:RegisterModule("nampower", "vanilla", function ()
end
-- Try GetSpellRec for duration if libdebuff doesn't have it
- if duration == 0 and GetSpellRec then
- local spellRec = GetSpellRec(spellId)
- if spellRec and spellRec.durationIndex and spellRec.durationIndex > 0 then
+ if duration == 0 and GetSpellRec and spellId then
+ local success, spellRec = pcall(GetSpellRec, spellId)
+ if success and spellRec and spellRec.durationIndex and spellRec.durationIndex > 0 then
-- Duration index maps to spell duration - common values:
-- This is a rough approximation since we don't have the duration table
duration = 30 -- Default fallback
@@ -170,21 +170,25 @@ pfUI:RegisterModule("nampower", "vanilla", function ()
local effect, rank, texture, stacks, dtype, duration, timeleft, caster = originalUnitDebuff(self, unit, id)
-- If we have Nampower data for this unit, try to enhance it
- local _, guid = UnitExists(unit)
- if guid and debuffdb[guid] then
- -- Find the debuff by slot
- for spellId, data in pairs(debuffdb[guid]) do
- if data.slot == id then
- -- Use Nampower data for more accurate timing
- if data.duration and data.duration > 0 and data.start then
- duration = data.duration
- timeleft = data.duration + data.start - GetTime()
- if timeleft < 0 then timeleft = 0 end
- caster = data.caster
- stacks = data.stacks or stacks
- end
- break
+ if not UnitExists then return effect, rank, texture, stacks, dtype, duration, timeleft, caster end
+
+ local exists, guid = UnitExists(unit)
+ if not exists or not guid or not debuffdb[guid] then
+ return effect, rank, texture, stacks, dtype, duration, timeleft, caster
+ end
+
+ -- Find the debuff by slot
+ for spellId, data in pairs(debuffdb[guid]) do
+ if data.slot == id then
+ -- Use Nampower data for more accurate timing
+ if data.duration and data.duration > 0 and data.start then
+ duration = data.duration
+ timeleft = data.duration + data.start - GetTime()
+ if timeleft < 0 then timeleft = 0 end
+ caster = data.caster
+ stacks = data.stacks or stacks
end
+ break
end
end
@@ -222,20 +226,22 @@ pfUI:RegisterModule("nampower", "vanilla", function ()
if SpellInfo then
spellName, spellRank, texture = SpellInfo(spellId)
end
- if GetSpellNameAndRankForId then
+ if not spellName and GetSpellNameAndRankForId then
spellName, spellRank = GetSpellNameAndRankForId(spellId)
end
- buffdb[guid][spellId] = {
- spellId = spellId,
- name = spellName,
- rank = spellRank,
- texture = texture,
- stacks = stackCount or 1,
- start = GetTime(),
- slot = slot,
- auraLevel = auraLevel
- }
+ if spellName then
+ buffdb[guid][spellId] = {
+ spellId = spellId,
+ name = spellName,
+ rank = spellRank,
+ texture = texture,
+ stacks = stackCount or 1,
+ start = GetTime(),
+ slot = slot,
+ auraLevel = auraLevel
+ }
+ end
elseif event == "BUFF_REMOVED_OTHER" or event == "BUFF_REMOVED_SELF" then
if buffdb[guid] and buffdb[guid][spellId] then
buffdb[guid][spellId] = nil
@@ -294,13 +300,13 @@ pfUI:RegisterModule("nampower", "vanilla", function ()
local res = GetUnitField(unit, "resistances")
if not res then return nil end
return {
- armor = res[1],
- holy = res[2],
- fire = res[3],
- nature = res[4],
- frost = res[5],
- shadow = res[6],
- arcane = res[7]
+ armor = res[1] or 0,
+ holy = res[2] or 0,
+ fire = res[3] or 0,
+ nature = res[4] or 0,
+ frost = res[5] or 0,
+ shadow = res[6] or 0,
+ arcane = res[7] or 0
}
end
end
@@ -389,13 +395,13 @@ pfUI:RegisterModule("nampower", "vanilla", function ()
local cd = GetSpellIdCooldown(spellId)
if not cd then return nil end
return {
- onCooldown = cd.isOnCooldown == 1,
- remaining = cd.cooldownRemainingMs / 1000,
- remainingMs = cd.cooldownRemainingMs,
- gcdRemaining = cd.gcdCategoryRemainingMs / 1000,
- gcdRemainingMs = cd.gcdCategoryRemainingMs,
- individualRemaining = cd.individualRemainingMs / 1000,
- categoryRemaining = cd.categoryRemainingMs / 1000,
+ onCooldown = (cd.isOnCooldown or 0) == 1,
+ remaining = (cd.cooldownRemainingMs or 0) / 1000,
+ remainingMs = cd.cooldownRemainingMs or 0,
+ gcdRemaining = (cd.gcdCategoryRemainingMs or 0) / 1000,
+ gcdRemainingMs = cd.gcdCategoryRemainingMs or 0,
+ individualRemaining = (cd.individualRemainingMs or 0) / 1000,
+ categoryRemaining = (cd.categoryRemainingMs or 0) / 1000,
}
end
@@ -405,9 +411,9 @@ pfUI:RegisterModule("nampower", "vanilla", function ()
local cd = GetItemIdCooldown(itemId)
if not cd then return nil end
return {
- onCooldown = cd.isOnCooldown == 1,
- remaining = cd.cooldownRemainingMs / 1000,
- remainingMs = cd.cooldownRemainingMs,
+ onCooldown = (cd.isOnCooldown or 0) == 1,
+ remaining = (cd.cooldownRemainingMs or 0) / 1000,
+ remainingMs = cd.cooldownRemainingMs or 0,
}
end
end
@@ -433,9 +439,10 @@ pfUI:RegisterModule("nampower", "vanilla", function ()
if GetTrinkets then
pfUI.api.GetEquippedTrinkets = function()
local trinkets = GetTrinkets()
+ if not trinkets then return {} end
local equipped = {}
for _, trinket in pairs(trinkets) do
- if trinket.bagIndex == nil then -- nil bagIndex = equipped
+ if trinket and trinket.bagIndex == nil then -- nil bagIndex = equipped
table.insert(equipped, trinket)
end
end
@@ -445,11 +452,11 @@ pfUI:RegisterModule("nampower", "vanilla", function ()
pfUI.api.GetTrinketCooldown = function(slot)
if not GetTrinketCooldown then return nil end
local cd = GetTrinketCooldown(slot)
- if cd == -1 then return nil end
+ if cd == -1 or not cd then return nil end
return {
- onCooldown = cd.isOnCooldown == 1,
- remaining = cd.cooldownRemainingMs / 1000,
- remainingMs = cd.cooldownRemainingMs,
+ onCooldown = (cd.isOnCooldown or 0) == 1,
+ remaining = (cd.cooldownRemainingMs or 0) / 1000,
+ remainingMs = cd.cooldownRemainingMs or 0,
}
end
@@ -473,7 +480,7 @@ pfUI:RegisterModule("nampower", "vanilla", function ()
return GetItemLevel(itemId)
end
local success, stats = pcall(GetItemStats, itemId, true)
- if success and stats then
+ if success and stats and stats.itemLevel then
return stats.itemLevel
end
return nil
@@ -587,41 +594,41 @@ pfUI:RegisterModule("nampower", "vanilla", function ()
-- Spell Database Access via GetSpellRec
if GetSpellRec then
pfUI.api.GetSpellRecord = function(spellId)
- local rec = GetSpellRec(spellId)
- if not rec then return nil end
+ local success, rec = pcall(GetSpellRec, spellId)
+ if not success or not rec then return nil end
return {
spellId = spellId,
- name = rec.name,
- rank = rec.rank,
- description = rec.description,
- manaCost = rec.manaCost,
- baseLevel = rec.baseLevel,
- spellLevel = rec.spellLevel,
- maxLevel = rec.maxLevel,
- maxTargetLevel = rec.maxTargetLevel,
- maxTargets = rec.maxTargets,
- durationIndex = rec.durationIndex,
- powerType = rec.powerType,
- rangeIndex = rec.rangeIndex,
- speed = rec.speed,
- schoolMask = rec.schoolMask,
- runeCostID = rec.runeCostID,
- spellMissileID = rec.spellMissileID,
- iconID = rec.iconID,
- activeIconID = rec.activeIconID,
- nameSubtext = rec.nameSubtext,
- castingTimeIndex = rec.castingTimeIndex,
- categoryRecoveryTime = rec.categoryRecoveryTime,
- recoveryTime = rec.recoveryTime,
- startRecoveryCategory = rec.startRecoveryCategory,
- startRecoveryTime = rec.startRecoveryTime,
+ name = rec.name or "",
+ rank = rec.rank or "",
+ description = rec.description or "",
+ manaCost = rec.manaCost or 0,
+ baseLevel = rec.baseLevel or 0,
+ spellLevel = rec.spellLevel or 0,
+ maxLevel = rec.maxLevel or 0,
+ maxTargetLevel = rec.maxTargetLevel or 0,
+ maxTargets = rec.maxTargets or 0,
+ durationIndex = rec.durationIndex or 0,
+ powerType = rec.powerType or 0,
+ rangeIndex = rec.rangeIndex or 0,
+ speed = rec.speed or 0,
+ schoolMask = rec.schoolMask or 0,
+ runeCostID = rec.runeCostID or 0,
+ spellMissileID = rec.spellMissileID or 0,
+ iconID = rec.iconID or 0,
+ activeIconID = rec.activeIconID or 0,
+ nameSubtext = rec.nameSubtext or "",
+ castingTimeIndex = rec.castingTimeIndex or 0,
+ categoryRecoveryTime = rec.categoryRecoveryTime or 0,
+ recoveryTime = rec.recoveryTime or 0,
+ startRecoveryCategory = rec.startRecoveryCategory or 0,
+ startRecoveryTime = rec.startRecoveryTime or 0,
}
end
-- Get spell school (fire, frost, nature, etc.)
pfUI.api.GetSpellSchool = function(spellId)
- local rec = GetSpellRec(spellId)
- if not rec then return nil end
+ local success, rec = pcall(GetSpellRec, spellId)
+ if not success or not rec or not rec.schoolMask then return nil end
local schools = {
[1] = "Physical",
[2] = "Holy",
@@ -740,4 +747,4 @@ pfUI:RegisterModule("nampower", "vanilla", function ()
},
}
end
-end)
+end)
\ No newline at end of file
From 37e7b5af8d30e5b04069738b671dc84a72c8d9ae Mon Sep 17 00:00:00 2001
From: Meow <30401521+me0wg4ming@users.noreply.github.com>
Date: Tue, 6 Jan 2026 20:43:12 +0100
Subject: [PATCH 35/40] unit updateframes_fix
Fixed "Use Raid Frames to display group members" not updating the frames when people recieved dmg
---
api/unitframes.lua | 18 +++++++++++-------
1 file changed, 11 insertions(+), 7 deletions(-)
diff --git a/api/unitframes.lua b/api/unitframes.lua
index e9a4eb81..b94592f0 100644
--- a/api/unitframes.lua
+++ b/api/unitframes.lua
@@ -31,17 +31,21 @@ pfUI.uf.RebuildUnitmap = function()
if pfUI.uf.raid then
for i = 1, 40 do
local frame = pfUI.uf.raid[i]
- if frame and frame.id and frame.id ~= 0 then
- pfUI.uf.unitmap["raid" .. frame.id] = frame
+ if frame and frame.id and frame.id ~= 0 and frame.label then
+ -- ✅ Jetzt auch party-Frames in Raid-Frames unterstützen
+ local unitstr = frame.label .. frame.id
+ pfUI.uf.unitmap[unitstr] = frame
end
end
end
- -- Rebuild party mappings
- for i = 1, 4 do
- local frame = _G["pfGroup" .. i]
- if frame and frame.label == "party" then
- pfUI.uf.unitmap["party" .. frame.id] = frame
+ -- Rebuild party mappings (nur wenn nicht als Raid verwendet)
+ if C.unitframes.raidforgroup ~= "1" then
+ for i = 1, 4 do
+ local frame = _G["pfGroup" .. i]
+ if frame and frame.label == "party" then
+ pfUI.uf.unitmap["party" .. frame.id] = frame
+ end
end
end
end
From 205589c2252c95ca88676902391cef6dde098d6d Mon Sep 17 00:00:00 2001
From: Meow <30401521+me0wg4ming@users.noreply.github.com>
Date: Wed, 7 Jan 2026 23:39:43 +0100
Subject: [PATCH 36/40] performance improvement
Implemented throttle to update nameplates of non-targets to 0.2 times per second and target to 0.05 seconds
---
modules/nameplates.lua | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/modules/nameplates.lua b/modules/nameplates.lua
index 1835b99a..6f69fc96 100644
--- a/modules/nameplates.lua
+++ b/modules/nameplates.lua
@@ -878,12 +878,19 @@ pfUI:RegisterModule("nameplates", "vanilla", function ()
end
nameplates.OnUpdate = function(frame)
- local update
local frame = frame or this
local nameplate = frame.nameplate
+
+ -- Throttle: Update target more frequently than other nameplates
+ local target = UnitExists("target") and frame:GetAlpha() == 1 or nil
+ local throttle = target and 0.05 or 0.2
+
+ if (nameplate.lasttick or 0) + throttle > GetTime() then return end
+ nameplate.lasttick = GetTime()
+
+ local update
local original = nameplate.original
local name = original.name:GetText()
- local target = UnitExists("target") and frame:GetAlpha() == 1 or nil
local mouseover = UnitExists("mouseover") and original.glow:IsShown() or nil
local namefightcolor = C.nameplates.namefightcolor == "1"
From 30bffa9a6958ec3eae8653b561936993c1a0aab3 Mon Sep 17 00:00:00 2001
From: Meow <30401521+me0wg4ming@users.noreply.github.com>
Date: Thu, 8 Jan 2026 01:29:02 +0100
Subject: [PATCH 37/40] nameplate update
Using a new variant for nameplates.
If player uses superwow it will use unit_castevent for the nameplates.
If player doesn't have superwow it will automatically use a fallback logic.
---
modules/nameplates.lua | 272 ++++++++++++++++++++++++++++-------------
1 file changed, 189 insertions(+), 83 deletions(-)
diff --git a/modules/nameplates.lua b/modules/nameplates.lua
index 6f69fc96..73ef3cf8 100644
--- a/modules/nameplates.lua
+++ b/modules/nameplates.lua
@@ -2,8 +2,9 @@ pfUI:RegisterModule("nameplates", "vanilla", function ()
-- disable original castbars
pcall(SetCVar, "ShowVKeyCastbar", 0)
- -- check for SuperWoW support
- local superwow_active = HasSuperWoW()
+ -- check for SuperWoW support (use SUPERWOW_VERSION global)
+ local superwow_active = SUPERWOW_VERSION ~= nil
+ --print("pfUI Nameplates: SuperWoW " .. (superwow_active and "ACTIVE" or "INACTIVE"))
local unitcolors = {
["ENEMY_NPC"] = { .9, .2, .3, .8 },
@@ -40,6 +41,10 @@ pfUI:RegisterModule("nameplates", "vanilla", function ()
local registry = {}
local debuffdurations = C.appearance.cd.debuffs == "1" and true or nil
+ -- NEW: Cast event cache like Overhead.lua
+ local CastEvents = {}
+ local _, PlayerGUID = UnitExists("player")
+
-- cache default border color
local er, eg, eb, ea = GetStringColor(pfUI_config.appearance.border.color)
@@ -70,6 +75,15 @@ pfUI:RegisterModule("nameplates", "vanilla", function ()
return
end
+ local function wipe(table)
+ if type(table) ~= "table" then
+ return
+ end
+ for k in pairs(table) do
+ table[k] = nil
+ end
+ end
+
local function IsNamePlate(frame)
if frame:GetObjectType() ~= NAMEPLATE_FRAMETYPE then return nil end
regions = plate:GetRegions()
@@ -314,18 +328,65 @@ pfUI:RegisterModule("nameplates", "vanilla", function ()
nameplates:RegisterEvent("UNIT_COMBO_POINTS")
nameplates:RegisterEvent("PLAYER_COMBO_POINTS")
nameplates:RegisterEvent("UNIT_AURA")
+
+ -- NEW: Register cast events like Overhead.lua
+ if superwow_active then
+ nameplates:RegisterEvent("UNIT_CASTEVENT")
+ end
nameplates:SetScript("OnEvent", function()
if event == "PLAYER_ENTERING_WORLD" then
this:SetGameVariables()
+ elseif event == "UNIT_CASTEVENT" then
+ -- NEW: Event-based cast handling from Overhead.lua
+ local casterGUID = arg1
+ if casterGUID == PlayerGUID then return end
+
+ local eventType = arg3 -- "START", "CAST", "FAIL", "CHANNEL"
+ local spellID = arg4
+ local castDuration = arg5
+ local spellName, _, icon = SpellInfo(spellID)
+
+ if eventType == "MAINHAND" or eventType == "OFFHAND" then
+ return
+ end
+
+ if eventType == "CAST" then
+ if not CastEvents[casterGUID] or spellID ~= CastEvents[casterGUID].spell then
+ return
+ end
+ end
+
+ if eventType == "START" or eventType == "CHANNEL" then
+ if not CastEvents[casterGUID] then
+ CastEvents[casterGUID] = {}
+ end
+ wipe(CastEvents[casterGUID])
+ CastEvents[casterGUID].event = eventType
+ CastEvents[casterGUID].spellID = spellID
+ CastEvents[casterGUID].spellName = spellName
+ CastEvents[casterGUID].icon = icon
+ CastEvents[casterGUID].startTime = GetTime()
+ CastEvents[casterGUID].endTime = castDuration and GetTime() + castDuration / 1000
+ CastEvents[casterGUID].duration = castDuration and castDuration / 1000 or nil
+ elseif eventType == "FAIL" then
+ if CastEvents[casterGUID] then
+ wipe(CastEvents[casterGUID])
+ end
+ end
+
+ -- Propagate cast event to all nameplates
+ for plate in pairs(registry) do
+ plate.eventcache = true
+ end
else
this.eventcache = true
end
end)
nameplates:SetScript("OnUpdate", function()
- -- throttle to 10 updates per second instead of every frame
- if (this.tick or 0.1) > GetTime() then return else this.tick = GetTime() + 0.1 end
+ -- Throttle main scanner to reasonable rate
+ if (this.tick or 0) > GetTime() then return else this.tick = GetTime() + 0.05 end
-- propagate events to all nameplates
if this.eventcache then
@@ -881,9 +942,9 @@ pfUI:RegisterModule("nameplates", "vanilla", function ()
local frame = frame or this
local nameplate = frame.nameplate
- -- Throttle: Update target more frequently than other nameplates
+ -- OPTIMIZED: Minimal throttle - only skip if very recent update
local target = UnitExists("target") and frame:GetAlpha() == 1 or nil
- local throttle = target and 0.05 or 0.2
+ local throttle = target and 0.01 or 0.05
if (nameplate.lasttick or 0) + throttle > GetTime() then return end
nameplate.lasttick = GetTime()
@@ -900,12 +961,11 @@ pfUI:RegisterModule("nameplates", "vanilla", function ()
nameplate.eventcache = nil
end
- -- reset strata cache on target change
+ -- OPTIMIZED: Cache strata changes
if nameplate.istarget ~= target then
nameplate.target_strata = nil
end
- -- keep target nameplate above others
if target and nameplate.target_strata ~= 1 then
nameplate:SetFrameStrata("LOW")
nameplate.target_strata = 1
@@ -914,15 +974,22 @@ pfUI:RegisterModule("nameplates", "vanilla", function ()
nameplate.target_strata = 0
end
- -- cache target value
nameplate.istarget = target
- -- set non-target plate alpha
+ -- OPTIMIZED: Cache alpha changes
+ local newAlpha
if target or not UnitExists("target") then
- nameplate:SetAlpha(1)
+ newAlpha = 1
else
- frame:SetAlpha(.95)
- nameplate:SetAlpha(tonumber(C.nameplates.notargalpha))
+ newAlpha = tonumber(C.nameplates.notargalpha)
+ end
+
+ if nameplate.cachedAlpha ~= newAlpha then
+ if not target and UnitExists("target") then
+ frame:SetAlpha(.95)
+ end
+ nameplate:SetAlpha(newAlpha)
+ nameplate.cachedAlpha = newAlpha
end
-- queue update on visual target update
@@ -950,7 +1017,7 @@ pfUI:RegisterModule("nameplates", "vanilla", function ()
if namefightcolor then
if r > .9 and g < .2 and b < .2 then
- nameplate.name:SetTextColor(1,0.4,0.2,1) -- infight
+ nameplate.name:SetTextColor(1,0.4,0.2,1)
else
nameplate.name:SetTextColor(r,g,b,1)
end
@@ -990,97 +1057,136 @@ pfUI:RegisterModule("nameplates", "vanilla", function ()
nameplate.tick = GetTime() + .5
end
- -- target zoom
- local w, h = nameplate.health:GetWidth(), nameplate.health:GetHeight()
+ -- OPTIMIZED: Cache zoom dimensions
if target and C.nameplates.targetzoom == "1" then
- local zoomval = tonumber(C.nameplates.targetzoomval)+1
- local wc = tonumber(C.nameplates.width)*zoomval
- local hc = tonumber(C.nameplates.heighthealth)*(zoomval*.9)
- local animation = false
-
+ if not nameplate.health.zoomed then
+ local zoomval = tonumber(C.nameplates.targetzoomval)+1
+ local wc = tonumber(C.nameplates.width)*zoomval
+ local hc = tonumber(C.nameplates.heighthealth)*(zoomval*.9)
+ nameplate.health.targetWidth = wc
+ nameplate.health.targetHeight = hc
+ end
+
+ local w, h = nameplate.health:GetWidth(), nameplate.health:GetHeight()
+ local wc, hc = nameplate.health.targetWidth, nameplate.health.targetHeight
+
if wc >= w then
- wc = w*1.05
- nameplate.health:SetWidth(wc)
+ nameplate.health:SetWidth(w*1.05)
nameplate.health.zoomTransition = true
- animation = true
- end
-
- if hc >= h then
- hc = h*1.05
- nameplate.health:SetHeight(hc)
+ elseif hc >= h then
+ nameplate.health:SetHeight(h*1.05)
nameplate.health.zoomTransition = true
- animation = true
- end
-
- if animation == false and not nameplate.health.zoomed then
- nameplate.health:SetWidth(wc)
- nameplate.health:SetHeight(hc)
- nameplate.health.zoomTransition = nil
+ else
+ if nameplate.health.zoomTransition then
+ nameplate.health:SetWidth(wc)
+ nameplate.health:SetHeight(hc)
+ nameplate.health.zoomTransition = nil
+ end
nameplate.health.zoomed = true
end
elseif nameplate.health.zoomed or nameplate.health.zoomTransition then
+ local w, h = nameplate.health:GetWidth(), nameplate.health:GetHeight()
local wc = tonumber(C.nameplates.width)
local hc = tonumber(C.nameplates.heighthealth)
- local animation = false
if wc <= w then
- wc = w*.95
- nameplate.health:SetWidth(wc)
- animation = true
- end
-
- if hc <= h then
- hc = h*0.95
- nameplate.health:SetHeight(hc)
- animation = true
- end
-
- if animation == false then
+ nameplate.health:SetWidth(w*.95)
+ elseif hc <= h then
+ nameplate.health:SetHeight(h*0.95)
+ else
nameplate.health:SetWidth(wc)
nameplate.health:SetHeight(hc)
nameplate.health.zoomTransition = nil
nameplate.health.zoomed = nil
+ nameplate.health.targetWidth = nil
+ nameplate.health.targetHeight = nil
end
end
- -- castbar update
+ -- OPTIMIZED: Event-based castbar from Overhead.lua
if C.nameplates["showcastbar"] == "1" and ( C.nameplates["targetcastbar"] == "0" or target ) then
- local channel, cast, nameSubtext, text, texture, startTime, endTime, isTradeSkill
-
- -- detect cast or channel bars
- cast, nameSubtext, text, texture, startTime, endTime, isTradeSkill = UnitCastingInfo(target and "target" or name)
- if not cast then channel, nameSubtext, text, texture, startTime, endTime, isTradeSkill = UnitChannelInfo(target and "target" or name) end
-
- -- read enemy casts from SuperWoW if enabled
- if superwow_active then
- cast, nameSubtext, text, texture, startTime, endTime, isTradeSkill = UnitCastingInfo(nameplate.parent:GetName(1))
- if not cast then channel, nameSubtext, text, texture, startTime, endTime, isTradeSkill = UnitChannelInfo(nameplate.parent:GetName(1)) end
+ local unitstr = target and "target" or nil
+
+ -- Use SuperWoW GUID if available
+ if superwow_active and not unitstr then
+ unitstr = nameplate.parent:GetName(1)
end
-
- if not cast and not channel then
- nameplate.castbar:Hide()
- elseif cast or channel then
- local effect = cast or channel
- local duration = endTime - startTime
- local max = duration / 1000
- local cur = GetTime() - startTime / 1000
-
- -- invert castbar values while channeling
- if channel then cur = max + startTime/1000 - GetTime() end
-
- nameplate.castbar:SetMinMaxValues(0, duration/1000)
- nameplate.castbar:SetValue(cur)
- nameplate.castbar.text:SetText(round(cur,1))
- if C.nameplates.spellname == "1" then
- nameplate.castbar.spell:SetText(effect)
+
+ -- Check event-based cast cache first
+ local castInfo = unitstr and CastEvents[unitstr]
+
+ if castInfo and castInfo.spellID then
+ -- Check if cast is still valid
+ if castInfo.startTime + castInfo.duration < GetTime() then
+ wipe(castInfo)
+ nameplate.castbar:Hide()
+ elseif castInfo.event == "CAST" or castInfo.event == "FAIL" then
+ wipe(castInfo)
+ nameplate.castbar:Hide()
else
- nameplate.castbar.spell:SetText("")
+ -- Update from cached event data
+ nameplate.castbar:SetMinMaxValues(castInfo.startTime, castInfo.endTime)
+
+ local barValue
+ if castInfo.event == "CHANNEL" then
+ barValue = castInfo.startTime + (castInfo.endTime - GetTime())
+ else
+ barValue = GetTime()
+ end
+
+ nameplate.castbar:SetValue(barValue)
+ nameplate.castbar.text:SetText(round(GetTime() - castInfo.startTime, 1))
+
+ if C.nameplates.spellname == "1" then
+ nameplate.castbar.spell:SetText(castInfo.spellName)
+ else
+ nameplate.castbar.spell:SetText("")
+ end
+
+ if castInfo.icon then
+ nameplate.castbar.icon.tex:SetTexture(castInfo.icon)
+ nameplate.castbar.icon.tex:SetTexCoord(.1,.9,.1,.9)
+ end
+
+ nameplate.castbar:Show()
end
- nameplate.castbar:Show()
+ else
+ -- Fallback to API calls if no event data (for non-SuperWoW or target)
+ local channel, cast, nameSubtext, text, texture, startTime, endTime, isTradeSkill
+
+ if target then
+ cast, nameSubtext, text, texture, startTime, endTime, isTradeSkill = UnitCastingInfo("target")
+ if not cast then
+ channel, nameSubtext, text, texture, startTime, endTime, isTradeSkill = UnitChannelInfo("target")
+ end
+ end
+
+ if not cast and not channel then
+ nameplate.castbar:Hide()
+ else
+ local effect = cast or channel
+ local duration = endTime - startTime
+ local max = duration / 1000
+ local cur = GetTime() - startTime / 1000
- if texture then
- nameplate.castbar.icon.tex:SetTexture(texture)
- nameplate.castbar.icon.tex:SetTexCoord(.1,.9,.1,.9)
+ if channel then cur = max + startTime/1000 - GetTime() end
+
+ nameplate.castbar:SetMinMaxValues(0, duration/1000)
+ nameplate.castbar:SetValue(cur)
+ nameplate.castbar.text:SetText(round(cur,1))
+
+ if C.nameplates.spellname == "1" then
+ nameplate.castbar.spell:SetText(effect)
+ else
+ nameplate.castbar.spell:SetText("")
+ end
+
+ nameplate.castbar:Show()
+
+ if texture then
+ nameplate.castbar.icon.tex:SetTexture(texture)
+ nameplate.castbar.icon.tex:SetTexCoord(.1,.9,.1,.9)
+ end
end
end
else
@@ -1247,4 +1353,4 @@ pfUI:RegisterModule("nameplates", "vanilla", function ()
end
pfUI.nameplates = nameplates
-end)
+end)
\ No newline at end of file
From 78422d9f277ac586f94a9c06875d10df8260aa1c Mon Sep 17 00:00:00 2001
From: Meow <30401521+me0wg4ming@users.noreply.github.com>
Date: Thu, 8 Jan 2026 01:39:53 +0100
Subject: [PATCH 38/40] an other nameplate update
just adjusting the update rate a little more
---
modules/nameplates.lua | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/modules/nameplates.lua b/modules/nameplates.lua
index 73ef3cf8..8c78e6cc 100644
--- a/modules/nameplates.lua
+++ b/modules/nameplates.lua
@@ -944,7 +944,7 @@ pfUI:RegisterModule("nameplates", "vanilla", function ()
-- OPTIMIZED: Minimal throttle - only skip if very recent update
local target = UnitExists("target") and frame:GetAlpha() == 1 or nil
- local throttle = target and 0.01 or 0.05
+ local throttle = target and 0.02 or 0.10
if (nameplate.lasttick or 0) + throttle > GetTime() then return end
nameplate.lasttick = GetTime()
From 2390e6dfd98b0b20d571abf6cd8a196fa2c62d34 Mon Sep 17 00:00:00 2001
From: Meow <30401521+me0wg4ming@users.noreply.github.com>
Date: Thu, 8 Jan 2026 01:50:28 +0100
Subject: [PATCH 39/40] nameplates...
changed update rate to 0.02 for casts (else it looks to laggy)
---
modules/nameplates.lua | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/modules/nameplates.lua b/modules/nameplates.lua
index 8c78e6cc..89081147 100644
--- a/modules/nameplates.lua
+++ b/modules/nameplates.lua
@@ -944,7 +944,7 @@ pfUI:RegisterModule("nameplates", "vanilla", function ()
-- OPTIMIZED: Minimal throttle - only skip if very recent update
local target = UnitExists("target") and frame:GetAlpha() == 1 or nil
- local throttle = target and 0.02 or 0.10
+ local throttle = target and 0.02 or 0.02
if (nameplate.lasttick or 0) + throttle > GetTime() then return end
nameplate.lasttick = GetTime()
From c94d04ca14a2d70e76f8157f9ed612608e5e899c Mon Sep 17 00:00:00 2001
From: Meow <30401521+me0wg4ming@users.noreply.github.com>
Date: Thu, 8 Jan 2026 01:53:27 +0100
Subject: [PATCH 40/40] comment change :p
---
modules/nameplates.lua | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/modules/nameplates.lua b/modules/nameplates.lua
index 89081147..3f05a2f8 100644
--- a/modules/nameplates.lua
+++ b/modules/nameplates.lua
@@ -1103,7 +1103,7 @@ pfUI:RegisterModule("nameplates", "vanilla", function ()
end
end
- -- OPTIMIZED: Event-based castbar from Overhead.lua
+ -- OPTIMIZED: UNIT_CASTEVENT implementation
if C.nameplates["showcastbar"] == "1" and ( C.nameplates["targetcastbar"] == "0" or target ) then
local unitstr = target and "target" or nil