Quantcast

update healcomm

Ou Junhui [09-05-22 - 22:41]
update healcomm
Filename
oUF/libs/LibHealComm-4.0/LibHealComm-4.0.lua
oUF_Simple/core/functions.lua
oUF_Simple/core/style.lua
oUF_Simple/oUF_Simple.toc
oUF_SimpleConfig/player.lua
oUF_SimpleConfig/raid.lua
rBag/libs/SortBags.lua
rButtonAura/LICENSE.md
rButtonAura/core.lua
rButtonAura/rButtonAura.toc
rButtonAura_Zork/LICENSE.md
rButtonAura_Zork/config.lua
rButtonAura_Zork/rButtonAura_Zork.toc
rButtonTemplate/core.lua
rButtonTemplate_Zork/theme.lua
rCombatText/rCombatText.lua
rFilter/LICENSE.md
rFilter/README.md
rFilter/buff.lua
rFilter/cooldown.lua
rFilter/debuff.lua
rFilter/functions.lua
rFilter/init.lua
rFilter/rFilter.toc
rFilter/timer.lua
rFilter_Zork/LICENSE.md
rFilter_Zork/classes/hunter.lua
rFilter_Zork/classes/rogue.lua
rFilter_Zork/init.lua
rFilter_Zork/rFilter_Zork.toc
rFilter_Zork/theme.lua
rMinimap/core.lua
readme.md
diff --git a/oUF/libs/LibHealComm-4.0/LibHealComm-4.0.lua b/oUF/libs/LibHealComm-4.0/LibHealComm-4.0.lua
index 2a74cc1..e823281 100644
--- a/oUF/libs/LibHealComm-4.0/LibHealComm-4.0.lua
+++ b/oUF/libs/LibHealComm-4.0/LibHealComm-4.0.lua
@@ -1,7 +1,5 @@
-if WOW_PROJECT_ID == WOW_PROJECT_MAINLINE then return end
-
 local major = "LibHealComm-4.0"
-local minor = 100
+local minor = 107
 assert(LibStub, format("%s requires LibStub.", major))

 local HealComm = LibStub:NewLibrary(major, minor)
@@ -19,6 +17,7 @@ local gsub = gsub
 local max = max
 local min = min
 local pairs = pairs
+local ipairs = ipairs
 local rawset = rawset
 local select = select
 local setmetatable = setmetatable
@@ -61,6 +60,7 @@ local SpellIsTargeting = SpellIsTargeting
 local UnitAura = UnitAura
 local UnitCanAssist = UnitCanAssist
 local UnitExists = UnitExists
+local UnitBuff = UnitBuff
 local UnitGUID = UnitGUID
 local UnitIsCharmed = UnitIsCharmed
 local UnitIsVisible = UnitIsVisible
@@ -69,25 +69,35 @@ local UnitLevel = UnitLevel
 local UnitName = UnitName
 local UnitPlayerControlled = UnitPlayerControlled
 local CheckInteractDistance = CheckInteractDistance
+local CombatLogGetCurrentEventInfo = CombatLogGetCurrentEventInfo
+local UnitHasVehicleUI = UnitHasVehicleUI or function() end
+local GetGlyphSocketInfo = GetGlyphSocketInfo or function() end
+local GetNumGlyphSockets = GetNumGlyphSockets or function() return 0 end

+local MAX_RAID_MEMBERS = MAX_RAID_MEMBERS
+local MAX_PARTY_MEMBERS = MAX_PARTY_MEMBERS
 local COMBATLOG_OBJECT_AFFILIATION_MINE = COMBATLOG_OBJECT_AFFILIATION_MINE

-local isTBC = WOW_PROJECT_ID == WOW_PROJECT_BURNING_CRUSADE_CLASSIC
+local build = floor(select(4,GetBuildInfo())/10000)
+local isTBC = build == 2
+local isWrath = build == 3

 local spellRankTableData = {
-	[1] = { 774, 8936, 5185, 740, 635, 19750, 139, 2060, 596, 2061, 2054, 2050, 1064, 331, 8004, 136, 755, 689, 746, 33763, 32546, 37563 },
-	[2] = { 1058, 8938, 5186, 8918, 639, 19939, 6074, 10963, 996, 9472, 2055, 2052, 10622, 332, 8008, 3111, 3698, 699, 1159 },
-	[3] = { 1430, 8939, 5187, 9862, 647, 19940, 6075, 10964, 10960, 9473, 6063, 2053, 10623, 547, 8010, 3661, 3699, 709, 3267 },
-	[4] = { 2090, 8940, 5188, 9863, 1026, 19941, 6076, 10965, 10961, 9474, 6064, 913, 10466, 3662, 3700, 7651, 3268, 25422 },
-	[5] = { 2091, 8941, 5189, 1042, 19942, 6077, 22009, 25314, 25316, 10915, 939, 10467, 13542, 11693, 11699, 7926, 25423, 26983 },
-	[6] = { 3627, 9750, 6778, 3472, 19943, 6078, 10916, 959, 10468, 13543, 11694, 11700, 7927, 23569, 24412, 25210, 25308 },
-	[7] = { 8910, 9856, 8903, 10328, 10927, 10917, 8005, 13544, 11695, 10838, 27137, 25213, 25420, 27219 },
-	[8] = { 9839, 9857, 9758, 10329, 10928, 10395, 10839, 23568, 24413, 25233, 27259, 27220, 27046 },
-	[9] = { 9840, 9858, 9888, 25292, 10929, 10396, 18608, 25235 },
-	[10] = { 9841, 9889, 25315, 25357, 18610, 23567, 24414, 26980, 27135 },
-	[11] = { 25299, 25297, 30020, 27136, 25221, 25391, 27030 },
-	[12] = { 26981, 26978, 25222, 25396, 27031 },
-	[13] = { 26982, 26979 },
+	[1] = { 774, 8936, 5185, 740, 635, 19750, 139, 2060, 596, 2061, 2054, 2050, 1064, 331, 8004, 136, 755, 689, 746, 33763, 32546, 37563, 48438, 61295, 51945, 50464, 47757 },
+	[2] = { 1058, 8938, 5186, 8918, 639, 19939, 6074, 10963, 996, 9472, 2055, 2052, 10622, 332, 8008, 3111, 3698, 699, 1159, 53248, 61299, 51990, 48450, 52986, 48119 },
+	[3] = { 1430, 8939, 5187, 9862, 647, 19940, 6075, 10964, 10960, 9473, 6063, 2053, 10623, 547, 8010, 3661, 3699, 709, 3267, 53249, 61300, 51997, 48451, 52987, 48120 },
+	[4] = { 2090, 8940, 5188, 9863, 1026, 19941, 6076, 10965, 10961, 9474, 6064, 913, 10466, 3662, 3700, 7651, 3268, 25422, 53251, 61301, 51998, 52988 },
+	[5] = { 2091, 8941, 5189, 1042, 19942, 6077, 22009, 25314, 25316, 10915, 939, 10467, 13542, 11693, 11699, 7926, 25423, 26983, 51999 },
+	[6] = { 3627, 9750, 6778, 3472, 19943, 6078, 10916, 959, 10468, 13543, 11694, 11700, 7927, 23569, 24412, 25210, 25308, 52000, 55458, 48446 },
+	[7] = { 8910, 9856, 8903, 10328, 10927, 10917, 8005, 13544, 11695, 10838, 27137, 25213, 25420, 27219, 55459, 48447, 48072 },
+	[8] = { 9839, 9857, 9758, 10329, 10928, 10395, 10839, 23568, 24413, 25233, 27259, 27220, 27046, 48784, 49275, 48062 },
+	[9] = { 9840, 9858, 9888, 25292, 10929, 10396, 18608, 25235, 48785, 49276, 48063, 48989, 47856, 47857 },
+	[10] = { 9841, 9889, 25315, 25357, 18610, 23567, 24414, 26980, 27135, 48070, 48990 },
+	[11] = { 25299, 25297, 30020, 27136, 25221, 25391, 27030, 48442, 48071 },
+	[12] = { 26981, 26978, 25222, 25396, 27031, 48781, 48443 },
+	[13] = { 26982, 26979, 48782, 49272, 48067, 45543 },
+	[14] = { 49273, 48377, 48440, 48068, 45544 },
+	[15] = { 48378, 48441 },
 }

 local SpellIDToRank = {}
@@ -127,6 +137,7 @@ HealComm.pendingHots = HealComm.pendingHots or {}
 HealComm.spellData = HealComm.spellData or {}
 HealComm.talentData = HealComm.talentData or {}
 HealComm.tempPlayerList = HealComm.tempPlayerList or {}
+HealComm.glyphCache = HealComm.glyphCache or {}

 if( not HealComm.unitToPet ) then
 	HealComm.unitToPet = {["player"] = "pet"}
@@ -429,7 +440,11 @@ function HealComm:GetNextHealAmount(guid, bitFlag, time, ignoreGUID, srcGUID)
 									local nextTick = currentTime + (secondsLeft % pending.tickInterval)
 									if( not healTime or nextTick < healTime ) then
 										healTime = nextTick
-										healAmount = amount * stack
+										if pending.hasVariableTicks then
+											healAmount = amount[pending.totalTicks - pending[i + 4] + 1]
+										else
+											healAmount = amount * stack
+										end
 										healFrom = casterGUID
 									end
 								end
@@ -465,7 +480,16 @@ local function filterData(spells, filterGUID, bitFlag, time, ignoreGUID)
 						elseif( ( pending.bitType == CHANNEL_HEALS or pending.bitType == HOT_HEALS ) and endTime > currentTime ) then
 							local ticksLeft = pending[i + 4]
 							if( not time or time >= endTime ) then
-								healAmount = healAmount + (amount * stack) * ticksLeft
+								if( not pending.hasVariableTicks ) then
+									healAmount = healAmount + (amount * stack) * ticksLeft
+								else
+									local ticksPassed = pending.totalTicks - ticksLeft
+									for numTick, heal in pairs(amount) do
+										if numTick > ticksPassed then
+											healAmount = healAmount + (heal * stack)
+										end
+									end
+								end
 							else
 								local secondsLeft = endTime - currentTime
 								local bandSeconds = time - currentTime
@@ -475,8 +499,16 @@ local function filterData(spells, filterGUID, bitFlag, time, ignoreGUID)
 								if( nextTickIn > 0 and nextTickIn < fractionalBand ) then
 									ticks = ticks + 1
 								end
-
-								healAmount = healAmount + (amount * stack) * min(ticks, ticksLeft)
+								if( not pending.hasVariableTicks ) then
+									healAmount = healAmount + (amount * stack) * min(ticks, ticksLeft)
+								else
+									local ticksPassed = pending.totalTicks - ticksLeft
+									for numTick, heal in ipairs(amount) do
+										if numTick > ticksPassed then
+											healAmount = healAmount + (heal * stack)
+										end
+									end
+								end
 							end
 						end
 					end
@@ -560,7 +592,10 @@ function HealComm:GetHealAmountEx(dstGUID, dstBitFlag, dstTime, srcGUID, srcBitF
 							local targetGUID = pending[i]

 							if targetGUID == dstGUID then
-								local amount = pending[i + 1]
+								local amount = 0
+								if not pending.hasVariableTicks then
+									amount = pending[i + 1]
+								end
 								local stack = pending[i + 2]
 								local endTime = pending[i + 3]

@@ -604,9 +639,19 @@ function HealComm:GetHealAmountEx(dstGUID, dstBitFlag, dstTime, srcGUID, srcBitF
 										if ticks > ticksLeft then
 											ticks = ticksLeft
 										end
-
-										amount1 = amount * ticks
-										amount2 = amount * ticksLeft
+										if not pending.hasVariableTicks then
+											amount1 = amount * ticks
+											amount2 = amount * ticksLeft
+										else
+											amount = pending[i + 1]
+											amount1 = amount[pending.totalTicks - pending[i + 4] + 1] or 0
+											local ticksPassed = pending.totalTicks - ticksLeft
+											for numTick, heal in ipairs(amount) do
+												if numTick > ticksPassed then
+													amount2 = amount2 + (heal * stack)
+												end
+											end
+										end
 									end

 									if casterGUID ~= srcGUID then
@@ -664,7 +709,7 @@ end
 -- Healing class data
 -- Thanks to Gagorian (DrDamage) for letting me steal his formulas and such
 local playerCurrentRelic
-local guidToUnit, guidToGroup = HealComm.guidToUnit, HealComm.guidToGroup
+local guidToUnit, guidToGroup, glyphCache = HealComm.guidToUnit, HealComm.guidToGroup, HealComm.glyphCache

 local unitHasAura

@@ -699,11 +744,13 @@ end

 local function calculateGeneralAmount(level, amount, spellPower, spModifier, healModifier)
 	local penalty = level > 20 and 1 or (1 - ((20 - level) * 0.0375))
-	if isTBC then
+	if isWrath then
+		--https://wowwiki-archive.fandom.com/wiki/Downranking
+		penalty = min(1,max(0,(22+(level+5)-playerLevel)/20))
+	elseif isTBC then
 		-- TBC added another downrank penalty
 		penalty = penalty * min(1, (level + 11) / playerLevel)
 	end
-
 	spellPower = spellPower * penalty

 	return healModifier * (amount + (spellPower * spModifier))
@@ -723,35 +770,25 @@ end

 --[[
 	What the different callbacks do:
-
 	AuraHandler: Specific aura tracking needed for this class, who has Beacon up on them and such
-
 	ResetChargeData: Due to spell "queuing" you can't always rely on aura data for buffs that last one or two casts, for example Divine Favor (+100% crit, one spell)
 	if you cast Holy Light and queue Flash of Light the library would still see they have Divine Favor and give them crits on both spells. The reset means that the flag that indicates
 	they have the aura can be killed and if they interrupt the cast then it will call this and let you reset the flags.
-
 	What happens in terms of what the client thinks and what actually is, is something like this:
-
 	UNIT_SPELLCAST_START, Holy Light -> Divine Favor up
 	UNIT_SPELLCAST_SUCCEEDED, Holy Light -> Divine Favor up (But it was really used)
 	UNIT_SPELLCAST_START, Flash of Light -> Divine Favor up (It's not actually up but auras didn't update)
 	UNIT_AURA -> Divine Favor up (Split second where it still thinks it's up)
 	UNIT_AURA -> Divine Favor faded (Client catches up and realizes it's down)
-
 	CalculateHealing: Calculates the healing value, does all the formula calculations talent modifiers and such
-
 	CalculateHotHealing: Used specifically for calculating the heals of hots
-
 	GetHealTargets: Who the heal is going to hit, used for setting extra targets for Beacon of Light + Paladin heal or Prayer of Healing.
 	The returns should either be:
-
 	"compressedGUID1,compressedGUID2,compressedGUID3,compressedGUID4", healthAmount
 	Or if you need to set specific healing values for one GUID it should be
 	"compressedGUID1,healthAmount1,compressedGUID2,healAmount2,compressedGUID3,healAmount3", -1
-
 	The latter is for cases like Glyph of Healing Wave where you need a heal for 1,000 on A and a heal for 200 on the player for B without sending 2 events.
 	The -1 tells the library to look in the GUId list for the heal amounts
-
 	**NOTE** Any GUID returned from GetHealTargets must be compressed through a call to compressGUID[guid]
 ]]

@@ -767,7 +804,7 @@ local function getBaseHealAmount(spellData, spellName, spellID, spellRank)
 	if type(average) == "number" then
 		return average
 	end
-	local requiresLevel = spellData.levels[spellRank] or spellData.levels[1] -- needs review
+	local requiresLevel = spellData.levels[spellRank]
 	return average[min(playerLevel - requiresLevel + 1, #average)]
 end

@@ -781,28 +818,58 @@ if( playerClass == "DRUID" ) then
 		local Rejuvenation = GetSpellInfo(774)
 		local Tranquility = GetSpellInfo(740)
 		local Lifebloom = GetSpellInfo(33763) or "Lifebloom"
-		local EmpoweredRejuv = GetSpellInfo(33886) or "EmpoweredRejuv"
-		local EmpoweredTouch = GetSpellInfo(33879) or "EmpoweredTouch"
-
-		hotData[Regrowth] = { interval = 3, ticks = 7, coeff = isTBC and 0.7 or 0.5, levels = { 12, 18, 24, 30, 36, 42, 48, 54, 60, 65 }, averages = { 98, 175, 259, 343, 427, 546, 686, 861, 1064, 1274 }}
-		hotData[Rejuvenation] = { interval = 3, levels = { 4, 10, 16, 22, 28, 34, 40, 46, 52, 58, 60, 63, 69 }, averages = { 32, 56, 116, 180, 244, 304, 388, 488, 608, 756, 888, 932, 1060 }}
-		hotData[Lifebloom] = {interval = 1, ticks = 7, coeff = 0.52, dhCoeff = 0.34335, levels = {64}, averages = {273}, bomb = {600}}
-
-		spellData[HealingTouch] = { levels = {1, 8, 14, 20, 26, 32, 38, 44, 50, 56, 60, 62, 69}, averages = {
-			{avg(37, 51), avg(37, 52), avg(38, 53), avg(39, 54), avg(40, 55)},
-			{avg(88, 112), avg(89, 114), avg(90, 115), avg(91, 116), avg(93, 118), avg(94, 119)},
-			{avg(195, 243), avg(196, 245), avg(198, 247), avg(200, 249), avg(202, 251), avg(204, 253)},
-			{avg(363, 445), avg(365, 448), avg(368, 451), avg(371, 454), avg(373, 456), avg(376, 459)},
-			{avg(572, 694), avg(575, 698), avg(579, 701), avg(582, 705), avg(586, 708), avg(589, 712)},
-			{avg(742, 894), avg(746, 898), avg(750, 902), avg(754, 906), avg(758, 910), avg(762, 914)},
-			{avg(936, 1120), avg(940, 1125), avg(945, 1129), avg(949, 1134), avg(954, 1138), avg(958, 1143)},
-			{avg(1199, 1427), avg(1204, 1433), avg(1209, 1438), avg(1214, 1443), avg(1219, 1448), avg(1225, 1453)},
-			{avg(1516, 1796), avg(1521, 1802), avg(1527, 1808), avg(1533, 1814), avg(1539, 1820), avg(1545, 1826)},
-			{avg(1890, 2230), avg(1896, 2237), avg(1903, 2244), avg(1909, 2250), avg(1916, 2257), avg(1923, 2263)},
-			{avg(2267, 2677), avg(2274, 2685), avg(2281, 2692), avg(2288, 2699), avg(2296, 2707), avg(2303, 2714)},
-			{avg(2364, 2790), avg(2371, 2798), avg(2378, 2805), avg(2386, 2813), avg(2393, 2820), avg(2401, 2827)},
-			{avg(2707, 3197), avg(2715, 3206)} }}
-		spellData[Regrowth] = {coeff = 0.5 * (2 / 3.5) , levels = hotData[Regrowth].levels, averages = {
+		local EmpoweredRejuv = GetSpellInfo(33886) or "Empowered Rejuv"
+		local EmpoweredTouch = GetSpellInfo(33879) or "Empowered Touch"
+		local WildGrowth = GetSpellInfo(48438) or "Wild Growth"
+		local Nourish = GetSpellInfo(50464) or "Nourish"
+		local MasterShapeshifter = GetSpellInfo(48411) or "Master Shapeshifter"
+		local Genesis = GetSpellInfo(57810) or "Genesis"
+		local NaturesSplendor = GetSpellInfo(57865) or "Natures Splendor"
+		local TreeofLife = GetSpellInfo(33891) or "Tree of Life"
+
+		hotData[Regrowth] = { interval = 3, ticks = 7, coeff = (isTBC or isWrath) and 0.7 or 0.5, levels = { 12, 18, 24, 30, 36, 42, 48, 54, 60, 65, 71, 77 }, averages = { 98, 175, 259, 343, 427, 546, 686, 861, 1064, 1274, 1792, 2345 }}
+		if isWrath then
+			hotData[Rejuvenation] = { interval = 3, levels = { 4, 10, 16, 22, 28, 34, 40, 46, 52, 58, 60, 63, 69, 75, 80 }, averages = { 40, 70, 145, 225, 305, 380, 485, 610, 760, 945, 1110, 1165, 1325, 1490, 1690 }}
+			hotData[Lifebloom] = {interval = 1, ticks = 7, coeff = 0.66626, dhCoeff = 0.517928287, levels = {64, 72, 80}, averages = {224, 287, 371}, bomb = {480, 616, 776}}
+			hotData[WildGrowth] = {interval = 1, ticks = 7, coeff = 0.8056, levels = {60, 70, 75, 80}, averages = {686, 861, 1239, 1442}}
+		else
+			hotData[Rejuvenation] = { interval = 3, levels = { 4, 10, 16, 22, 28, 34, 40, 46, 52, 58, 60, 63, 69 }, averages = { 32, 56, 116, 180, 244, 304, 388, 488, 608, 756, 888, 932, 1060 }}
+			hotData[Lifebloom] = {interval = 1, ticks = 7, coeff = 0.52, dhCoeff = 0.34335, levels = {64}, averages = {273}, bomb = {600}}
+		end
+		if isWrath then
+			spellData[HealingTouch] = { levels = {1, 8, 14, 20, 26, 32, 38, 44, 50, 56, 60, 62, 69, 74, 79}, averages = {
+				{avg(37, 51), avg(37, 52), avg(38, 53), avg(39, 54), avg(40, 55)},
+				{avg(88, 112), avg(89, 114), avg(90, 115), avg(91, 116), avg(93, 118), avg(94, 119)},
+				{avg(195, 243), avg(196, 245), avg(198, 247), avg(200, 249), avg(202, 251), avg(204, 253)},
+				{avg(363, 445), avg(365, 448), avg(368, 451), avg(371, 454), avg(373, 456), avg(376, 459)},
+				{avg(490, 594), avg(493, 597), avg(496, 600), avg(499, 603), avg(502, 606), avg(505, 609)},
+				{avg(636, 766), avg(639, 770), avg(642, 773), avg(646, 777), avg(649, 780), avg(653, 783)},
+				{avg(802, 960), avg(805, 964), avg(809, 968), avg(813, 972), avg(817, 976), avg(821, 980)},
+				{avg(1199, 1427), avg(1203, 1432), avg(1208, 1436), avg(1212, 1441), avg(1217, 1445), avg(1221, 1450)},
+				{avg(1299, 1539), avg(1304, 1545), avg(1309, 1550), avg(1314, 1555), avg(1319, 1560), avg(1324, 1565)},
+				{avg(1620, 1912), avg(1625, 1918), avg(1631, 1924), avg(1637, 1930), avg(1642, 1935), avg(1648, 1941)},
+				{avg(1944, 2294), avg(1950, 2301), avg(1956, 2307), avg(1962, 2313), avg(1968, 2319), avg(1975, 2325)},
+				{avg(2026, 2392), avg(2032, 2399), avg(2038, 2405), avg(2044, 2411), avg(2051, 2418), avg(2057, 2424)},
+				{avg(2321, 2739), avg(2328, 2746), avg(2335, 2753), avg(2342, 2760), avg(2349, 2767)},
+				{avg(3223, 3805), avg(3232, 3815), avg(3242, 3825), avg(3252, 3835), avg(3262, 3845)},
+				{avg(3750, 4428), avg(3761, 4440)} }}
+		else
+			spellData[HealingTouch] = { levels = {1, 8, 14, 20, 26, 32, 38, 44, 50, 56, 60, 62, 69}, averages = {
+				{avg(37, 51), avg(37, 52), avg(38, 53), avg(39, 54), avg(40, 55)},
+				{avg(88, 112), avg(89, 114), avg(90, 115), avg(91, 116), avg(93, 118), avg(94, 119)},
+				{avg(195, 243), avg(196, 245), avg(198, 247), avg(200, 249), avg(202, 251), avg(204, 253)},
+				{avg(363, 445), avg(365, 448), avg(368, 451), avg(371, 454), avg(373, 456), avg(376, 459)},
+				{avg(572, 694), avg(575, 698), avg(579, 701), avg(582, 705), avg(586, 708), avg(589, 712)},
+				{avg(742, 894), avg(746, 898), avg(750, 902), avg(754, 906), avg(758, 910), avg(762, 914)},
+				{avg(936, 1120), avg(940, 1125), avg(945, 1129), avg(949, 1134), avg(954, 1138), avg(958, 1143)},
+				{avg(1199, 1427), avg(1204, 1433), avg(1209, 1438), avg(1214, 1443), avg(1219, 1448), avg(1225, 1453)},
+				{avg(1516, 1796), avg(1521, 1802), avg(1527, 1808), avg(1533, 1814), avg(1539, 1820), avg(1545, 1826)},
+				{avg(1890, 2230), avg(1896, 2237), avg(1903, 2244), avg(1909, 2250), avg(1916, 2257), avg(1923, 2263)},
+				{avg(2267, 2677), avg(2274, 2685), avg(2281, 2692), avg(2288, 2699), avg(2296, 2707), avg(2303, 2714)},
+				{avg(2364, 2790), avg(2371, 2798), avg(2378, 2805), avg(2386, 2813), avg(2393, 2820), avg(2401, 2827)},
+				{avg(2707, 3197), avg(2715, 3206)} }}
+		end
+		spellData[Regrowth] = {coeff = (isWrath and 0.6 or 0.5) * (2 / 3.5) , levels = hotData[Regrowth].levels, averages = {
 			{avg(84, 98), avg(85, 100), avg(87, 102), avg(89, 104), avg(91, 106), avg(93, 107)},
 			{avg(164, 188), avg(166, 191), avg(169, 193), avg(171, 196), avg(174, 198), avg(176, 201)},
 			{avg(240, 274), avg(243, 278), avg(246, 281), avg(249, 284), avg(252, 287), avg(255, 290)},
@@ -812,34 +879,60 @@ if( playerClass == "DRUID" ) then
 			{avg(646, 724), avg(651, 730), avg(656, 735), avg(661, 740), avg(667, 746), avg(672, 751)},
 			{avg(809, 905), avg(815, 911), avg(821, 917), avg(827, 923), avg(833, 929), avg(839, 935)},
 			{avg(1003, 1119), avg(1009, 1126), avg(1016, 1133), avg(1023, 1140), avg(1030, 1147), avg(1037, 1153)},
-			{avg(1215, 1355), avg(1222, 1363), avg(1230, 1371), avg(1238, 1379), avg(1245, 1386), avg(1253, 1394)} }}
-		if isTBC then
-			spellData[Tranquility] = {coeff = 1.145, ticks = 4, interval = 2, levels = {30, 40, 50, 60, 70}, averages = {
+			{avg(1215, 1355), avg(1222, 1363), avg(1230, 1371), avg(1238, 1379), avg(1245, 1386), avg(1253, 1394)},
+			{avg(1710, 1908), avg(1720, 1919), avg(1731, 1930), avg(1742, 1941), avg(1753, 1952), avg(1764, 1962)},
+			{avg(2234, 2494), avg(2241, 2502), avg(2249, 2510), avg(2257, 2518)} }}
+		if isTBC or isWrath then
+			spellData[Tranquility] = {_isChanneled = true, coeff = 1.145, ticks = 4, interval = 2, levels = {30, 40, 50, 60, 70, 75, 80}, averages = {
 				{351 * 4, 354 * 4, 356 * 4, 358 * 4, 360 * 4, 362 * 4, 365 * 4},
 				{515 * 4, 518 * 4, 521 * 4, 523 * 4, 526 * 4, 528 * 4, 531 * 4},
 				{765 * 4, 769 * 4, 772 * 4, 776 * 4, 779 * 4, 782 * 4, 786 * 4},
 				{1097 * 4, 1101 * 4, 1105 * 4, 1109 * 4, 1112 * 4, 1116 * 4, 1120 * 4},
-				{1518 * 4} }}
+				{1518 * 4, 1523 * 4, 1527 * 4, 1532 * 4, 1536 * 4},
+				{2598 * 4, 2606 * 4, 2614 * 4, 2622 * 4, 2629 * 4},
+				{3035 * 4} }}
 		else
-			spellData[Tranquility] = {coeff = 1/3, ticks = 5, interval = 2, levels = {30, 40, 50, 60}, averages = {
+			spellData[Tranquility] = {_isChanneled = true, coeff = 1/3, ticks = 5, interval = 2, levels = {30, 40, 50, 60}, averages = {
 				{94 * 5, 95 * 5, 96 * 5, 96 * 5, 97 * 5, 97 * 5, 98 * 5},
 				{138 * 5, 139 * 5, 140 * 5, 141 * 5, 141 * 5, 142 * 5, 143 * 5},
 				{205 * 5, 206 * 5, 207 * 5, 208 * 5, 209 * 5, 210 * 5, 211 * 5},
 				{294 * 5} }}
 		end
+		spellData[Nourish] = {coeff = 0.358005, levels = {80}, averages = {avg(1883, 2187)}}

 		talentData[GiftofNature] = {mod = 0.02, current = 0}
 		talentData[ImprovedRejuv] = {mod = 0.05, current = 0}
 		talentData[EmpoweredRejuv] = {mod = 0.04, current = 0}
 		talentData[EmpoweredTouch] = {mod = 0.1, current = 0}
+		talentData[Genesis] = {mod = 0.01, current = 0}
+		talentData[NaturesSplendor] = {mod = 1, current = 0}
+		talentData[MasterShapeshifter] = {mod = 0.02, current = 0}

 		itemSetsData["Stormrage"] = {16903, 16898, 16904, 16897, 16900, 16899, 16901, 16902}
 		itemSetsData["Nordrassil"] = {30216, 30217, 30219, 30220, 30221}
 		itemSetsData["Thunderheart"] = {31041, 31032, 31037, 31045, 31047, 34571, 34445, 34554}
-		local bloomBombIdols = {[28355] = 87, [33076] = 105, [33841] = 116, [35021] = 131}
-		local rejuIdols = {[186054] = 15, [22398] = 50, [25643] = 86}
+		itemSetsData["Dreamwalker"] = {40460, 40461, 40462, 40463, 40465, 39531, 39538, 39539, 39542, 39543}
+		itemSetsData["Lasherweave"] = {50106, 50107, 50108, 50109, 50113, 51139, 51138, 51137, 51136, 51135, 51300, 51301, 51302, 51303, 51304}
+
+		local bloomBombIdols = {[28355] = 87, [33076] = 105, [33841] = 116, [35021] = 131, [42576] = 188, [42577] = 217, [42578] = 246, [42579] = 294, [42580] = 376, [51423] = 448}
+		local rejuIdols = {[186054] = 15, [22398] = 50, [25643] = 86, [38366] = 33}
+		local bloomIdols = {[40711] = 125, [27886] = 47}
+
+		local hotTotals, hasRegrowth = {}, {}
+		AuraHandler = function(unit, guid)
+			hotTotals[guid] = 0
+			if( unitHasAura(unit, Rejuvenation) ) then hotTotals[guid] = hotTotals[guid] + 1 end
+			if( unitHasAura(unit, Lifebloom) ) then hotTotals[guid] = hotTotals[guid] + 1 end
+			if( unitHasAura(unit, WildGrowth) ) then hotTotals[guid] = hotTotals[guid] + 1 end
+			if( unitHasAura(unit, Regrowth) ) then
+				hasRegrowth[guid] = true
+				hotTotals[guid] = hotTotals[guid] + 1
+			else
+				hasRegrowth[guid] = nil
+			end
+		end

-		GetHealTargets = function(bitType, guid, healAmount, spellID)
+		GetHealTargets = function(bitType, guid, spellID)
 			-- Tranquility pulses on everyone within 30 yards, if they are in range of Mark of the Wild they'll get Tranquility
 			local spellName = GetSpellInfo(spellID)
 			if( spellName == Tranquility ) then
@@ -847,18 +940,18 @@ if( playerClass == "DRUID" ) then
 				local playerGroup = guidToGroup[playerGUID]

 				for groupGUID, id in pairs(guidToGroup) do
-					if( id == playerGroup and playerGUID ~= groupGUID and not IsSpellInRange(MarkoftheWild, guidToUnit[groupGUID]) == 1 ) then
+					if( id == playerGroup and playerGUID ~= groupGUID and not UnitHasVehicleUI(guidToUnit[groupID]) and IsSpellInRange(MarkoftheWild, guidToUnit[groupGUID]) == 1 ) then
 						targets = targets .. "," .. compressGUID[groupGUID]
 					end
 				end
-
-				return targets, healAmount
+				return targets
 			end

-			return compressGUID[guid], healAmount
+			return compressGUID[guid]
 		end

 		-- Calculate hot heals
+		local wgTicks = {}
 		CalculateHotHealing = function(guid, spellID)
 			local spellName, spellRank = GetSpellInfo(spellID), SpellIDToRank[spellID]
 			local healAmount = getBaseHealAmount(hotData, spellName, spellID, spellRank)
@@ -867,17 +960,24 @@ if( playerClass == "DRUID" ) then
 			local bombAmount, totalTicks

 			-- Gift of Nature
-			if isTBC then
+			if isTBC or isWrath then
 				healModifier = healModifier * (1 + talentData[GiftofNature].current)
 			else
 				-- Gift of Nature does only apply to base values in classic
-				healAmount = healAmount * (1 + talentData[GiftofNature].current)
+				healAmount = healAmount + talentData[GiftofNature].current
+			end
+
+			if( unitHasAura("player", TreeofLife) ) then
+				-- 32387 - Idol of the Raven Godess, +44 SP while in TOL
+				if( playerCurrentRelic == 32387 ) then
+					spellPower = spellPower + 44
+				end
 			end

 			-- Rejuvenation
 			if( spellName == Rejuvenation ) then
-				if isTBC then
-					healModifier = healModifier * (1 + talentData[ImprovedRejuv].current)
+				if isTBC or isWrath then
+					healModifier = healModifier + talentData[ImprovedRejuv].current
 				else
 					-- Improved Rejuvenation only applies to base values in classic
 					healAmount = healAmount * (1 + talentData[ImprovedRejuv].current)
@@ -887,30 +987,28 @@ if( playerClass == "DRUID" ) then
 					spellPower = spellPower + rejuIdols[playerCurrentRelic]
 				end

-				local duration = 12
+				local duration = isWrath and 15 or 12
 				local ticks = duration / hotData[spellName].interval

 				if( equippedSetCache["Stormrage"] >= 8 ) then
 					healAmount = healAmount + (healAmount / ticks) -- Add Tick Amount Gained by Set.
-					duration = 15
+					duration = duration + 3
 					ticks = ticks + 1
 				end

 				totalTicks = ticks

-				spellPower = spellPower * (duration / 15) * (1 + talentData[EmpoweredRejuv].current)
+				spellPower = spellPower * (((duration / 15) * (isWrath and 1.88 or 1)) * (1 + talentData[EmpoweredRejuv].current))
 				spellPower = spellPower / ticks
 				healAmount = healAmount / ticks
-				if( playerCurrentRelic == 186054 ) then
-					healAmount = healAmount + 15
-				end
 			elseif( spellName == Regrowth ) then
-				spellPower = spellPower * hotData[spellName].coeff * (1 + talentData[EmpoweredRejuv].current)
+				spellPower = spellPower * hotData[spellName].coeff * (isWrath and 1.88 or 1 ) * (1 + talentData[EmpoweredRejuv].current)
 				spellPower = spellPower / hotData[spellName].ticks
 				healAmount = healAmount / hotData[spellName].ticks

 				totalTicks = 7

+				if( talentData[NaturesSplendor].current >= 1 ) then totalTicks = totalTicks + 2 end
 				if( equippedSetCache["Nordrassil"] >= 2 ) then totalTicks = totalTicks + 2 end

 			elseif( spellName == Lifebloom ) then
@@ -921,26 +1019,57 @@ if( playerClass == "DRUID" ) then
 				end

 				local bombSpell = bombSpellPower * hotData[spellName].dhCoeff * (1 + talentData[EmpoweredRejuv].current)
-				bombAmount = math.ceil(calculateGeneralAmount(hotData[spellName].levels[spellRank], hotData[spellName].bomb[spellRank], bombSpell, spModifier, healModifier))
+				bombAmount = ceil(calculateGeneralAmount(hotData[spellName].levels[spellRank], hotData[spellName].bomb[spellRank], bombSpell, spModifier, healModifier))

 				-- Figure out the hot tick healing
 				spellPower = spellPower * (hotData[spellName].coeff * (1 + talentData[EmpoweredRejuv].current))
+				spellPower = spellPower / hotData[spellName].ticks
+				healAmount = healAmount / hotData[spellName].ticks
+				-- Figure out total ticks
+				totalTicks = 7

-				-- Idol of the Emerald Queen, +47 SP per tick
-				if( playerCurrentRelic == 27886 ) then
-					spellPower = spellPower + 47
+				if( playerCurrentRelic and bloomIdols[playerCurrentRelic] ) then
+					spellPower = spellPower + bloomIdols[playerCurrentRelic]
 				end

+				-- Glyph of Lifebloom, +1 second
+				if( glyphCache[54826] ) then totalTicks = totalTicks + 1 end
+				-- Nature's Splendor, +2 seconds
+				if( talentData[NaturesSplendor].current >= 1 ) then totalTicks = totalTicks + 2 end
+
+			-- Wild Growth
+			elseif( spellName == WildGrowth ) then
+				spellPower = spellPower * (hotData[spellName].coeff * (1 + talentData[EmpoweredRejuv].current))
 				spellPower = spellPower / hotData[spellName].ticks
 				healAmount = healAmount / hotData[spellName].ticks
-				-- Figure out total ticks
-				totalTicks = 7

+				healModifier = healModifier + talentData[Genesis].current
+
+				table.wipe(wgTicks)
+				local tickModifier = equippedSetCache["Lasherweave"] >= 2 and 0.70 or 1
+				local tickAmount = healAmount / hotData[spellName].ticks
+				for i=1, hotData[spellName].ticks do
+					table.insert(wgTicks, math.ceil(healModifier * ((healAmount + tickAmount * (3 - (i - 1) * tickModifier)) + (spellPower * spModifier))))
+				end
+
+				if( isWrath and unitHasAura("player", MasterShapeshifter) ) then
+					healModifier = healModifier * (1 + talentData[MasterShapeshifter].current)
+				end
+
+				return HOT_HEALS, wgTicks, hotData[spellName].ticks, hotData[spellName].interval, nil, true
 			end

-			healAmount = calculateGeneralAmount(hotData[spellName].levels[spellRank], healAmount, spellPower, spModifier, healModifier)
+			healModifier = healModifier + talentData[Genesis].current

-			return HOT_HEALS, ceil(healAmount), totalTicks, hotData[spellName].interval, bombAmount
+			if( isWrath and unitHasAura("player", MasterShapeshifter) ) then
+				healModifier = healModifier * (1 + talentData[MasterShapeshifter].current)
+				if bombAmount then
+					bombAmount = bombAmount * (1 + talentData[MasterShapeshifter].current)
+				end
+			end
+
+			healAmount = calculateGeneralAmount(hotData[spellName].levels[spellRank], healAmount, spellPower, spModifier, healModifier)
+			return HOT_HEALS, ceil(max(0, healAmount)), totalTicks, hotData[spellName].interval, bombAmount
 		end

 		-- Calcualte direct and channeled heals
@@ -951,23 +1080,71 @@ if( playerClass == "DRUID" ) then
 			local healModifier, spModifier = playerHealModifier, 1

 			-- Gift of Nature
-			if isTBC then
+			if isTBC or isWrath then
 				healModifier = healModifier * (1 + talentData[GiftofNature].current)
 			else
 				-- Gift of Nature does only apply to base values in classic
 				healAmount = healAmount * (1 + talentData[GiftofNature].current)
 			end

+			if( isWrath and unitHasAura("player", MasterShapeshifter) ) then
+				healModifier = healModifier * ( 1 + talentData[MasterShapeshifter].current)
+				-- 32387 - Idol of the Raven Godess, +44 SP while in TOL
+				if( playerCurrentRelic == 32387 ) then
+					spellPower = spellPower + 44
+				end
+			end
+
 			-- Regrowth
 			if( spellName == Regrowth ) then
-				spellPower = spellPower * spellData[spellName].coeff
-				-- Healing Touch
+				-- Glyph of Regrowth - +20% if target has Regrowth
+				if( glyphCache[54743] and hasRegrowth[guid] ) then
+					healModifier = healModifier * 1.20
+				end
+				spellPower = spellPower * spellData[spellName].coeff * (isWrath and 1.88 or 1)
+			-- Nourish
+			elseif( spellName == Nourish ) then
+				-- 46138 - Idol of Flourishing Life, +187 Nourish SP
+				if( playerCurrentRelic == 46138 ) then
+					spellPower = spellPower + 187
+				end
+
+				-- Apply any hot specific bonuses
+				local hots = hotTotals[guid]
+				if( hots and hots > 0 ) then
+					local bonus = 1.20
+
+					-- T7 Resto, +5% healing per each of the players hot on their target
+					if( equippedSetCache["Dreamwalker"] >= 2 ) then
+						bonus = bonus + 0.05 * hots
+					end
+
+					-- Glyph of Nourish - 6% per HoT
+					if( glyphCache[62971] ) then
+						bonus = bonus + 0.06 * hots
+					end
+
+					healModifier = healModifier * bonus
+				end
+
+				spellPower = spellPower * ((spellData[spellName].coeff * 1.88) + talentData[EmpoweredTouch].current)
+			-- Healing Touch
 			elseif( spellName == HealingTouch ) then

-				healAmount = healAmount + (spellPower * talentData[EmpoweredTouch].current)
+				local castTime
+				if isWrath then
+					castTime = spellRank > 3 and 3 or spellRank == 3 and 2.5 or spellRank == 2 and 2 or 1.5
+				else
+					castTime = spellRank >= 5 and 3.5 or (spellRank == 4 and 3 or (spellRank == 3 and 2.5 or (spellRank == 2 and 2 or 1.5)))
+				end

-				local castTime = spellRank >= 5 and 3.5 or (spellRank == 4 and 3 or (spellRank == 3 and 2.5 or (spellRank == 2 and 2 or 1.5)))
-				spellPower = spellPower * (castTime / 3.5)
+				-- Glyph of Healing Touch
+				if( glyphCache[54825] ) then
+					healAmount = healAmount / 2
+					castTime = max(castTime - 1.5,1.5)
+				end
+
+				spellPower = spellPower * (((castTime / 3.5) * (isWrath and 1.88 or 1)) + (talentData[EmpoweredTouch].current * (isWrath and 2 or 1)))

 				if( playerCurrentRelic == 22399 ) then
 					healAmount = healAmount + 100
@@ -976,12 +1153,14 @@ if( playerClass == "DRUID" ) then
 				end

 				if equippedSetCache["Thunderheart"] >= 4 then
-					healModifier = healModifier + 0.05
+					healModifier = healModifier * 1.05
 				end

 				-- Tranquility
 			elseif( spellName == Tranquility ) then
-				spellPower = spellPower * spellData[spellName].coeff * (1 + talentData[EmpoweredRejuv].current)
+				healModifier = healModifier + talentData[Genesis].current
+
+				spellPower = spellPower * spellData[spellName].coeff * (isWrath and 1.88 or 1) * (1 + talentData[EmpoweredRejuv].current)
 				spellPower = spellPower / spellData[spellName].ticks
 				healAmount = healAmount / spellData[spellName].ticks
 			end
@@ -1002,7 +1181,7 @@ if( playerClass == "DRUID" ) then
 	end
 end

-local hasDivineFavor
+local hasDivineFavor, activeBeaconGUID

 if( playerClass == "PALADIN" ) then
 	LoadClassData = function()
@@ -1010,33 +1189,74 @@ if( playerClass == "PALADIN" ) then
 		local FlashofLight = GetSpellInfo(19750)
 		local HealingLight = GetSpellInfo(20237)
 		local HolyLight = GetSpellInfo(635)
-
-		spellData[HolyLight] = { coeff = 2.5 / 3.5, levels = {1, 6, 14, 22, 30, 38, 46, 54, 60, 62, 70}, averages = {
-			{avg(39, 47), avg(39, 48), avg(40, 49), avg(41, 50), avg(42, 51)},
-			{avg(76, 90), avg(77, 92), avg(78, 93), avg(79, 94), avg(80, 95), avg(81, 96)},
-			{avg(159, 187), avg(160, 189), avg(162, 191), avg(164, 193), avg(165, 194), avg(167, 196)},
-			{avg(310, 356), avg(312, 359), avg(314, 361), avg(317, 364), avg(319, 366), avg(322, 368)},
-			{avg(491, 553), avg(494, 557), avg(497, 560), avg(500, 563), avg(503, 566), avg(506, 569)},
-			{avg(698, 780), avg(701, 784), avg(705, 788), avg(709, 792), avg(713, 796), avg(717, 799)},
-			{avg(945, 1053), avg(949, 1058), avg(954, 1063), avg(958, 1067), avg(963, 1072), avg(968, 1076)},
-			{avg(1246, 1388), avg(1251, 1394), avg(1256, 1399), avg(1261, 1404), avg(1266, 1409), avg(1272, 1414)},
-			{avg(1590, 1770), avg(1595, 1775), avg(1601, 1781), avg(1607, 1787), avg(1613, 1793), avg(1619, 1799)},
-			{avg(1741, 1939), avg(1747, 1946), avg(1753, 1952), avg(1760, 1959), avg(1766, 1965), avg(1773, 1971)},
-			{avg(2196, 2446)} }}
-		spellData[FlashofLight] = { coeff = 1.5 / 3.5, levels = {20, 26, 34, 42, 50, 58, 66}, averages = {
-			{avg(62, 72), avg(63, 73), avg(64, 74), avg(65, 75), avg(66, 76), avg(67, 77)},
-			{avg(96, 110), avg(97, 112), avg(98, 113), avg(99, 114), avg(101, 116), avg(102, 117)},
-			{avg(145, 163), avg(146, 165), avg(148, 167), avg(149, 168), avg(151, 170), avg(153, 171)},
-			{avg(197, 221), avg(198, 223), avg(200, 225), avg(202, 227), avg(204, 229), avg(206, 231)},
-			{avg(267, 299), avg(269, 302), avg(271, 304), avg(273, 306), avg(275, 308), avg(278, 310)},
-			{avg(343, 383), avg(345, 386), avg(348, 389), avg(350, 391), avg(353, 394), avg(356, 396)},
-			{avg(448, 502), avg(450, 505), avg(453, 508), avg(455, 510), avg(458, 513)} }}
+		local Divinity = GetSpellInfo(63646) or "Divinity"
+		local TouchedbytheLight = GetSpellInfo(53592) or "TouchedbytheLight"
+		local BeaconofLight = GetSpellInfo(53563) or "BeaconofLight"
+		local SealofLight = GetSpellInfo(20165) or "SealofLight"
+		local DivineIllumination = GetSpellInfo(31842) or "DivineIllumination"
+
+		if isWrath then
+			spellData[HolyLight] = { coeff = 2.5 / 3.5, levels = {1, 6, 14, 22, 30, 38, 46, 54, 60, 62, 70, 75, 80}, averages = {
+				{avg(50, 60), avg(50, 61), avg(51, 62), avg(52, 63), avg(53, 64)},
+				{avg(96, 116), avg(97, 118), avg(98, 119), avg(99, 120), avg(100, 121), avg(101, 122)},
+				{avg(203, 239), avg(204, 241), avg(206, 243), avg(208, 245), avg(209, 246), avg(211, 248)},
+				{avg(397, 455), avg(399, 458), avg(401, 460), avg(404, 463), avg(406, 465), avg(409, 467)},
+				{avg(628, 708), avg(631, 712), avg(634, 715), avg(637, 718), avg(640, 721), avg(643, 724)},
+				{avg(894, 998), avg(897, 1002), avg(901, 1006), avg(905, 1010), avg(909, 1014), avg(913, 1017)},
+				{avg(1209, 1349), avg(1213, 1354), avg(1218, 1359), avg(1222, 1363), avg(1227, 1368), avg(1232, 1372)},
+				{avg(1595, 1777), avg(1600, 1783), avg(1605, 1788), avg(1610, 1793), avg(1615, 1798), avg(1621, 1803)},
+				{avg(2034, 2266), avg(2039, 2272), avg(2045, 2278), avg(2051, 2284), avg(2057, 2290), avg(2063, 2295)},
+				{avg(2232, 2486), avg(2238, 2493), avg(2244, 2499), avg(2251, 2506), avg(2257, 2512), avg(2264, 2518)},
+				{avg(2818, 3138), avg(2825, 3145), avg(2832, 3152), avg(2839, 3159), avg(2846, 3166)},
+				{avg(4199, 4677), avg(4209, 4688), avg(4219, 4698), avg(4230, 4709), avg(4240, 4719)},
+				{avg(4888, 5444)} }}
+			spellData[FlashofLight] = { coeff = 1.5 / 3.5, levels = {20, 26, 34, 42, 50, 58, 66, 74, 79}, averages = {
+				{avg(81, 93), avg(82, 94), avg(83, 95), avg(84, 96), avg(85, 97), avg(86, 98)},
+				{avg(124, 144), avg(125, 146), avg(126, 147), avg(127, 148), avg(129, 150), avg(130, 151)},
+				{avg(189, 211), avg(190, 213), avg(192, 215), avg(193, 216), avg(195, 218), avg(197, 219)},
+				{avg(256, 288), avg(257, 290), avg(259, 292), avg(261, 294), avg(263, 296), avg(265, 298)},
+				{avg(346, 390), avg(348, 393), avg(350, 395), avg(352, 397), avg(354, 399), avg(357, 401)},
+				{avg(445, 499), avg(447, 502), avg(450, 505), avg(452, 507), avg(455, 510), avg(458, 512)},
+				{avg(588, 658), avg(591, 661), avg(594, 664), avg(597, 667), avg(600, 670)},
+				{avg(682, 764), avg(685, 768), avg(688, 771), avg(692, 775), avg(695, 778)},
+				{avg(785,879), avg(788,883)} }}
+		else
+			spellData[HolyLight] = { coeff = 2.5 / 3.5, levels = {1, 6, 14, 22, 30, 38, 46, 54, 60, 62, 70}, averages = {
+				{avg(39, 47), avg(39, 48), avg(40, 49), avg(41, 50), avg(42, 51)},
+				{avg(76, 90), avg(77, 92), avg(78, 93), avg(79, 94), avg(80, 95), avg(81, 96)},
+				{avg(159, 187), avg(160, 189), avg(162, 191), avg(164, 193), avg(165, 194), avg(167, 196)},
+				{avg(310, 356), avg(312, 359), avg(314, 361), avg(317, 364), avg(319, 366), avg(322, 368)},
+				{avg(491, 553), avg(494, 557), avg(497, 560), avg(500, 563), avg(503, 566), avg(506, 569)},
+				{avg(698, 780), avg(701, 784), avg(705, 788), avg(709, 792), avg(713, 796), avg(717, 799)},
+				{avg(945, 1053), avg(949, 1058), avg(954, 1063), avg(958, 1067), avg(963, 1072), avg(968, 1076)},
+				{avg(1246, 1388), avg(1251, 1394), avg(1256, 1399), avg(1261, 1404), avg(1266, 1409), avg(1272, 1414)},
+				{avg(1590, 1770), avg(1595, 1775), avg(1601, 1781), avg(1607, 1787), avg(1613, 1793), avg(1619, 1799)},
+				{avg(1741, 1939), avg(1747, 1946), avg(1753, 1952), avg(1760, 1959), avg(1766, 1965), avg(1773, 1971)},
+				{avg(2196, 2446)} }}
+			spellData[FlashofLight] = { coeff = 1.5 / 3.5, levels = {20, 26, 34, 42, 50, 58, 66}, averages = {
+				{avg(62, 72), avg(63, 73), avg(64, 74), avg(65, 75), avg(66, 76), avg(67, 77)},
+				{avg(96, 110), avg(97, 112), avg(98, 113), avg(99, 114), avg(101, 116), avg(102, 117)},
+				{avg(145, 163), avg(146, 165), avg(148, 167), avg(149, 168), avg(151, 170), avg(153, 171)},
+				{avg(197, 221), avg(198, 223), avg(200, 225), avg(202, 227), avg(204, 229), avg(206, 231)},
+				{avg(267, 299), avg(269, 302), avg(271, 304), avg(273, 306), avg(275, 308), avg(278, 310)},
+				{avg(343, 383), avg(345, 386), avg(348, 389), avg(350, 391), avg(353, 394), avg(356, 396)},
+				{avg(448, 502), avg(450, 505), avg(453, 508), avg(455, 510), avg(458, 513)} }}
+		end

 		talentData[HealingLight] = { mod = 0.04, current = 0 }
+		talentData[Divinity] = { mod = 0.01, current = 0 }
+		talentData[TouchedbytheLight] = {mod = 0.10, current = 0}

 		itemSetsData["Lightbringer"] = {30992, 30983, 30988, 30994, 30996, 34432, 34487, 34559}
+		itemSetsData["Lightsworn"] = {50865, 50866, 50867, 50868, 50869, 51270, 51271, 51272, 51273, 51274, 51165, 51166, 51167, 51168, 51169}

-		local flashLibrams = {[23006] = 83, [23201] = 53, [186065] = 10, [25644] = 79}
+		local flashLibrams
+		if isWrath then
+			flashLibrams = {[51472] = 510, [42616] = 436, [42615] = 375, [42614] = 331, [42613] = 293, [42612] = 204, [28592] = 89, [25644] = 79, [23006] = 43, [23201] = 28}
+		else
+			flashLibrams = {[23006] = 83, [23201] = 53, [186065] = 10, [25644] = 79}
+		end
+		local holyLibrams = {[45436] = 160, [40268] = 141, [28296] = 47}

 		local blessings = {
 			[19977] = {
@@ -1066,13 +1286,23 @@ if( playerClass == "PALADIN" ) then
 		}

 		AuraHandler = function(unit, guid)
+			if( unitHasAura(unit, BeaconofLight) ) then
+				activeBeaconGUID = guid
+			elseif( activeBeaconGUID == guid ) then
+				activeBeaconGUID = nil
+			end
+
 			if( unit == "player" ) then
 				hasDivineFavor = unitHasAura("player", DivineFavor)
 			end
 		end

-		GetHealTargets = function(bitType, guid, healAmount, spellID)
-			return compressGUID[guid], healAmount
+		GetHealTargets = function(bitType, guid, spellID)
+			if( activeBeaconGUID and activeBeaconGUID ~= guid and guidToUnit[activeBeaconGUID] and UnitIsVisible(guidToUnit[activeBeaconGUID]) ) then
+				return string.format("%s,%s", compressGUID[guid], compressGUID[activeBeaconGUID])
+			end
+
+			return compressGUID[guid]
 		end

 		CalculateHealing = function(guid, spellID, unit)
@@ -1081,23 +1311,31 @@ if( playerClass == "PALADIN" ) then
 			local spellPower = GetSpellBonusHealing()
 			local healModifier, spModifier = playerHealModifier, 1

-			if isTBC then
-				healModifier = healModifier * (1 + talentData[HealingLight].current)
+			if( glyphCache[54943] and unitHasAura("player", SealofLight) ) then
+				healModifier = healModifier * 1.05
+			end
+
+			if isTBC or isWrath then
+				healModifier = healModifier * (1 + talentData[HealingLight].current) * (1 + (talentData[Divinity].current * (UnitIsUnit(unit,"player") and 2 or 1)))
 			else
 				healAmount = healAmount * (1 + talentData[HealingLight].current)
 			end

 			if playerCurrentRelic then
-				if spellName == FlashofLight and flashLibrams[playerCurrentRelic] then
+				if( spellName == HolyLight and holyLibrams[playerCurrentRelic] ) then
+					spellPower = spellPower + holyLibrams[playerCurrentRelic]
+				elseif( spellName == FlashofLight and flashLibrams[playerCurrentRelic] ) then
 					spellPower = spellPower + flashLibrams[playerCurrentRelic]
-				elseif spellName == HolyLight and playerCurrentRelic == 28296 then
-					spellPower = spellPower + 87
 				end
 			end

+			if( equippedSetCache["Lightsworn"] >= 2 and unitHasAura("player", DivineIllumination) ) then
+				healModifier = healModifier * 1.35
+			end
+
 			if( equippedSetCache["Lightbringer"] >= 4 and spellName == FlashofLight ) then healModifier = healModifier + 0.05 end

-			spellPower = spellPower * spellData[spellName].coeff
+			spellPower = spellPower * spellData[spellName].coeff * (isWrath and 2.35 or 1)
 			healAmount = calculateGeneralAmount(spellData[spellName].levels[spellRank], healAmount, spellPower, spModifier, healModifier)

 			for auraID, values in pairs(blessings) do
@@ -1116,7 +1354,7 @@ if( playerClass == "PALADIN" ) then
 			end

 			if( hasDivineFavor or GetSpellCritChance(2) >= 100 ) then
-				healAmount = healAmount * 1.50
+				healAmount = healAmount * (1.50 * (1 + talentData[TouchedbytheLight].current))
 			end

 			return DIRECT_HEALS, ceil(healAmount)
@@ -1135,19 +1373,27 @@ if( playerClass == "PRIEST" ) then
 		local SpiritualHealing = GetSpellInfo(14898)
 		local ImprovedRenew = GetSpellInfo(14908)
 		local GreaterHealHot = GetSpellInfo(22009)
-		local CureDisease = GetSpellInfo(528)
+		local DispelMagic = GetSpellInfo(527)
 		local BindingHeal = GetSpellInfo(32546) or "Binding Heal"
 		local EmpoweredHealing = GetSpellInfo(33158) or "Empowered Healing"
 		local Renewal = GetSpellInfo(37563) and "37563" -- T4 bonus
-
-		hotData[Renew] = {coeff = 1, interval = 3, ticks = 5, levels = {8, 14, 20, 26, 32, 38, 44, 50, 56, 60, 65, 70}, averages = {
-			45, 100, 175, 245, 315, 400, 510, 650, 810, 970, 1010, 1110 }}
+		local Penance = GetSpellInfo(53007) or "Penance"
+		local Grace = GetSpellInfo(47517) or "Grace"
+		local BlessedResilience = GetSpellInfo(33142) or "Blessed Resilience"
+		local FocusedPower = GetSpellInfo(33190) or "Focused Power"
+		local DivineProvidence = GetSpellInfo(47567) or "Divine Providence"
+		local EmpoweredRenew = GetSpellInfo(63534) or "Empowered Renew"
+		local TwinDisciplines = GetSpellInfo(47586) or "Twin Disciplines"
+
+		hotData[Renew] = {coeff = 1, interval = 3, ticks = 5, levels = {8, 14, 20, 26, 32, 38, 44, 50, 56, 60, 65, 70, 75, 80}, averages = {
+			45, 100, 175, 245, 315, 400, 510, 650, 810, 970, 1010, 1110, 1235, 1400 }}
 		hotData[GreaterHealHot] = hotData[Renew]
-		if isTBC then -- prevent error on Classic Era realms
+
+		if Renewal then
 			hotData[Renewal] = {coeff = 0, interval = 3, ticks = 3, levels = {70}, averages = {150}}
 		end

-		spellData[FlashHeal] = {coeff = 1.5 / 3.5, levels = {20, 26, 32, 38, 44, 50, 56, 61, 67}, averages = {
+		spellData[FlashHeal] = {coeff = 1.5 / 3.5, levels = {20, 26, 32, 38, 44, 50, 56, 61, 67, 73, 79}, averages = {
 			{avg(193, 237), avg(194, 239), avg(196, 241), avg(198, 243),  avg(200, 245), avg(202, 247)},
 			{avg(258, 314), avg(260, 317), avg(262, 319), avg(264, 321), avg(266, 323), avg(269, 325)},
 			{avg(327, 393), avg(329, 396), avg(332, 398), avg(334, 401), avg(337, 403), avg(339, 406)},
@@ -1156,15 +1402,19 @@ if( playerClass == "PRIEST" ) then
 			{avg(644, 764), avg(647, 768), avg(651, 772), avg(655, 776), avg(658, 779), avg(662, 783)},
 			{avg(812, 958), avg(816, 963), avg(820, 967), avg(824, 971), avg(828, 975), avg(833, 979)},
 			{avg(913, 1059), avg(917, 1064), avg(922, 1069), avg(927, 1074), avg(931, 1078)},
-			{avg(1101, 1279), avg(1106, 1285), avg(1111, 1290), avg(1116, 1295)} }}
-		spellData[GreaterHeal] = {coeff = 3 / 3.5, levels = {40, 46, 52, 58, 60, 63, 68}, averages = {
+			{avg(1101, 1279), avg(1106, 1285), avg(1111, 1290), avg(1116, 1295), avg(1121, 1300)},
+			{avg(1578, 1832), avg(1586, 1840), avg(1594, 1848), avg(1602, 1856), avg(1610, 1864), avg(1618, 1872)},
+			{avg(1887, 2193), avg(1896, 2203)} }}
+		spellData[GreaterHeal] = {coeff = 3 / 3.5, levels = {40, 46, 52, 58, 60, 63, 68, 73, 78}, averages = {
 			{avg(899, 1013), avg(904, 1019), avg(909, 1024), avg(914, 1029), avg(919, 1034), avg(924, 1039)},
 			{avg(1149, 1289), avg(1154, 1295), avg(1160, 1301), avg(1166, 1307), avg(1172, 1313), avg(1178, 1318)},
 			{avg(1437, 1609), avg(1443, 1616), avg(1450, 1623), avg(1456, 1629), avg(1463, 1636), avg(1470, 1642)},
 			{avg(1798, 2006), avg(1805, 2014), avg(1813, 2021), avg(1820, 2029), avg(1828, 2036), avg(1835, 2044)},
 			{avg(1966, 2194), avg(1974, 2203), avg(1982, 2211), avg(1990, 2219), avg(1998, 2227), avg(2006, 2235)},
 			{avg(2074, 2410), avg(2082, 2419), avg(2090, 2427), avg(2099, 2436), avg(2107, 2444)},
-			{avg(2396, 2784), avg(2405, 2794), avg(2414, 2803)} }}
+			{avg(2396, 2784), avg(2405, 2794), avg(2414, 2803), avg(2423, 2812), avg(2433, 2822)},
+			{avg(3395, 3945), avg(3408, 3959), avg(3421, 3972), avg(3434, 3985), avg(3447, 3998)},
+			{avg(3950, 4590), avg(3965, 4606), avg(3980, 4621)}	}}
 		spellData[Heal] = {coeff = 3 / 3.5, levels = {16, 22, 28, 34}, averages = {
 			{avg(295, 341), avg(297, 344), avg(299, 346), avg(302, 349), avg(304, 351), avg(307, 353)},
 			{avg(429, 491), avg(432, 495), avg(435, 498), avg(438, 501), avg(441, 504), avg(445, 507)},
@@ -1174,48 +1424,77 @@ if( playerClass == "PRIEST" ) then
 			{avg(46, 56), avg(46, 57), avg(47, 58)},
 			{avg(71, 85), avg(72, 87), avg(73, 88), avg(74, 89), avg(75, 90), avg(76, 91)},
 			{avg(135, 157), avg(136, 159), avg(138, 161), avg(139, 162), avg(141, 164), avg(143, 165)} }}
-		spellData[PrayerofHealing] = {coeff = isTBC and 0.431596 or (3/3.5/3), levels = {30, 40, 50, 60, 60, 68}, averages = {
+		spellData[PrayerofHealing] = {coeff = (isWrath and 0.2798 or isTBC and 0.431596 or (3/3.5/3)), levels = {30, 40, 50, 60, 60, 68, 76}, averages = {
 			{avg(301, 321), avg(302, 323), avg(303, 324), avg(304, 325), avg(306, 327), avg(307, 328), avg(308, 329), avg(310, 331), avg(311, 332), avg(312, 333)},
 			{avg(444, 472), avg(445, 474), avg(447, 476), avg(448, 477), avg(450, 479), avg(452, 480), avg(453, 482), avg(455, 484), avg(456, 485), avg(458, 487)},
 			{avg(657, 695), avg(659, 697), avg(661, 699), avg(663, 701), avg(665, 703), avg(667, 705), avg(669, 707), avg(671, 709), avg(673, 711), avg(675, 713)},
 			{avg(939, 991), avg(941, 994), avg(943, 996), avg(946, 999), avg(948, 1001), avg(951, 1003), avg(953, 1006), avg(955, 1008), avg(958, 1011), avg(960, 1013)},
 			{avg(997, 1053), avg(999, 1056), avg(1002, 1058), avg(1004, 1061), avg(1007, 1063), avg(1009, 1066), avg(1012, 1068), avg(1014, 1071), avg(1017, 1073), avg(1019, 1076)},
-			{avg(1246, 1316), avg(1248, 1319), avg(1251, 1322)} }}
-		spellData[BindingHeal] = {coeff = 1.5 / 3.5, levels = {64}, averages = {
-			{avg(1042, 1338), avg(1043, 1340), avg(1045, 1342), avg(1047, 1344), avg(1049, 1346), avg(1051, 1348), avg(1053, 1350)} }}
+			{avg(1246, 1316), avg(1248, 1319), avg(1251, 1322), avg(1254, 1325), avg(1257, 1328), avg(1260, 1330), avg(1262, 1333), avg(1265, 1336)},
+			{avg(2091, 2209), avg(2095, 2214), avg(2100, 2219), avg(2105, 2224), avg(2109, 2228)} }}
+		spellData[BindingHeal] = {coeff = 1.5 / 3.5, levels = {64, 72, 78}, averages = {
+			{avg(1042, 1338), avg(1043, 1340), avg(1045, 1342), avg(1047, 1344), avg(1049, 1346), avg(1051, 1348), avg(1053, 1350), avg(1055, 1352)},
+			{avg(1619, 2081), avg(1622, 2084), avg(1625, 2087), avg(1628, 2090), avg(1631, 2093)},
+			{avg(1952, 2508), avg(1955, 2512), avg(1959, 2516)} }}
+		spellData[Penance] = {_isChanneled = true, coeff = 0.857, ticks = 3, levels = {60, 70, 75, 80}, averages = {avg(670, 756), avg(805, 909), avg(1278, 1442), avg(1484, 1676)}}

 		talentData[ImprovedRenew] = {mod = 0.05, current = 0}
 		talentData[SpiritualHealing] = {mod = 0.02, current = 0}
 		talentData[EmpoweredHealing] = {mod = 0.02, current = 0}
+		if isWrath then
+			talentData[EmpoweredHealing].mod = 0.04
+		end
+		talentData[BlessedResilience] = {mod = 0.01, current = 0}
+		talentData[FocusedPower] = {mod = 0.02, current = 0}
+		talentData[DivineProvidence] = {mod = 0.02, current = 0}
+		talentData[EmpoweredRenew] = {mod = 0.05, current = 0}
+		talentData[TwinDisciplines] = {mod = 0.01, current = 0}

 		itemSetsData["Oracle"] = {21351, 21349, 21350, 21348, 21352}
 		itemSetsData["Absolution"] = {31068, 31063, 31060, 31069, 31066, 34562, 34527, 34435}
 		itemSetsData["Avatar"] = {30153, 30152, 30151, 30154, 30150}

-		GetHealTargets = function(bitType, guid, healAmount, spellID)
+		local activeGraceGUID, activeGraceModifier = nil, 0
+		AuraHandler = function(unit, guid)
+			local stack, _, _, _, caster = select(3, unitHasAura(unit, Grace))
+			if( caster == "player" ) then
+				activeGraceModifier = stack * 0.03
+				activeGraceGUID = guid
+			elseif( activeGraceGUID == guid ) then
+				activeGraceGUID = nil
+			end
+		end
+
+		GetHealTargets = function(bitType, guid, spellID)
 			local spellName = GetSpellInfo(spellID)
 			if( spellName == BindingHeal ) then
 				if guid == playerGUID then
-					return string.format("%s", compressGUID[playerGUID]), healAmount
+					return format("%s", compressGUID[playerGUID])
 				else
-					return string.format("%s,%s", compressGUID[guid], compressGUID[playerGUID]), healAmount
+					return format("%s,%s", compressGUID[guid], compressGUID[playerGUID])
 				end
 			elseif( spellName == PrayerofHealing ) then
-				guid = UnitGUID("player")
+				-- In Wrath PoH can be castet on other groups than your own
+				if not isWrath then
+					guid = UnitGUID("player")
+				end
 				local targets = compressGUID[guid]
 				local group = guidToGroup[guid]

 				for groupGUID, id in pairs(guidToGroup) do
-					local unit = guidToUnit[groupGUID]
-					if( id == group and guid ~= groupGUID and (IsSpellInRange(CureDisease, unit) == 1 or CheckInteractDistance(unit, 4)) ) then
+					--We skip the rangecheck in Wrath since range would have to be measured from our target to its party and we can't do that
+					local unit = isWrath and "player" or guidToUnit[groupGUID]
+					local testUnit = guidToUnit[groupGUID]
+					-- Dispel Magic is chosen because it's learned before PoH and maintains 30y range through the expansions
+					if( id == group and guid ~= groupGUID and (IsSpellInRange(DispelMagic, unit) == 1 or CheckInteractDistance(unit, 4)) and UnitIsVisible(testUnit) and not UnitHasVehicleUI(testUnit) ) then
 						targets = targets .. "," .. compressGUID[groupGUID]
 					end
 				end

-				return targets, healAmount
+				return targets
 			end

-			return compressGUID[guid], healAmount
+			return compressGUID[guid]
 		end

 		CalculateHotHealing = function(guid, spellID)
@@ -1225,48 +1504,66 @@ if( playerClass == "PRIEST" ) then
 			local healModifier, spModifier = playerHealModifier, 1
 			local totalTicks

-			if isTBC then
+			if isWrath then
+				healModifier = healModifier + talentData[SpiritualHealing].current
+			elseif isTBC then
 				healModifier = healModifier * (1 + talentData[SpiritualHealing].current)
 			else
-				-- Spiritual Healing only applies to base values
+				-- Spiritual Healing only applies to base value in classic
 				healAmount = healAmount * (1 + talentData[SpiritualHealing].current)
 			end

 			if( spellName == Renew or spellName == GreaterHealHot ) then
-				if isTBC then
+				if isWrath then
+					healModifier = healModifier + talentData[ImprovedRenew].current
+				elseif isTBC then
 					healModifier = healModifier * (1 + talentData[ImprovedRenew].current)
 				else
 					-- Improved Renew only applies to the base value in classic
 					healAmount = healAmount * (1 + talentData[ImprovedRenew].current)
 				end
+				healModifier = healModifier + talentData[TwinDisciplines].current

-				local duration = 15
-				local ticks = hotData[spellName].ticks
+				totalTicks = hotData[spellName].ticks
+
+				if( glyphCache[55674] ) then
+					healModifier = healModifier + 0.25
+					-- completly lose a tick
+					healAmount = healAmount - (healAmount / totalTicks)
+					spellPower = spellPower - (spellPower / totalTicks)
+					totalTicks = totalTicks - 1
+				end

 				if( equippedSetCache["Oracle"] >= 5 or equippedSetCache["Avatar"] >= 4 ) then
-					healAmount = healAmount + (healAmount / ticks) -- Add Tick Amount Gained by Set.
-					duration = 18
-					ticks = ticks + 1
+					healAmount = healAmount + (healAmount / totalTicks) -- Add Tick Amount gained by Set.
+					totalTicks = totalTicks + 1
 				end

-				totalTicks = ticks
+				spellPower = spellPower * ((isWrath and 1.88 or 1) * (1 + (talentData[EmpoweredRenew].current)))
+				spellPower = spellPower / totalTicks
+				healAmount = healAmount / totalTicks
+			end

-				spellPower = spellPower / ticks
-				healAmount = healAmount / ticks
+			if( activeGraceGUID == guid ) then
+				healModifier = healModifier * (1 + activeGraceModifier)
 			end

+			healModifier = healModifier * (1 + talentData[FocusedPower].current)
+			healModifier = healModifier * (1 + talentData[BlessedResilience].current)
+
 			healAmount = calculateGeneralAmount(hotData[spellName].levels[spellRank], healAmount, spellPower, spModifier, healModifier)
 			return HOT_HEALS, ceil(healAmount), totalTicks, hotData[spellName].interval
 		end

-		-- If only every other class was as easy as Paladins
 		CalculateHealing = function(guid, spellID)
 			local spellName, spellRank = GetSpellInfo(spellID), SpellIDToRank[spellID]
 			local healAmount = getBaseHealAmount(spellData, spellName, spellID, spellRank)
 			local spellPower = GetSpellBonusHealing()
 			local healModifier, spModifier = playerHealModifier, 1

-			if isTBC then
+			if isWrath then
+				healModifier = healModifier + talentData[SpiritualHealing].current
+			elseif isTBC then
 				healModifier = healModifier * (1 + talentData[SpiritualHealing].current)
 			else
 				healAmount = healAmount * (1 + talentData[SpiritualHealing].current)
@@ -1275,28 +1572,39 @@ if( playerClass == "PRIEST" ) then
 			-- Greater Heal
 			if( spellName == GreaterHeal ) then
 				if( equippedSetCache["Absolution"] >= 4 ) then healModifier = healModifier * 1.05 end
-				healAmount = healAmount + (spellPower * (talentData[EmpoweredHealing].current * 2))
-				spellPower = spellPower * spellData[spellName].coeff
+				spellPower = spellPower * ((spellData[spellName].coeff * (isWrath and 1.88 or 1)) * (1 + (talentData[EmpoweredHealing].current * 2)))
 				-- Flash Heal
 			elseif( spellName == FlashHeal ) then
-				healAmount = healAmount + (spellPower * talentData[EmpoweredHealing].current)
-				spellPower = spellPower * spellData[spellName].coeff
+				spellPower = spellPower * ((spellData[spellName].coeff * (isWrath and 1.88 or 1)) * (1 + talentData[EmpoweredHealing].current))
 				-- Binding Heal
 			elseif( spellName == BindingHeal ) then
-				healAmount = healAmount + (spellPower * talentData[EmpoweredHealing].current)
-				spellPower = spellPower * spellData[spellName].coeff
+				healModifier = healModifier + talentData[DivineProvidence].current
+				spellPower = spellPower * ((spellData[spellName].coeff * (isWrath and 1.88 or 1)) * (1 + talentData[EmpoweredHealing].current))
+				-- Penance
+			elseif( spellName == Penance ) then
+				spellPower = spellPower * (spellData[spellName].coeff * 1.88)
+				spellPower = spellPower / spellData[spellName].ticks
+				healModifier = healModifier + talentData[TwinDisciplines].current
 				-- Prayer of Healing
 			elseif( spellName == PrayerofHealing ) then
-				spellPower = spellPower * spellData[spellName].coeff
+				healModifier = healModifier + talentData[DivineProvidence].current
+				spellPower = spellPower * spellData[spellName].coeff * (isWrath and 1.88 or 1)
 				-- Heal
 			elseif( spellName == Heal ) then
-				spellPower = spellPower * spellData[spellName].coeff
+				spellPower = spellPower * spellData[spellName].coeff * (isWrath and 1.88 or 1)
 				-- Lesser Heal
 			elseif( spellName == LesserHeal ) then
 				local castTime = spellRank >= 3 and 2.5 or spellRank == 2 and 2 or 1.5
-				spellPower = spellPower * (castTime / 3.5)
+				spellPower = spellPower * (castTime / 3.5) * (isWrath and 1.88 or 1)
 			end

+			if( activeGraceGUID == guid ) then
+				healModifier = healModifier * (1 + activeGraceModifier)
+			end
+
+			healModifier = healModifier * (1 + talentData[FocusedPower].current)
+			healModifier = healModifier * (1 + talentData[BlessedResilience].current)
+
 			healAmount = calculateGeneralAmount(spellData[spellName].levels[spellRank], healAmount, spellPower, spModifier, healModifier)

 			-- Player has over a 100% chance to crit with Holy spells
@@ -1304,6 +1612,11 @@ if( playerClass == "PRIEST" ) then
 				healAmount = healAmount * 1.50
 			end

+			-- Penance ticks 3 times, the player will see all 3 ticks, everyone else should only see the last 2
+			if( spellName == Penance ) then
+				return CHANNEL_HEALS, math.ceil(healAmount), spellData[spellName].ticks, 1
+			end
+
 			return DIRECT_HEALS, ceil(healAmount)
 		end
 	end
@@ -1315,16 +1628,25 @@ if( playerClass == "SHAMAN" ) then
 		local HealingWave = GetSpellInfo(331)
 		local LesserHealingWave = GetSpellInfo(8004)
 		local ImpChainHeal = GetSpellInfo(30872) or "Improved Chain Heal"
-		local HealingWay = GetSpellInfo(29206)
-		local Purification = GetSpellInfo(16178)
+		local HealingWay = GetSpellInfo(29206) or "Healing Way"
+		local Purification = GetSpellInfo(16178) or "Purification"
+		local EarthShield = GetSpellInfo(49284) or "Earth Shield"
+		local TidalWaves = GetSpellInfo(51566) or "Tidal Waves"
+		local Riptide = GetSpellInfo(61295) or "Riptide"
+		local Earthliving = GetSpellInfo(52000) or "Earthliving"

-		spellData[ChainHeal] = {coeff = 2.5 / 3.5, levels = {40, 46, 54, 61, 68}, averages = {
+		hotData[Riptide] = {interval = 3, ticks = 5, coeff = 0.50, levels = {60, 70, 75, 80}, averages = {665, 885, 1435, 1670}}
+		hotData[Earthliving] = {interval = 3, ticks = 4, coeff = 0.80, levels = {30, 40, 50, 60, 70, 80}, averages = {116, 160, 220, 348, 456, 652}}
+
+		spellData[ChainHeal] = {coeff = 2.5 / 3.5, levels = {40, 46, 54, 61, 68, 74, 80}, averages = {
 			{avg(320, 368), avg(322, 371), avg(325, 373), avg(327, 376), avg(330, 378), avg(332, 381)},
 			{avg(405, 465), avg(407, 468), avg(410, 471), avg(413, 474), avg(416, 477), avg(419, 479)},
 			{avg(551, 629), avg(554, 633), avg(557, 636), avg(560, 639), avg(564, 643), avg(567, 646)},
 			{avg(605, 691), avg(608, 695), avg(612, 699), avg(616, 703), avg(620, 707), avg(624, 710)},
-			{avg(826, 942), avg(829, 946), avg(833, 950)} }}
-		spellData[HealingWave] = {levels = {1, 6, 12, 18, 24, 32, 40, 48, 56, 60, 63, 70}, averages = {
+			{avg(826, 942), avg(829, 946), avg(833, 950), avg(837, 954), avg(841, 958), avg(845, 961)},
+			{avg(906, 1034), avg(909, 1038), avg(913, 1042), avg(917, 1046), avg(921, 1050), avg(925, 1053)},
+			{avg(1055, 1205)} }}
+		spellData[HealingWave] = {levels = {1, 6, 12, 18, 24, 32, 40, 48, 56, 60, 63, 70, 75, 80}, averages = {
 			{avg(34, 44), avg(34, 45), avg(35, 46), avg(36, 47)},
 			{avg(64, 78), avg(65, 79), avg(66, 80), avg(67, 81), avg(68, 82), avg(69, 83)},
 			{avg(129, 155), avg(130, 157), avg(132, 158), avg(133, 160), avg(135, 161), avg(136, 163)},
@@ -1336,37 +1658,107 @@ if( playerClass == "SHAMAN" ) then
 			{avg(1367, 1561), avg(1372, 1567), avg(1378, 1572), avg(1383, 1578), avg(1389, 1583), avg(1394, 1589)},
 			{avg(1620, 1850), avg(1625, 1856), avg(1631, 1861), avg(1636, 1867), avg(1642, 1872), avg(1647, 1878)},
 			{avg(1725, 1969), avg(1731, 1976), avg(1737, 1982), avg(1743, 1988), avg(1750, 1995), avg(1756, 2001)},
-			{avg(2134, 2436)} }}
-		spellData[LesserHealingWave] = {coeff = 1.5 / 3.5, levels = {20, 28, 36, 44, 52, 60, 66}, averages = {
+			{avg(2134, 2436), avg(2141, 2444), avg(2148, 2451), avg(2155, 2458), avg(2162, 2465)},
+			{avg(2624, 2996), avg(2632, 3004), avg(2640, 3012), avg(2648, 3020), avg(2656, 3028)},
+			{avg(3034, 3466)} }}
+		spellData[LesserHealingWave] = {coeff = 1.5 / 3.5, levels = {20, 28, 36, 44, 52, 60, 66, 72, 77}, averages = {
 			{avg(162, 186), avg(163, 188), avg(165, 190), avg(167, 192), avg(168, 193), avg(170, 195)},
 			{avg(247, 281), avg(249, 284), avg(251, 286), avg(253, 288), avg(255, 290), avg(257, 292)},
 			{avg(337, 381), avg(339, 384), avg(342, 386), avg(344, 389), avg(347, 391), avg(349, 394)},
 			{avg(458, 514), avg(461, 517), avg(464, 520), avg(467, 523), avg(470, 526), avg(473, 529)},
 			{avg(631, 705), avg(634, 709), avg(638, 713), avg(641, 716), avg(645, 720), avg(649, 723)},
 			{avg(832, 928), avg(836, 933), avg(840, 937), avg(844, 941), avg(848, 945), avg(853, 949)},
-			{avg(1039, 1185), avg(1043, 1190), avg(1047, 1194), avg(1051, 1198)} }}
+			{avg(1039, 1185), avg(1043, 1190), avg(1047, 1194), avg(1051, 1198), avg(1055, 1202)},
+			{avg(1382, 1578), avg(1387, 1583), avg(1392, 1588), avg(1397, 1593), avg(1402, 1598)},
+			{avg(1606, 1834), avg(1612, 1840), avg(1618, 1846), avg(1624, 1852)} }}

-		talentData[HealingWay] = {mod = 0, current = 0}
+		talentData[HealingWay] = {mod = (0.25/3), current = 0}
 		talentData[ImpChainHeal] = {mod = 0.10, current = 0}
 		talentData[Purification] = {mod = 0.02, current = 0}
+		talentData[TidalWaves] = {mod = 0.04, current = 0}

 		itemSetsData["Skyshatter"] = {31016, 31007, 31012, 31019, 31022, 34543, 34438, 34565}
+		itemSetsData["T7 Resto"] = {40508, 40509, 40510, 40512, 40513, 39583, 39588, 39589, 39590, 39591}
+		itemSetsData["T9 Resto"] = {48280, 48281, 48282, 48283, 48284, 48295, 48296, 48297, 48298, 48299, 48301, 48302, 48303, 48304, 48300, 48306, 48307, 48308, 48309, 48305, 48286, 48287, 48288, 48289, 48285, 48293, 48292, 48291, 48290, 48294}

-		local lhwTotems = {[22396] = 80, [23200] = 53, [186072] = 10, [25645] = 79}
+		local lhwTotems = {[42598] = 320, [42597] = 267, [42596] = 236, [42595] = 204, [25645] = 79, [22396] = 80, [23200] = 53, [186072] = 10}
+		local chTotems = {[45114] = 243, [38368] = 102, [28523] = 87}
+
+		-- Keep track of who has riptide on them
+		local riptideData, earthshieldList = {}, {}
+		AuraHandler = function(unit, guid)
+			riptideData[guid] = unitHasAura(unit, Riptide) and true or nil
+
+			-- Currently, Glyph of Lesser Healing Wave + Any Earth Shield increase the healing not just the players own
+			if( unitHasAura(unit, EarthShield) ) then
+				earthshieldList[guid] = true
+			elseif( earthshieldList[guid] ) then
+				earthshieldList[guid] = nil
+			end
+		end
+
+		ResetChargeData = function(guid)
+			riptideData[guid] = guidToUnit[guid] and unitHasAura(guidToUnit[guid], Riptide) and true or nil
+		end

 		-- Lets a specific override on how many people this will hit
-		GetHealTargets = function(bitType, guid, healAmount)
-			return compressGUID[guid], healAmount
+		GetHealTargets = function(bitType, guid, spellID, amount)
+			local spellName = GetSpellInfo(spellID)
+			-- Glyph of Healing Wave, heals you for 20% of your heal when you heal someone else
+			if( glyphCache[55440] and guid ~= playerGUID and spellName == HealingWave ) then
+				if guidToUnit[guid] then
+					return string.format("%s,%d,%s,%d", compressGUID[guid], amount, compressGUID[playerGUID], amount *  0.20), -1
+				else
+					return compressGUID[UnitGUID("player")], amount *  0.20
+				end
+			end
+
+			return compressGUID[guid]
+		end
+
+		CalculateHotHealing = function(guid, spellID)
+			local spellName, spellRank = GetSpellInfo(spellID), SpellIDToRank[spellID]
+			local healAmount = getBaseHealAmount(hotData, spellName, spellID, spellRank)
+			local spellPower = GetSpellBonusHealing()
+			local healModifier, spModifier = playerHealModifier, 1
+			local totalTicks
+
+			healModifier = healModifier * (1 + talentData[Purification].current)
+
+			-- Riptide
+			if( spellName == Riptide ) then
+				if( equippedSetCache["T9 Resto"] >= 2 ) then
+					spModifier = spModifier * 1.20
+				end
+
+				spellPower = spellPower * (hotData[spellName].coeff * 1.88)
+				spellPower = spellPower / hotData[spellName].ticks
+				healAmount = healAmount / hotData[spellName].ticks
+
+				totalTicks = hotData[spellName].ticks
+				-- Glyph of Riptide, +6 seconds
+				if( glyphCache[63273] ) then totalTicks = totalTicks + 2 end
+
+			-- Earthliving Weapon
+			elseif( spellName == Earthliving ) then
+				spellPower = (spellPower * (hotData[spellName].coeff * 1.88) * 0.45)
+				spellPower = spellPower / hotData[spellName].ticks
+				healAmount = healAmount / hotData[spellName].ticks
+
+				totalTicks = hotData[spellName].ticks
+			end
+
+			healAmount = calculateGeneralAmount(hotData[spellName].levels[spellRank], healAmount, spellPower, spModifier, healModifier)
+			return HOT_HEALS, healAmount, totalTicks, hotData[spellName].interval
 		end

-		-- If only every other class was as easy as Paladins
 		CalculateHealing = function(guid, spellID, unit)
 			local spellName, spellRank = GetSpellInfo(spellID), SpellIDToRank[spellID]
 			local healAmount = getBaseHealAmount(spellData, spellName, spellID, spellRank)
 			local spellPower = GetSpellBonusHealing()
 			local healModifier, spModifier = playerHealModifier, 1

-			if isTBC then
+			if isTBC or isWrath then
 				healModifier = healModifier * (1 + talentData[Purification].current)
 			else
 				-- Purification only applies to base values in classic
@@ -1375,33 +1767,57 @@ if( playerClass == "SHAMAN" ) then

 			-- Chain Heal
 			if( spellName == ChainHeal ) then
-				spellPower = spellPower * spellData[spellName].coeff
+				spellPower = spellPower * spellData[spellName].coeff * (isWrath and 1.88 or 1)

 				if( equippedSetCache["Skyshatter"] >= 4 ) then
 					healModifier = healModifier * 1.05
 				end

+				if( equippedSetCache["T7 Resto"] >= 4 ) then
+					healModifier = healModifier * 1.05
+				end
+
 				healModifier = healModifier * (1 + talentData[ImpChainHeal].current)

-				if playerCurrentRelic == 28523 then healAmount = healAmount + 87 end
-				-- Heaing Wave
+				-- Add +25% from Riptide being up and reset the flag
+				if( riptideData[guid] ) then
+					healModifier = healModifier * 1.25
+					riptideData[guid] = nil
+				end
+
+				if playerCurrentRelic and chTotems[playerCurrentRelic] then
+					healAmount = healAmount + chTotems[playerCurrentRelic]
+				end
+				-- Healing Wave
 			elseif( spellName == HealingWave ) then
 				local hwStacks = select(3, unitHasAura(unit, 29203))
 				if( hwStacks ) then
 					healAmount = healAmount * ((hwStacks * 0.06) + 1)
 				end
-				--healModifier = healModifier * (talentData[HealingWay].spent == 3 and 1.25 or talentData[HealingWay].spent == 2 and 1.16 or talentData[HealingWay].spent == 1 and 1.08 or 1)
+
+				if isWrath then
+					healModifier = healModifier * (1 + talentData[HealingWay].current)
+				end
+
+				if( equippedSetCache["T7 Resto"] >= 4 ) then
+					healModifier = healModifier * 1.05
+				end

 				local castTime = spellRank > 3 and 3 or spellRank == 3 and 2.5 or spellRank == 2 and 2 or 1.5

 				if playerCurrentRelic == 27544 then spellPower = spellPower + 88 end

-				spellPower = spellPower * (castTime / 3.5)
+				spellPower = spellPower * ((castTime / 3.5) * (isWrath and 1.88 or 1) + talentData[TidalWaves].current)

 				-- Lesser Healing Wave
 			elseif( spellName == LesserHealingWave ) then
+				-- Glyph of Lesser Healing Wave, +20% healing on LHW if target has ES up
+				if( glyphCache[55438] and earthshieldList[guid] ) then
+					healModifier = healModifier * 1.20
+				end
+
 				spellPower = spellPower + (playerCurrentRelic and lhwTotems[playerCurrentRelic] or 0)
-				spellPower = spellPower * spellData[spellName].coeff
+				spellPower = spellPower * (spellData[spellName].coeff * (isWrath and 1.88 or 1) + (talentData[TidalWaves].current / 2))
 			end

 			healAmount = calculateGeneralAmount(spellData[spellName].levels[spellRank], healAmount, spellPower, spModifier, healModifier)
@@ -1421,16 +1837,17 @@ if( playerClass == "HUNTER" ) then
 	LoadClassData = function()
 		local MendPet = GetSpellInfo(136)

-		if isTBC then
-			hotData[MendPet] = { interval = 3, levels = { 12, 20, 28, 36, 44, 52, 60, 68 }, ticks = 5, averages = {125, 250, 450, 700, 1000, 1400, 1825, 2375 } }
+		if isTBC or isWrath then
+			hotData[MendPet] = { interval = 3, levels = { 12, 20, 28, 36, 44, 52, 60, 68, 74, 80 }, ticks = 5, averages = {125, 250, 450, 700, 1000, 1400, 1825, 2375, 4250, 5250 } }
 		else
 			spellData[MendPet] = { interval = 1, levels = { 12, 20, 28, 36, 44, 52, 60 }, ticks = 5, averages = {100, 190, 340, 515, 710, 945, 1225 } }
 		end

 		itemSetsData["Giantstalker"] = {16851, 16849, 16850, 16845, 16848, 16852, 16846, 16847}

-		GetHealTargets = function(bitType, guid, healAmount, spellID)
-			return compressGUID[UnitGUID("pet")], healAmount
+		GetHealTargets = function(bitType, guid, spellID)
+			local petGUID = UnitGUID("pet")
+			return petGUID and compressGUID[petGUID]
 		end

 		CalculateHotHealing = function(guid, spellID)
@@ -1453,31 +1870,44 @@ if( playerClass == "HUNTER" ) then
 	end
 end

+--[[
+-- While the groundwork is done, "CalculateHealing" needs to be theory crafted for classic / TBC / WotLK. Deactivating until someone steps up.
 if( playerClass == "WARLOCK" ) then
 	LoadClassData = function()
 		local HealthFunnel = GetSpellInfo(755)
 		local DrainLife = GetSpellInfo(689)
 		local ImpHealthFunnel = GetSpellInfo(18703)
-
-		spellData[HealthFunnel] = { interval = 1, levels = { 12, 20, 28, 36, 44, 52, 60, 68 }, ticks = 10, averages = { 120, 240, 430, 640, 890, 1190, 1530, 1880 } }
-		spellData[DrainLife] = { interval = 1, levels = { 14, 22, 30, 38, 46, 54, 62, 69 }, ticks = 5, averages = { 10 * 5, 17 * 5, 29 * 5, 41 * 5, 55 * 5, 71 * 5, 87 * 5, 108 * 5 } }
-
+		local ShadowMastery = GetSpellInfo(18271)
+		spellData[HealthFunnel] = {_isChanneled = true, coeff = 0.548, interval = 1, levels = { 12, 20, 28, 36, 44, 52, 60, 68, 76 }, ticks = 10, averages = { 120, 240, 430, 640, 890, 1190, 1530, 1880, 5200 } }
+		spellData[DrainLife] = {_isChanneled = true, coeff = 0.143, interval = 1, levels = { 14, 22, 30, 38, 46, 54, 62, 69, 78 }, ticks = 5, averages = { 10 * 5, 17 * 5, 29 * 5, 41 * 5, 55 * 5, 71 * 5, 87 * 5, 108 * 5, 133 * 5 } }
 		talentData[ImpHealthFunnel] = { mod = 0.1, current = 0 }
-
-		GetHealTargets = function(bitType, guid, healAmount, spellID)
-			return compressGUID[UnitGUID("pet")], healAmount
+		talentData[ShadowMastery] = { mod = 0.1, current = 0 }
+		GetHealTargets = function(bitType, guid, spellID)
+			local spellName = GetSpellInfo(spellID)
+			local petGUID = UnitGUID("pet")
+			if spellName == DrainLife then
+				return compressGUID[playerGUID]
+			else
+				return petGUID and compressGUID[petGUID]
+			end
 		end
-
 		CalculateHealing = function(guid, spellID)
 			local spellName, spellRank = GetSpellInfo(spellID), SpellIDToRank[spellID]
 			local healAmount = getBaseHealAmount(spellData, spellName, spellID, spellRank)
-
-			healAmount = healAmount * (1 + talentData[ImpHealthFunnel].current)
-
+			local spellPower = GetSpellBonusHealing()
+			local healModifier, spModifier = playerHealModifier, 1
+			if spellName == DrainLife then
+				healModifier = healModifier * (1 + talentData[ShadowMastery].current)
+			elseif spellName == HealthFunnel then
+				healModifier = healModifier * (1 + talentData[ImpHealthFunnel].current)
+			end
+			spellPower = spellPower * spellData[spellName].coeff
+			healAmount = calculateGeneralAmount(spellData[spellName].levels[spellRank], healAmount, spellPower, spModifier, healModifier)
 			return CHANNEL_HEALS, ceil(healAmount / spellData[spellName].ticks), spellData[spellName].ticks, spellData[spellName].interval
 		end
 	end
 end
+]]

 -- Healing modifiers
 if( not HealComm.aurasUpdated ) then
@@ -1561,6 +1991,13 @@ HealComm.healingModifiers = HealComm.healingModifiers or {
 	[23230] = 0.50, -- Blood Fury
 	[31977] = 1.50, -- Curse of Infinity
 }
+if isWrath then
+	HealComm.healingModifiers[34123] = 1.06 -- Tree of Life
+	HealComm.healingModifiers[45237] = 1.03 -- Focused Will Rank 1
+	HealComm.healingModifiers[45241] = 1.04 -- Focused Will Rank 2
+	HealComm.healingModifiers[45242] = 1.05 -- Focused Will Rank 3
+end
+

 HealComm.healingStackMods = HealComm.healingStackMods or {
 	-- Mortal Wound
@@ -1578,7 +2015,7 @@ HealComm.healingStackMods = HealComm.healingStackMods or {
 	[45242] = function(stacks) return 1 + stacks * 0.10 end,
 }

-if isTBC then
+if isTBC or isWrath then
 	HealComm.healingStackMods[13218] = function(stacks) return 1 - stacks * 0.10 end -- Wound Poison (Rank 1)
 	HealComm.healingStackMods[13222] = function(stacks) return 1 - stacks * 0.10 end -- Wound Poison (Rank 2)
 	HealComm.healingStackMods[13223] = function(stacks) return 1 - stacks * 0.10 end -- Wound Poison (Rank 3)
@@ -1656,6 +2093,7 @@ function HealComm:UNIT_AURA(unit)

 			if( healingModifiers[spellID] ) then
 				increase = increase * healingModifiers[spellID]
+
 			elseif( healingStackMods[spellID] ) then
 				increase = increase * healingStackMods[spellID](stack)
 			end
@@ -1663,7 +2101,6 @@ function HealComm:UNIT_AURA(unit)

 		id = id + 1
 	end
-
 	-- Scan debuffs
 	id = 1
 	while( true ) do
@@ -1693,7 +2130,7 @@ function HealComm:UNIT_AURA(unit)
 	wipe(alreadyAdded)

 	if( unit == "player" ) then
-		if unitHasAura("player", 10060) then -- Power Infusion
+		if unitHasAura("player", 10060) and not (isWrath or isTBC) then -- Power Infusion
 			playerIncrease = playerIncrease * 1.20
 		end

@@ -1735,6 +2172,28 @@ function HealComm:UNIT_AURA(unit)
 	end
 end

+-- Monitor glyph changes
+function HealComm:GlyphsUpdated(id)
+	local spellID = glyphCache[id]
+
+	-- Invalidate the old cache value
+	if( spellID ) then
+		glyphCache[spellID] = nil
+		glyphCache[id] = nil
+	end
+
+	-- Cache the new one if any
+	local enabled, _, glyphID = GetGlyphSocketInfo(id)
+	if( enabled and glyphID ) then
+		glyphCache[glyphID] = true
+		glyphCache[id] = glyphID
+	end
+end
+
+HealComm.GLYPH_ADDED = HealComm.GlyphsUpdated
+HealComm.GLYPH_REMOVED = HealComm.GlyphsUpdated
+HealComm.GLYPH_UPDATED = HealComm.GlyphsUpdated
+
 function HealComm:PLAYER_LEVEL_UP(level)
 	playerLevel = tonumber(level) or UnitLevel("player")
 end
@@ -1802,7 +2261,7 @@ local function loadHealList(pending, amount, stack, endTime, ticksLeft, ...)
 		for i = 1, select("#", ...), 2 do
 			local guid = select(i, ...)
 			local decompGUID = guid and decompressGUID[guid]
-			amount = tonumber((select(i + 1, ...)))
+			amount = not pending.hasVariableTicks and tonumber((select(i + 1, ...))) or loadHealAmount(string.split("@", amount))
 			if( decompGUID and amount ) then
 				updateRecord(pending, decompGUID, amount, stack, endTime, ticksLeft)
 				tinsert(tempPlayerList, decompGUID)
@@ -1877,8 +2336,8 @@ local function parseChannelHeal(casterGUID, spellID, amount, totalTicks, ...)
 	pending.bitType = CHANNEL_HEALS

 	local ticksLeft = ceil((endTime - GetTime()) / pending.tickInterval)
-	loadHealList(pending, amount, 1, endTime, ticksLeft, ...)

+	loadHealList(pending, amount, 1, endTime, ticksLeft, ...)
 	HealComm.callbacks:Fire("HealComm_HealStarted", casterGUID, spellID, pending.bitType, pending.endTime, unpack(tempPlayerList))
 end

@@ -1910,13 +2369,16 @@ local function parseHotHeal(casterGUID, wasUpdated, spellID, tickAmount, totalTi
 	-- If the user is on 3.3, then anything without a total ticks attached to it is rejected
 	if( not tickAmount or not spellName or select("#", ...) == 0 ) then return end

+	if type(tickAmount) == "table" then
+		tickAmount = table.concat(tickAmount, "@")
+	end
 	-- Retrieve the hot information
 	local inc = 2
 	local stack, duration, endTime = findAura(casterGUID, spellID, ...)

 	if not ( tickAmount == -1 or tickAmount == "-1" ) then
 		inc = 1
-		duration = totalTicks * tickInterval
+		duration = totalTicks * (tickInterval or 1)
 		endTime = GetTime() + duration
 	end

@@ -1963,7 +2425,7 @@ local function parseHotBomb(casterGUID, wasUpdated, spellID, amount, ...)
 	pending.endTime = hotPending.endTime
 	pending.spellID = spellID
 	pending.bitType = BOMB_HEALS
-	pending.stack = 1 -- TBC Lifebloom bomb heal does not stack
+	pending.stack = isWrath and hotPending.stack or 1 -- TBC Lifebloom bomb heal does not stack

 	loadHealList(pending, amount, pending.stack, pending.endTime, nil, ...)

@@ -2075,21 +2537,28 @@ function HealComm:CHAT_MSG_ADDON(prefix, message, channel, sender)
 		parseDirectHeal(casterGUID, spellID, tonumber(arg1), tonumber(extraArg), strsplit(",", arg2))
 		-- New channel heal - C:<extra>:<spellID>:<amount>:<totalTicks>:target1,target2...
 	elseif( commType == "C" and arg1 and arg3 ) then
+		-- Penance heals its first tick instantly and by now has already happened
 		parseChannelHeal(casterGUID, spellID, tonumber(arg1), tonumber(arg2), strsplit(",", arg3))
 		-- New hot with a "bomb" component - B:<totalTicks>:<spellID>:<bombAmount>:target1,target2:<amount>:<isMulti>:<tickInterval>:target1,target2...
 	elseif( commType == "B" and arg1 and arg6 ) then
-		parseHotHeal(casterGUID, false, spellID, tonumber(arg3), tonumber(extraArg), tonumber(arg5), string.split(",", arg6))
-		parseHotBomb(casterGUID, false, spellID, tonumber(arg1), string.split(",", arg2))
+		parseHotHeal(casterGUID, false, spellID, tonumber(arg3), tonumber(extraArg), tonumber(arg5), strsplit(",", arg6))
+		parseHotBomb(casterGUID, false, spellID, tonumber(arg1), strsplit(",", arg2))
 		-- New hot - H:<totalTicks>:<spellID>:<amount>:<isMulti>:<tickInterval>:target1,target2...
 	elseif( commType == "H" and arg1 and arg4 ) then
 		parseHotHeal(casterGUID, false, spellID, tonumber(arg1), tonumber(extraArg), tonumber(arg3), strsplit(",", arg4))
 		-- New updated heal somehow before ending - U:<totalTicks>:<spellID>:<amount>:<tickInterval>:target1,target2...
 	elseif( commType == "U" and arg1 and arg3 ) then
 		parseHotHeal(casterGUID, true, spellID, tonumber(arg1), tonumber(extraArg), tonumber(arg2), strsplit(",", arg3))
+		-- New variable tick hot - VH::<spellID>:<amount>:<isMulti>:<tickInterval>:target1,target2...
+	elseif( commType == "VH" and arg1 and arg4 ) then
+		parseHotHeal(casterGUID, false, spellID, arg1, tonumber(arg3), tonumber(extraArg), string.split(",", arg4))
+		-- New updated variable tick hot - U::<spellID>:amount1@amount2@amount3:<tickTotal>:target1,target2...
+	elseif( commType == "VU" and arg1 and arg3 ) then
+		parseHotHeal(casterGUID, true, spellID, arg1, tonumber(arg2), tonumber(extraArg), string.split(",", arg3))
 		-- New updated bomb hot - UB:<totalTicks>:<spellID>:<bombAmount>:target1,target2:<amount>:<tickInterval>:target1,target2...
 	elseif( commType == "UB" and arg1 and arg5 ) then
-		parseHotHeal(casterGUID, true, spellID, tonumber(arg3), tonumber(extraArg), tonumber(arg4), string.split(",", arg5))
-		parseHotBomb(casterGUID, true, spellID, tonumber(arg1), string.split(",", arg2))
+		parseHotHeal(casterGUID, true, spellID, tonumber(arg3), tonumber(extraArg), tonumber(arg4), strsplit(",", arg5))
+		parseHotBomb(casterGUID, true, spellID, tonumber(arg1), strsplit(",", arg2))
 		-- Heal stopped - S:<extra>:<spellID>:<ended early: 0/1>:target1,target2...
 	elseif( commType == "S" or commType == "HS" ) then
 		local interrupted = arg1 == "1" and true or false
@@ -2136,11 +2605,16 @@ HealComm.bucketFrame:SetScript("OnUpdate", function(self, elapsed)
 						wipe(data)
 						-- We're doing a bucket for a cast thats a multi-target heal like Wild Growth or Prayer of Healing
 					elseif( data.type == "heal" ) then
-						local bitType, amount, totalTicks, tickInterval, _ = CalculateHotHealing(data[1], data.spellID)
+						local bitType, amount, totalTicks, tickInterval, _, hasVariableTicks = CalculateHotHealing(data[1], data.spellID)
 						if( bitType ) then
-							local targets, amt = GetHealTargets(bitType, data[1], max(amount, 0), data.spellID, data)
-							parseHotHeal(playerGUID, false, data.spellID, amt, totalTicks, tickInterval, strsplit(",", targets))
-							sendMessage(format("H:%d:%d:%d::%d:%s", totalTicks, data.spellID, amt, tickInterval, targets))
+							local targets = GetHealTargets(bitType, data[1], data.spellID, data)
+							parseHotHeal(playerGUID, false, data.spellID, amount, totalTicks, tickInterval, strsplit(",", targets))
+
+							if( not hasVariableTicks ) then
+								sendMessage(format("H:%d:%d:%d::%d:%s", totalTicks, data.spellID, amount, tickInterval, targets))
+							else
+								sendMessage(format("VH:%d:%d:%s::%d:%s", tickInterval, data.spellID, table.concat(amount, "@"), totalTicks, targets))
+							end
 						end

 						wipe(data)
@@ -2187,11 +2661,11 @@ function HealComm:COMBAT_LOG_EVENT_UNFILTERED(...)

 			updateRecord(pending, destGUID, amount, stack, endTime, ticksLeft)

-			if( pending.isMultiTarget ) and sourceGUID then
+			if( pending.isMultiTarget and sourceGUID ) then
 				bucketHeals[sourceGUID] = bucketHeals[sourceGUID] or {}
-				bucketHeals[sourceGUID][spellID] = bucketHeals[sourceGUID][spellID] or {}
+				bucketHeals[sourceGUID][spellName] = bucketHeals[sourceGUID][spellName] or {}

-				local spellBucket = bucketHeals[sourceGUID][spellID]
+				local spellBucket = bucketHeals[sourceGUID][spellName]
 				if( not spellBucket[destGUID] ) then
 					spellBucket.timeout = BUCKET_FILLED
 					spellBucket.type = "tick"
@@ -2211,37 +2685,21 @@ function HealComm:COMBAT_LOG_EVENT_UNFILTERED(...)
 	elseif( ( eventType == "SPELL_AURA_APPLIED" or eventType == "SPELL_AURA_REFRESH" or eventType == "SPELL_AURA_APPLIED_DOSE" ) and bit.band(sourceFlags, COMBATLOG_OBJECT_AFFILIATION_MINE) == COMBATLOG_OBJECT_AFFILIATION_MINE ) then
 		if( hotData[spellName] ) then
 			-- Single target so we can just send it off now thankfully
-			local bitType, amount, totalTicks, tickInterval, bombAmount = CalculateHotHealing(destGUID, spellID)
+			local bitType, amount, totalTicks, tickInterval, bombAmount, hasVariableTicks = CalculateHotHealing(destGUID, spellID)
 			if( bitType ) then
-				local targets, amt = GetHealTargets(type, destGUID, max(amount, 0), spellID)
+				local targets = GetHealTargets(type, destGUID, spellID)
 				if targets then
-					parseHotHeal(sourceGUID, false, spellID, amt, totalTicks, tickInterval, strsplit(",", targets))
+					parseHotHeal(sourceGUID, false, spellID, amount, totalTicks, tickInterval, strsplit(",", targets))

 					-- Hot with a bomb!
 					if( bombAmount ) then
-						local bombTargets, bombAmount = GetHealTargets(BOMB_HEALS, destGUID, math.max(bombAmount, 0), spellName)
-						parseHotBomb(sourceGUID, false, spellID, bombAmount, string.split(",", bombTargets))
-						sendMessage(string.format("B:%d:%d:%d:%s:%d::%d:%s", totalTicks, spellID, bombAmount, bombTargets, amount, tickInterval, targets))
-					else
-						sendMessage(string.format("H:%d:%d:%d::%d:%s", totalTicks, spellID, amount, tickInterval, targets))
-					end
-				end
-			end
-		elseif spellData[spellName] and spellData[spellName]._isChanneled then
-			local bitType, amount, totalTicks, tickInterval = CalculateHealing(destGUID, spellID, destUnit)
-			if bitType == CHANNEL_HEALS then
-				local targets, amt = compressGUID[destGUID], max(amount, 0)
-				if targets then
-					local endTime = select(5, ChannelInfo())
-					if endTime then
-						endTime = endTime / 1000
+						local bombTargets = GetHealTargets(BOMB_HEALS, destGUID, spellName)
+						parseHotBomb(sourceGUID, false, spellID, bombAmount, strsplit(",", bombTargets))
+						sendMessage(format("B:%d:%d:%d:%s:%d::%d:%s", totalTicks, spellID, bombAmount, bombTargets, amount, tickInterval, targets))
+					elseif( hasVariableTicks ) then
+						sendMessage(format("VH:%d:%d:%s::%d:%s", tickInterval, spellID, table.concat(amount, "@"), totalTicks, targets))
 					else
-						endTime = GetTime() + totalTicks * tickInterval
-					end
-					local ticksLeft = min(floor((endTime - GetTime() + 0.001) / tickInterval), totalTicks)
-					if ticksLeft > 0 then
-						parseChannelHeal(sourceGUID, spellID, amt, ticksLeft, strsplit(",", targets))
-						sendMessage(format("C::%d:%d:%s:%s", spellID, amt, ticksLeft, targets))
+						sendMessage(format("H:%d:%d:%d::%d:%s", totalTicks, spellID, amount, tickInterval, targets))
 					end
 				end
 			end
@@ -2261,12 +2719,16 @@ function HealComm:COMBAT_LOG_EVENT_UNFILTERED(...)
 					if( bombAmount ) then
 						parseHotBomb(sourceGUID, true, spellID, bombAmount, compressGUID[destGUID])

-						sendMessage(string.format("UB:%s:%d:%d:%s:%d:%d:%s", pending.totalTicks, spellID, bombAmount, compressGUID[destGUID], amount, pending.tickInterval, compressGUID[destGUID]))
+						sendMessage(format("UB:%s:%d:%d:%s:%d:%d:%s", pending.totalTicks, spellID, bombAmount, compressGUID[destGUID], amount, pending.tickInterval, compressGUID[destGUID]))
 						return
 					end
 				end

-				sendMessage(string.format("U:%s:%d:%d:%d:%s", spellID, amount, pending.totalTicks, pending.tickInterval, compressGUID[destGUID]))
+				if( pending.hasVariableTicks ) then
+					sendMessage(format("VU:%d:%d:%s:%d:%s", pending.tickInterval, spellID, amount, pending.totalTicks, compressGUID[destGUID]))
+				else
+					sendMessage(format("U:%s:%d:%d:%d:%s", spellID, amount, pending.totalTicks, pending.tickInterval, compressGUID[destGUID]))
+				end
 			end
 		end
 		-- Aura faded
@@ -2308,6 +2770,13 @@ local function setCastData(priority, name, guid)
 	guidPriorities[lastSentID] = priority
 end

+-- Penance sends different spellIDs on UNIT_SPELLCAST_SENT and UNIT_SPELLCAST_START. Reported on beta / remove this once fixed.
+local penanceIDs = {
+	[47540] = 47757,
+	[53005] = 52986,
+	[53006] = 52987,
+	[53007] = 52988,
+}
 -- When the game tries to figure out the UnitID from the name it will prioritize players over non-players
 -- if there are conflicts in names it will pull the one with the least amount of current health
 function HealComm:UNIT_SPELLCAST_SENT(unit, targetName, castGUID, spellID)
@@ -2318,7 +2787,7 @@ function HealComm:UNIT_SPELLCAST_SENT(unit, targetName, castGUID, spellID)
 		targetName = targetName or UnitName("player")

 		castTarget = gsub(targetName, "(.-)%-(.*)$", "%1")
-		lastSentID = spellID
+		lastSentID = penanceIDs[spellID] or spellID

 		-- Self cast is off which means it's possible to have a spell waiting for a target.
 		-- It's possible that it's the mouseover unit, but if a Target, TargetLast or AssistUnit call comes right after it means it's casting on that instead instead.
@@ -2341,6 +2810,14 @@ function HealComm:UNIT_SPELLCAST_SENT(unit, targetName, castGUID, spellID)
 	end
 end

+local PlayerTargetSpells = {
+	[GetSpellInfo(689)] = true, -- Drain Life
+	[GetSpellInfo(740)] = true, -- Tranquility
+	[GetSpellInfo(331)] = true, -- Healing Wave
+}
+if isTBC or isWrath then
+	PlayerTargetSpells[GetSpellInfo(32546)] = true -- Binding Heal
+end
 function HealComm:UNIT_SPELLCAST_START(unit, cast, spellID)
 	if( unit ~= "player") then return end

@@ -2350,9 +2827,11 @@ function HealComm:UNIT_SPELLCAST_START(unit, cast, spellID)

 	local castGUID = castGUIDs[spellID]
 	local castUnit = guidToUnit[castGUID]
-	if isTBC and not castUnit and spellID == 32546 and castGUID == UnitGUID("target") then -- Binding Heal
+	if (isTBC or isWrath) and not castUnit and PlayerTargetSpells[spellName] then
 		castGUID = UnitGUID("player")
 		castUnit = "player"
+	elseif glyphCache[55440] and not castUnit and PlayerTargetSpells[spellName] then -- Glyph of Healing Wave
+		castUnit = unit
 	end
 	if( not castGUID or not castUnit ) then
 		return
@@ -2362,15 +2841,22 @@ function HealComm:UNIT_SPELLCAST_START(unit, cast, spellID)
 	local bitType, amount, ticks, tickInterval = CalculateHealing(castGUID, spellID, castUnit)
 	if not amount then return end

-	local targets, amt = GetHealTargets(bitType, castGUID, max(amount, 0), spellID)
+	local targets, fakeAmount = GetHealTargets(bitType, castGUID, spellID, amount)
+	amount = fakeAmount or amount
 	if not targets then return end -- only here until I compress/decompress npcs

 	if( bitType == DIRECT_HEALS ) then
 		local startTime, endTime = select(4, CastingInfo())
-		parseDirectHeal(playerGUID, spellID, amt, (endTime - startTime) / 1000, strsplit(",", targets))
-		sendMessage(format("D:%.3f:%d:%d:%s", (endTime - startTime) / 1000, spellID or 0, amt or "", targets))
+		parseDirectHeal(playerGUID, spellID, amount, (endTime - startTime) / 1000, strsplit(",", targets))
+		sendMessage(format("D:%.3f:%d:%d:%s", (endTime - startTime) / 1000, spellID or 0, amount or "", targets))
 	elseif( bitType == CHANNEL_HEALS ) then
-		spellData[spellName]._isChanneled = true
+		parseChannelHeal(playerGUID, spellID, amount, ticks, string.split(",", targets))
+		if spellName == GetSpellInfo(740) or spellName == GetSpellInfo(746) then
+			sendMessage(string.format("C::%d:%d:%s:%s", spellID, amount, ticks, targets))
+		else
+			-- Penance has its first tick already done by the time this arrives
+			sendMessage(string.format("C::%d:%d:%s:%s", spellID, amount, ticks - 1, targets))
+		end
 	end
 end

@@ -2644,11 +3130,11 @@ function HealComm:UNIT_PET(unit)

 	-- We have an active pet guid from this user and it's different, kill it
 	local activeGUID = activePets[unit]
-	if activeGUID and activeGUID ~= petGUID then
+	if activeGUID and petGUID and activeGUID ~= petGUID then
 		removeAllRecords(activeGUID)

 		rawset(self.compressGUID, activeGUID, nil)
-		rawset(self.decompressGUID, "p-"..strsub(UnitGUID(unit),8), nil)
+		rawset(self.decompressGUID, "p-"..strsub(guid,8), nil)
 		guidToUnit[activeGUID] = nil
 		guidToGroup[activeGUID] = nil
 		activePets[unit] = nil
@@ -2732,22 +3218,23 @@ function HealComm:OnInitialize()
 		local FirstAid = GetSpellInfo(746)

 		spellData[FirstAid] = {
-			ticks = {6, 6, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8},
+			_isChanneled = true,
+			ticks = {6, 6, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8},
 			interval = 1,
-			averages = {66, 114, 161, 301, 400, 640, 800, 1104, 1360, 2000, 2800, 3400}
+			averages = {66, 114, 161, 301, 400, 640, 800, 1104, 1360, 2000, 2800, 3400, 4800, 5800}
 		}

 		local _GetHealTargets = GetHealTargets

-		GetHealTargets = function(bitType, guid, healAmount, spellID, data)
+		GetHealTargets = function(bitType, guid, spellID)
 			local spellName = GetSpellInfo(spellID)

 			if spellName == FirstAid then
-				return compressGUID[guid], healAmount
+				return compressGUID[guid]
 			end

 			if _GetHealTargets then
-				return _GetHealTargets(bitType, guid, healAmount, spellID, data)
+				return _GetHealTargets(bitType, guid, spellID)
 			end
 		end

@@ -2771,6 +3258,15 @@ function HealComm:OnInitialize()
 		end
 	end

+	-- Cache glyphs initially
+    for id=1, GetNumGlyphSockets() do
+		local enabled, _, glyphID = GetGlyphSocketInfo(id)
+		if( enabled and glyphID ) then
+			glyphCache[glyphID] = true
+			glyphCache[id] = glyphID
+		end
+	end
+
 	self:PLAYER_EQUIPMENT_CHANGED()

 	-- When first logging in talent data isn't available until at least PLAYER_ALIVE, so if we don't have data
@@ -2801,6 +3297,11 @@ function HealComm:OnInitialize()
 	self.eventFrame:RegisterEvent("PLAYER_LEVEL_UP")
 	self.eventFrame:RegisterEvent("CHARACTER_POINTS_CHANGED")
 	self.eventFrame:RegisterEvent("UNIT_AURA")
+	if isWrath then
+		self.eventFrame:RegisterEvent("GLYPH_ADDED")
+		self.eventFrame:RegisterEvent("GLYPH_REMOVED")
+		self.eventFrame:RegisterEvent("GLYPH_UPDATED")
+	end

 	if( self.initialized ) then return end
 	self.initialized = true
diff --git a/oUF_Simple/core/functions.lua b/oUF_Simple/core/functions.lua
index c6ffb56..adc2c14 100644
--- a/oUF_Simple/core/functions.lua
+++ b/oUF_Simple/core/functions.lua
@@ -755,4 +755,14 @@ local function CreateRunesBar(self)
 	s.colorSpec = true
   return s
 end
-L.F.CreateRunesBar = CreateRunesBar
\ No newline at end of file
+L.F.CreateRunesBar = CreateRunesBar
+
+local function CreateResurrectIndicator(self)
+  if not self.cfg.resurrect or not self.cfg.resurrect.enabled then return end
+  if self.settings.template ~= "raid" then return end
+  local s = self.Health:CreateTexture(nil, "OVERLAY")
+  s:SetSize(unpack(self.cfg.resurrect.size))
+  SetPoint(s, self.Health, self.cfg.resurrect.point)
+  return s
+end
+L.F.CreateResurrectIndicator = CreateResurrectIndicator
\ No newline at end of file
diff --git a/oUF_Simple/core/style.lua b/oUF_Simple/core/style.lua
index 4231dc8..7675e08 100644
--- a/oUF_Simple/core/style.lua
+++ b/oUF_Simple/core/style.lua
@@ -40,7 +40,7 @@ local function CreateStyle(self)
   self.Runes = L.F.CreateRunesBar(self)
   -- self.AlternativePower = L.F.CreateAltPowerBar(self)
   -- self.AdditionalPower = L.F.CreateAdditionalPowerBar(self)
-  self.Swing = L.F.CreateSwing(self)
+  -- self.Swing = L.F.CreateSwing(self)
   self.Debuffs = L.F.CreateDebuffs(self)
   self.Buffs = L.F.CreateBuffs(self)
   self.LeaderIndicator = L.F.CreateGroupRoleIndicator(self)
@@ -51,6 +51,7 @@ local function CreateStyle(self)
   self.RaidRoleIndicator = L.F.CreateRaidRoleIndicator(self)
   self.Range = L.F.CreateRange(self)
   self.Trinket = L.F.CreateTrinket(self)
-  self.EnergyManaRegen = L.F.CreateEneryTicker(self)
+  self.ResurrectIndicator = L.F.CreateResurrectIndicator(self)
+  -- self.EnergyManaRegen = L.F.CreateEneryTicker(self)
 end
 L.F.CreateStyle = CreateStyle
\ No newline at end of file
diff --git a/oUF_Simple/oUF_Simple.toc b/oUF_Simple/oUF_Simple.toc
index e363171..035e7ae 100644
--- a/oUF_Simple/oUF_Simple.toc
+++ b/oUF_Simple/oUF_Simple.toc
@@ -7,10 +7,10 @@
 ## modules\rAbsorbBar.lua
 modules\rClassBar.lua
 modules\oUF_DebuffHighlight.lua
-modules\oUF_Swing.lua
+# modules\oUF_Swing.lua
 modules\oUF_RaidDebuffs.lua
 modules\oUF_Trinkets.lua
-modules\oUF_EnergyManaRegen.lua
+# modules\oUF_EnergyManaRegen.lua

 core\init.lua
 core\functions.lua
diff --git a/oUF_SimpleConfig/player.lua b/oUF_SimpleConfig/player.lua
index ffe0f47..d1bf905 100644
--- a/oUF_SimpleConfig/player.lua
+++ b/oUF_SimpleConfig/player.lua
@@ -122,8 +122,8 @@ L.C.player = {
   },
   runebar = {
     enabled = true,
-    size = {265,5},
-    point = {"BOTTOM","TOP",0,4}, --if no relativeTo is given the frame base will be the relativeTo reference
+    size = {180,5},
+    point = {"BOTTOMRIGHT","TOPRIGHT",0,4}, --if no relativeTo is given the frame base will be the relativeTo reference
   },
   --altpowerbar
   altpowerbar = {
diff --git a/oUF_SimpleConfig/raid.lua b/oUF_SimpleConfig/raid.lua
index 66672a6..13c3d8f 100644
--- a/oUF_SimpleConfig/raid.lua
+++ b/oUF_SimpleConfig/raid.lua
@@ -84,6 +84,12 @@ L.C.raid = {
     enabled = true,
     alpha = 0.3,  -- outside alpha
   },
+  --resurrect indicator
+  resurrect = {
+    enabled = true,
+    size = {24,24},
+    point = {"CENTER","CENTER",0,0}
+  },
   setup = {
     template = nil,
     visibility = "custom [group:raid] show; hide",
diff --git a/rBag/libs/SortBags.lua b/rBag/libs/SortBags.lua
index 7a86187..bdfb11b 100644
--- a/rBag/libs/SortBags.lua
+++ b/rBag/libs/SortBags.lua
@@ -86,23 +86,23 @@ local CLASSES = {
 	},
 	-- ench
 	{
-		containers = {22246, 22248, 22249, 22249, 21858},
-		items = arrayToSet({6218, 6222, 6339, 6342, 6343, 6344, 6345, 6346, 6347, 6348, 6349, 6375, 6376, 6377, 10938, 10939, 10940, 10978, 10998, 11038, 11039, 11081, 11082, 11083, 11084, 11098, 11101, 11130, 11134, 11135, 11137, 11138, 11139, 11145, 11150, 11151, 11152, 11163, 11164, 11165, 11166, 11167, 11168, 11174, 11175, 11176, 11177, 11178, 11202, 11203, 11204, 11205, 11206, 11207, 11208, 11223, 11224, 11225, 11226, 11813, 14343, 14344, 16202, 16203, 16204, 16207, 16214, 16215, 16216, 16217, 16218, 16219, 16220, 16221, 16222, 16223, 16224, 16242, 16243, 16244, 16245, 16246, 16247, 16248, 16249, 16250, 16251, 16252, 16253, 16254, 16255, 17725, 18259, 18260, 19444, 19445, 19446, 19447, 19448, 19449, 20725, 20726, 20727, 20728, 20729, 20730, 20731, 20732, 20733, 20734, 20735, 20736, 20752, 20753, 20754, 20755, 20756, 20757, 20758, 22392, 22445, 22446, 22447, 22448, 22449, 22450, 22461, 22462, 22463, 22530, 22531, 22532, 22533, 22534, 22535, 22536, 22537, 22538, 22539, 22540, 22541, 22542, 22543, 22544, 22545, 22546, 22547, 22548, 22551, 22552, 22553, 22554, 22555, 22556, 22557, 22558, 22559, 22560, 22561, 22562, 22563, 22564, 22565, 24000, 24003, 25848, 25849, 28270, 28271, 28272, 28273, 28274, 28276, 28277, 28279, 28280, 28281, 28282, 33148, 33149, 33150, 33151, 33152, 33153, 33165, 33307, 34872, 35297, 35298, 35299, 35498, 35500, 35756, 186683, 7081, 12810, 7068, 7972, 12808, 7067, 7075, 7076, 7077, 7078, 7080, 7082, 12803}),
+		containers = {22246, 22248, 22249, 30748, 21858},
+		items = arrayToSet({6218, 6222, 6339, 6342, 6343, 6344, 6345, 6346, 6347, 6348, 6349, 6375, 6376, 6377, 10938, 10939, 10940, 10978, 10998, 11038, 11039, 11081, 11082, 11083, 11084, 11098, 11101, 11130, 11134, 11135, 11137, 11138, 11139, 11145, 11150, 11151, 11152, 11163, 11164, 11165, 11166, 11167, 11168, 11174, 11175, 11176, 11177, 11178, 11202, 11203, 11204, 11205, 11206, 11207, 11208, 11223, 11224, 11225, 11226, 11813, 14343, 14344, 16202, 16203, 16204, 16207, 16214, 16215, 16216, 16217, 16218, 16219, 16220, 16221, 16222, 16223, 16224, 16242, 16243, 16244, 16245, 16246, 16247, 16248, 16249, 16250, 16251, 16252, 16253, 16254, 16255, 17725, 18259, 18260, 19444, 19445, 19446, 19447, 19448, 19449, 20725, 20726, 20727, 20728, 20729, 20730, 20731, 20732, 20733, 20734, 20735, 20736, 20752, 20753, 20754, 20755, 20756, 20757, 20758, 22392, 22445, 22446, 22447, 22448, 22449, 22450, 22461, 22462, 22463, 22530, 22531, 22532, 22533, 22534, 22535, 22536, 22537, 22538, 22539, 22540, 22541, 22542, 22543, 22544, 22545, 22546, 22547, 22548, 22551, 22552, 22553, 22554, 22555, 22556, 22557, 22558, 22559, 22560, 22561, 22562, 22563, 22564, 22565, 24000, 24003, 25848, 25849, 28270, 28271, 28272, 28273, 28274, 28276, 28277, 28279, 28280, 28281, 28282, 33148, 33149, 33150, 33151, 33152, 33153, 33165, 33307, 34872, 35297, 35298, 35299, 35498, 35500, 35756, 186683, 7081, 12810, 7068, 7972, 12808, 7067, 7075, 7076, 7077, 7078, 7080, 7082, 12803, 21885, 22451, 22456, 22457, 22572, 22576, 22577, 22578, 23571, 23572, 21886, 22575, 21884, 22452, 22573, 22574}),
 	},
 	-- herb
 	{
 		containers = {22250, 22251, 22252, 38225},
-		items = arrayToSet({765, 785, 1401, 2263, 2447, 2449, 2450, 2452, 2453, 3355, 3356, 3357, 3358, 3369, 3818, 3819, 3820, 3821, 4625, 5013, 5056, 5168, 8831, 8836, 8838, 8839, 8845, 8846, 11018, 11020, 11022, 11024, 11040, 11514, 11951, 11952, 13463, 13464, 13465, 13466, 13467, 13468, 16205, 16208, 17034, 17035, 17036, 17037, 17038, 17760, 18297, 19727, 22094, 22147, 22710, 22785, 22786, 22787, 22788, 22789, 22790, 22791, 22792, 22793, 22794, 22795, 22797, 23329, 23501, 23788, 24245, 24246, 24401, 31300, 32468, 34465, 8153, 10286, 19726}),
+		items = arrayToSet({765, 785, 1401, 2263, 2447, 2449, 2450, 2452, 2453, 3355, 3356, 3357, 3358, 3369, 3818, 3819, 3820, 3821, 4625, 5013, 5056, 5168, 8831, 8836, 8838, 8839, 8845, 8846, 11018, 11020, 11022, 11024, 11040, 11514, 11951, 11952, 13463, 13464, 13465, 13466, 13467, 13468, 16205, 16208, 17034, 17035, 17036, 17037, 17038, 17760, 18297, 19727, 22094, 22147, 22710, 22785, 22786, 22787, 22788, 22789, 22790, 22791, 22792, 22793, 22794, 22795, 22797, 23329, 23501, 23788, 24245, 24246, 24401, 31300, 32468, 34465, 8153, 10286, 19726, 21886, 22575}),
 	},
 	-- mining
 	{
 		containers = {29540, 30746},
-		items = arrayToSet({756, 778, 1819, 1893, 1959, 2770, 2771, 2772, 2775, 2776, 2835, 2836, 2838, 2840, 2841, 2842, 2901, 3575, 3576, 3577, 3858, 3859, 3860, 3861, 6037, 7911, 7912, 10620, 11370, 11371, 12359, 12360, 12365, 12655, 17771, 18562, 20723, 22202, 22203, 23424, 23425, 23426, 23427, 23445, 23446, 23447, 23448, 23449, 23573, 32464, 35128, 5956, 24186, 24188, 24190, 24234, 24235, 24242, 24243}),
+		items = arrayToSet({756, 778, 1819, 1893, 1959, 2770, 2771, 2772, 2775, 2776, 2835, 2836, 2838, 2840, 2841, 2842, 2901, 3575, 3576, 3577, 3858, 3859, 3860, 3861, 6037, 7911, 7912, 10620, 11370, 11371, 12359, 12360, 12365, 12655, 17771, 18562, 20723, 22202, 22203, 23424, 23425, 23426, 23427, 23445, 23446, 23447, 23448, 23449, 23573, 32464, 35128, 5956, 21884, 22452, 22573, 22574, 24186, 24188, 24190, 24234, 24235, 24242, 24243}),
 	},
 	-- leather
 	{
 		containers = {34482, 34490},
-		items = arrayToSet({783, 2304, 2313, 2318, 2319, 2320, 2321, 2324, 2325, 2406, 2407, 2408, 2409, 2604, 2605, 2934, 3182, 3824, 4096, 4231, 4232, 4233, 4234, 4235, 4236, 4265, 4289, 4291, 4293, 4294, 4295, 4296, 4297, 4298, 4299, 4300, 4301, 4304, 4337, 4340, 4341, 4342, 4461, 5082, 5083, 5116, 5373, 5637, 5784, 5785, 5786, 5787, 5788, 5789, 5972, 5973, 5974, 6260, 6261, 6470, 6471, 6474, 6475, 6476, 6710, 7005, 7070, 7071, 7286, 7287, 7288, 7289, 7290, 7360, 7361, 7362, 7363, 7364, 7392, 7428, 7449, 7450, 7451, 7452, 7453, 7613, 8146, 8150, 8151, 8154, 8165, 8167, 8168, 8169, 8170, 8171, 8172, 8173, 8343, 8368, 8384, 8385, 8386, 8387, 8388, 8389, 8390, 8395, 8397, 8398, 8399, 8400, 8401, 8402, 8403, 8404, 8405, 8406, 8407, 8408, 8409, 10290, 11512, 12607, 12709, 12731, 12753, 13287, 13288, 14341, 14635, 15407, 15408, 15409, 15410, 15412, 15414, 15415, 15416, 15417, 15419, 15420, 15422, 15423, 15564, 15725, 15726, 15727, 15728, 15729, 15730, 15731, 15732, 15733, 15734, 15735, 15737, 15738, 15739, 15740, 15741, 15742, 15743, 15744, 15745, 15746, 15747, 15748, 15749, 15751, 15752, 15753, 15754, 15755, 15756, 15757, 15758, 15759, 15760, 15761, 15762, 15763, 15764, 15765, 15768, 15769, 15770, 15771, 15772, 15773, 15774, 15775, 15776, 15777, 15779, 15781, 17012, 17022, 17023, 17025, 17056, 17722, 17967, 17968, 18239, 18240, 18251, 18252, 18512, 18514, 18515, 18516, 18517, 18518, 18519, 18662, 18731, 18949, 19326, 19327, 19328, 19329, 19330, 19331, 19332, 19333, 19767, 19768, 19769, 19770, 19771, 19772, 19773, 19901, 20253, 20254, 20381, 20382, 20498, 20499, 20500, 20501, 20506, 20507, 20508, 20509, 20510, 20511, 20576, 21548, 21887, 22692, 22694, 22695, 22696, 22697, 22698, 22769, 22770, 22771, 23793, 25649, 25650, 25651, 25652, 25699, 25700, 25707, 25708, 25720, 25721, 25722, 25725, 25726, 25728, 25729, 25730, 25731, 25732, 25733, 25734, 25735, 25736, 25737, 25738, 25739, 25740, 25741, 25742, 25743, 29213, 29214, 29215, 29217, 29218, 29219, 29483, 29485, 29486, 29487, 29488, 29528, 29529, 29530, 29531, 29532, 29533, 29534, 29535, 29536, 29539, 29547, 29548, 29664, 29669, 29672, 29673, 29674, 29675, 29677, 29682, 29684, 29689, 29691, 29693, 29698, 29700, 29701, 29702, 29703, 29704, 29713, 29714, 29717, 29718, 29719, 29720, 29721, 29722, 29723, 29724, 29725, 29726, 29727, 29728, 29729, 29730, 29731, 29732, 29733, 29734, 30183, 30301, 30302, 30303, 30304, 30305, 30306, 30307, 30308, 30444, 31361, 31362, 32428, 32429, 32430, 32431, 32432, 32433, 32434, 32435, 32436, 32470, 32744, 32745, 32746, 32747, 32748, 32749, 32750, 32751, 33124, 33205, 34172, 34173, 34174, 34175, 34200, 34201, 34207, 34218, 34262, 34330, 34491, 34664, 35212, 35213, 35214, 35215, 35216, 35217, 35218, 35219, 35300, 35301, 35302, 35303, 35517, 35519, 35520, 35521, 35523, 35524, 35527, 35528, 35539, 35540, 35541, 35542, 35545, 35546, 35549, 35550, 185848, 185849, 185850, 185851, 185852, 185922, 185923, 185924, 185925, 185926, 187048, 187049, 8153, 7081, 12810, 15846, 19726, 7067, 7075, 7076, 7077, 7078, 7080, 7082, 12803}),
+		items = arrayToSet({783, 2304, 2313, 2318, 2319, 2320, 2321, 2324, 2325, 2406, 2407, 2408, 2409, 2604, 2605, 2934, 3182, 3824, 4096, 4231, 4232, 4233, 4234, 4235, 4236, 4265, 4289, 4291, 4293, 4294, 4295, 4296, 4297, 4298, 4299, 4300, 4301, 4304, 4337, 4340, 4341, 4342, 4461, 5082, 5083, 5116, 5373, 5637, 5784, 5785, 5786, 5787, 5788, 5789, 5972, 5973, 5974, 6260, 6261, 6470, 6471, 6474, 6475, 6476, 6710, 7005, 7070, 7071, 7286, 7287, 7288, 7289, 7290, 7360, 7361, 7362, 7363, 7364, 7392, 7428, 7449, 7450, 7451, 7452, 7453, 7613, 8146, 8150, 8151, 8154, 8165, 8167, 8168, 8169, 8170, 8171, 8172, 8173, 8343, 8368, 8384, 8385, 8386, 8387, 8388, 8389, 8390, 8395, 8397, 8398, 8399, 8400, 8401, 8402, 8403, 8404, 8405, 8406, 8407, 8408, 8409, 10290, 11512, 12607, 12709, 12731, 12753, 13287, 13288, 14341, 14635, 15407, 15408, 15409, 15410, 15412, 15414, 15415, 15416, 15417, 15419, 15420, 15422, 15423, 15564, 15725, 15726, 15727, 15728, 15729, 15730, 15731, 15732, 15733, 15734, 15735, 15737, 15738, 15739, 15740, 15741, 15742, 15743, 15744, 15745, 15746, 15747, 15748, 15749, 15751, 15752, 15753, 15754, 15755, 15756, 15757, 15758, 15759, 15760, 15761, 15762, 15763, 15764, 15765, 15768, 15769, 15770, 15771, 15772, 15773, 15774, 15775, 15776, 15777, 15779, 15781, 17012, 17022, 17023, 17025, 17056, 17722, 17967, 17968, 18239, 18240, 18251, 18252, 18512, 18514, 18515, 18516, 18517, 18518, 18519, 18662, 18731, 18949, 19326, 19327, 19328, 19329, 19330, 19331, 19332, 19333, 19767, 19768, 19769, 19770, 19771, 19772, 19773, 19901, 20253, 20254, 20381, 20382, 20498, 20499, 20500, 20501, 20506, 20507, 20508, 20509, 20510, 20511, 20576, 21548, 21887, 22692, 22694, 22695, 22696, 22697, 22698, 22769, 22770, 22771, 23793, 25649, 25650, 25651, 25652, 25699, 25700, 25707, 25708, 25720, 25721, 25722, 25725, 25726, 25728, 25729, 25730, 25731, 25732, 25733, 25734, 25735, 25736, 25737, 25738, 25739, 25740, 25741, 25742, 25743, 29213, 29214, 29215, 29217, 29218, 29219, 29483, 29485, 29486, 29487, 29488, 29528, 29529, 29530, 29531, 29532, 29533, 29534, 29535, 29536, 29539, 29547, 29548, 29664, 29669, 29672, 29673, 29674, 29675, 29677, 29682, 29684, 29689, 29691, 29693, 29698, 29700, 29701, 29702, 29703, 29704, 29713, 29714, 29717, 29718, 29719, 29720, 29721, 29722, 29723, 29724, 29725, 29726, 29727, 29728, 29729, 29730, 29731, 29732, 29733, 29734, 30183, 30301, 30302, 30303, 30304, 30305, 30306, 30307, 30308, 30444, 31361, 31362, 32428, 32429, 32430, 32431, 32432, 32433, 32434, 32435, 32436, 32470, 32744, 32745, 32746, 32747, 32748, 32749, 32750, 32751, 33124, 33205, 34172, 34173, 34174, 34175, 34200, 34201, 34207, 34218, 34262, 34330, 34491, 34664, 35212, 35213, 35214, 35215, 35216, 35217, 35218, 35219, 35300, 35301, 35302, 35303, 35517, 35519, 35520, 35521, 35523, 35524, 35527, 35528, 35539, 35540, 35541, 35542, 35545, 35546, 35549, 35550, 185848, 185849, 185850, 185851, 185852, 185922, 185923, 185924, 185925, 185926, 187048, 187049, 8153, 7081, 12810, 15846, 19726, 7067, 7075, 7076, 7077, 7078, 7080, 7082, 12803, 21885, 22451, 22456, 22457, 22572, 22576, 22577, 22578, 23571, 23572, 21886, 22575, 21884, 22452, 22573, 22574}),
 	},
 	-- gems
 	{
@@ -112,7 +112,7 @@ local CLASSES = {
 	-- engineering
 	{
 		containers = {23774, 23775, 30745},
-		items = arrayToSet({814, 4357, 4358, 4359, 4360, 4361, 4363, 4364, 4365, 4366, 4367, 4368, 4370, 4371, 4373, 4374, 4375, 4376, 4377, 4378, 4380, 4381, 4382, 4384, 4385, 4386, 4387, 4388, 4389, 4390, 4391, 4392, 4393, 4394, 4395, 4396, 4397, 4398, 4399, 4400, 4403, 4404, 4405, 4406, 4407, 4408, 4409, 4410, 4411, 4412, 4413, 4414, 4415, 4416, 4417, 4852, 5507, 6219, 6672, 6712, 6714, 6715, 6716, 7069, 7148, 7189, 7190, 7191, 7192, 7506, 7560, 7561, 7742, 9060, 9061, 9312, 9313, 9318, 10498, 10499, 10500, 10501, 10502, 10503, 10504, 10505, 10506, 10507, 10514, 10518, 10542, 10543, 10545, 10546, 10548, 10558, 10559, 10560, 10561, 10562, 10576, 10577, 10580, 10585, 10586, 10587, 10588, 10601, 10602, 10603, 10604, 10605, 10606, 10607, 10608, 10609, 10645, 10646, 10647, 10648, 10716, 10720, 10721, 10723, 10724, 10725, 10726, 10727, 10790, 10791, 11590, 11827, 11828, 13308, 13309, 13310, 13311, 14639, 15992, 15993, 15994, 15999, 16000, 16005, 16006, 16008, 16009, 16022, 16023, 16040, 16041, 16042, 16043, 16044, 16045, 16046, 16047, 16048, 16049, 16050, 16051, 16052, 16053, 16054, 16055, 16056, 17716, 17720, 18232, 18235, 18283, 18290, 18291, 18292, 18587, 18588, 18594, 18631, 18634, 18636, 18637, 18638, 18639, 18641, 18645, 18647, 18648, 18649, 18650, 18651, 18652, 18653, 18654, 18655, 18656, 18657, 18658, 18660, 18661, 18984, 18986, 19026, 19027, 19998, 19999, 20000, 20001, 20475, 20816, 20834, 21557, 21558, 21559, 21571, 21574, 21576, 21589, 21590, 21592, 21714, 21716, 21718, 21724, 21725, 21726, 21727, 21728, 21729, 21730, 21731, 21732, 21733, 21734, 21735, 21737, 21738, 22728, 22729, 23736, 23737, 23758, 23761, 23762, 23763, 23764, 23765, 23766, 23768, 23769, 23770, 23771, 23781, 23782, 23783, 23784, 23785, 23786, 23787, 23799, 23800, 23802, 23803, 23804, 23805, 23806, 23807, 23808, 23809, 23810, 23811, 23812, 23813, 23814, 23815, 23816, 23817, 23819, 23820, 23821, 23822, 23823, 23824, 23825, 23826, 23827, 23828, 23829, 23831, 23832, 23835, 23836, 23838, 23839, 23840, 23841, 23874, 23882, 23883, 23884, 23887, 23888, 25886, 25887, 30542, 30544, 31666, 32381, 32413, 32423, 32461, 32472, 32473, 32474, 32475, 32476, 32478, 32479, 32480, 32494, 32495, 33092, 33093, 33804, 34060, 34061, 34113, 34114, 34353, 34354, 34355, 34356, 34357, 34467, 34503, 34504, 34626, 34627, 34847, 35181, 35182, 35183, 35184, 35185, 35186, 35187, 35189, 35190, 35191, 35192, 35193, 35194, 35195, 35196, 35197, 35310, 35311, 35485, 35581, 35582, 37567, 15846, 10286, 19726, 7068, 7972, 12808, 7067, 7075, 7076, 7077, 7078, 7080, 7082, 12803, 5956, 22574, 4401, 11825, 11826, 15996, 21277, 23767, 37710}),
+		items = arrayToSet({814, 4357, 4358, 4359, 4360, 4361, 4363, 4364, 4365, 4366, 4367, 4368, 4370, 4371, 4373, 4374, 4375, 4376, 4377, 4378, 4380, 4381, 4382, 4384, 4385, 4386, 4387, 4388, 4389, 4390, 4391, 4392, 4393, 4394, 4395, 4396, 4397, 4398, 4399, 4400, 4403, 4404, 4405, 4406, 4407, 4408, 4409, 4410, 4411, 4412, 4413, 4414, 4415, 4416, 4417, 4852, 5507, 6219, 6672, 6712, 6714, 6715, 6716, 7069, 7148, 7189, 7190, 7191, 7192, 7506, 7560, 7561, 7742, 9060, 9061, 9312, 9313, 9318, 10498, 10499, 10500, 10501, 10502, 10503, 10504, 10505, 10506, 10507, 10514, 10518, 10542, 10543, 10545, 10546, 10548, 10558, 10559, 10560, 10561, 10562, 10576, 10577, 10580, 10585, 10586, 10587, 10588, 10601, 10602, 10603, 10604, 10605, 10606, 10607, 10608, 10609, 10645, 10646, 10647, 10648, 10716, 10720, 10721, 10723, 10724, 10725, 10726, 10727, 10790, 10791, 11590, 11827, 11828, 13308, 13309, 13310, 13311, 14639, 15992, 15993, 15994, 15999, 16000, 16005, 16006, 16008, 16009, 16022, 16023, 16040, 16041, 16042, 16043, 16044, 16045, 16046, 16047, 16048, 16049, 16050, 16051, 16052, 16053, 16054, 16055, 16056, 17716, 17720, 18232, 18235, 18283, 18290, 18291, 18292, 18587, 18588, 18594, 18631, 18634, 18636, 18637, 18638, 18639, 18641, 18645, 18647, 18648, 18649, 18650, 18651, 18652, 18653, 18654, 18655, 18656, 18657, 18658, 18660, 18661, 18984, 18986, 19026, 19027, 19998, 19999, 20000, 20001, 20475, 20816, 20834, 21557, 21558, 21559, 21571, 21574, 21576, 21589, 21590, 21592, 21714, 21716, 21718, 21724, 21725, 21726, 21727, 21728, 21729, 21730, 21731, 21732, 21733, 21734, 21735, 21737, 21738, 22728, 22729, 23736, 23737, 23758, 23761, 23762, 23763, 23764, 23765, 23766, 23768, 23769, 23770, 23771, 23781, 23782, 23783, 23784, 23785, 23786, 23787, 23799, 23800, 23802, 23803, 23804, 23805, 23806, 23807, 23808, 23809, 23810, 23811, 23812, 23813, 23814, 23815, 23816, 23817, 23819, 23820, 23821, 23822, 23823, 23824, 23825, 23826, 23827, 23828, 23829, 23831, 23832, 23835, 23836, 23838, 23839, 23840, 23841, 23874, 23882, 23883, 23884, 23887, 23888, 25886, 25887, 30542, 30544, 31666, 32381, 32413, 32423, 32461, 32472, 32473, 32474, 32475, 32476, 32478, 32479, 32480, 32494, 32495, 33092, 33093, 33804, 34060, 34061, 34113, 34114, 34353, 34354, 34355, 34356, 34357, 34467, 34503, 34504, 34626, 34627, 34847, 35181, 35182, 35183, 35184, 35185, 35186, 35187, 35189, 35190, 35191, 35192, 35193, 35194, 35195, 35196, 35197, 35310, 35311, 35485, 35581, 35582, 37567, 15846, 10286, 19726, 7068, 7972, 12808, 7067, 7075, 7076, 7077, 7078, 7080, 7082, 12803, 21885, 22451, 22456, 22457, 22572, 22576, 22577, 22578, 23571, 23572, 21886, 22575, 5956, 21884, 22452, 22573, 22574, 4401, 11825, 11826, 15996, 21277, 23767, 37710}),
 	},
 }

diff --git a/rButtonAura/LICENSE.md b/rButtonAura/LICENSE.md
deleted file mode 100644
index 3d88403..0000000
--- a/rButtonAura/LICENSE.md
+++ /dev/null
@@ -1,21 +0,0 @@
-MIT License
-
-Copyright (c) 2011-2018 Erik Raetz
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
\ No newline at end of file
diff --git a/rButtonAura/core.lua b/rButtonAura/core.lua
deleted file mode 100644
index 0476bb8..0000000
--- a/rButtonAura/core.lua
+++ /dev/null
@@ -1,159 +0,0 @@
-
--- rButtonAura: core
--- zork, 2018
-
------------------------------
--- Variables
------------------------------
-
-local A, L = ...
-
-local tick = 0.1
-
-local GetTime, UnitAura = GetTime, UnitAura
-local numAuras = 0
-local auras = {}
-local spec = nil
-local form = 0
-
------------------------------
--- rButtonAura Global
------------------------------
-
-rButtonAura = {}
-rButtonAura.addonName = A
-
------------------------------
--- Functions
------------------------------
-
---AddAura
-function rButtonAura:AddAura(aura)
-  table.insert(auras,aura)
-end
-
---SetTick
-function rButtonAura:SetTick(t)
-  tick = t
-end
-
-local function ShowAura(aura)
-  if aura.bar then
-    aura.bar:Show()
-  end
-  if aura.border then
-    aura.border:Show()
-  end
-end
-
-local function HideAura(aura)
-  if aura.bar then
-    aura.bar:Hide()
-  end
-  if aura.border then
-    aura.border:Hide()
-  end
-end
-
---UpdateAura
-local function UpdateAura(aura)
-  local name, icon, count, debuffType, duration, expires, caster = AuraUtil.FindAuraByName(aura.spellName, aura.unit, aura.filter)
-  if name and caster == aura.caster then
-    if aura.bar then
-      local perc = (duration+GetTime()-expires)/duration
-      local w = aura.bar.maxwidth-perc*aura.bar.maxwidth
-      aura.bar:SetWidth(w)
-    end
-    ShowAura(aura)
-  else
-    HideAura(aura)
-  end
-end
-
---UpdateAuras
-local function UpdateAuras()
-  for i, aura in next, auras do
-    if aura.enabled then
-      UpdateAura(aura)
-    end
-  end
-end
-
---Tick
-local function Tick()
-  UpdateAuras()
-  C_Timer.After(tick, Tick)
-end
-
-local function UpdateSpells()
-  spec = GetSpecialization()
-  form = GetShapeshiftForm()
-  for i, aura in next, auras do
-    if aura.requireSpell and not IsPlayerSpell(aura.requireSpell) then
-      HideAura(aura)
-      aura.enabled = false
-    elseif aura.spec and aura.form and (aura.spec ~= spec or aura.form ~= form) then
-      HideAura(aura)
-      aura.enabled = false
-    elseif aura.spec and aura.spec ~= spec then
-      HideAura(aura)
-      aura.enabled = false
-    elseif aura.form and aura.form ~= form then
-      HideAura(aura)
-      aura.enabled = false
-    else
-      aura.enabled = true
-    end
-  end
-end
-
---Login
-local function Login()
-  numAuras = #auras
-  if numAuras == 0 then return end
-  local error = false
-  for i, aura in next, auras do
-    if type(aura.button) == "string" then aura.button = _G[aura.button] end
-    local border = _G[aura.button:GetName().."Border"]
-    if not border then
-      print(A,aura.spellid,"border not found")
-      error = true
-      break
-    else
-      aura.border = border
-    end
-    local spellName = GetSpellInfo(aura.spellid)
-    if not spellName then
-      print(A,aura.spellid,"spell id not found")
-      error = true
-      break
-    else
-      aura.spellName = spellName
-    end
-    if aura.useBar then
-      local a, b = aura.border:GetDrawLayer()
-      aura.bar = aura.border:GetParent():CreateTexture(nil,a,nil,b)
-      aura.bar:SetColorTexture(unpack(aura.barColor))
-      aura.bar:SetBlendMode("ADD")
-      aura.bar:SetPoint(unpack(aura.barPoint))
-      aura.bar:SetSize(0,aura.barHeight)
-      aura.bar:Hide()
-      aura.bar.maxwidth = aura.border:GetParent():GetWidth()
-    end
-    if aura.useBorder then
-      aura.border:SetVertexColor(unpack(aura.borderColor))
-    end
-    aura.enabled = false
-  end
-  if not error then
-    --RegisterCallback SPELLS_CHANGE
-    rLib:RegisterCallback("SPELLS_CHANGED", UpdateSpells)
-    UpdateSpells()
-    Tick()
-  end
-end
-
---RegisterCallback PLAYER_LOGIN
-rLib:RegisterCallback("PLAYER_LOGIN", Login)
-
-
diff --git a/rButtonAura/rButtonAura.toc b/rButtonAura/rButtonAura.toc
deleted file mode 100644
index 03bfb54..0000000
--- a/rButtonAura/rButtonAura.toc
+++ /dev/null
@@ -1,7 +0,0 @@
-## Interface: 30400
-## Title: rButtonAura |cff1a9fc0WLK|r
-## Author: zork
-## Notes: Highlights action buttons when a matching unit aura is present
-## RequiredDeps: rLib
-
-core.lua
diff --git a/rButtonAura_Zork/LICENSE.md b/rButtonAura_Zork/LICENSE.md
deleted file mode 100644
index 3d88403..0000000
--- a/rButtonAura_Zork/LICENSE.md
+++ /dev/null
@@ -1,21 +0,0 @@
-MIT License
-
-Copyright (c) 2011-2018 Erik Raetz
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
\ No newline at end of file
diff --git a/rButtonAura_Zork/config.lua b/rButtonAura_Zork/config.lua
deleted file mode 100644
index d4ee0fb..0000000
--- a/rButtonAura_Zork/config.lua
+++ /dev/null
@@ -1,258 +0,0 @@
-
--- rButtonAura_Zork: config
--- zork, 2018
-
------------------------------
--- Variables
------------------------------
-
-local A, L = ...
-
-local character = UnitName("player")
-
------------------------------
--- Aura config for Zörk
------------------------------
-
-if character == "Zörk" then
-
-  --shield block
-  local aura = {
-    button          = ActionButton8,
-    unit            = "player",
-    caster          = "player",
-    spellid         = 132404,
-    filter          = "HELPFUL|PLAYER",
-    spec            = 3,
-    useBar          = true,
-    barColor        = {1,1,0,1},
-    barPoint        = {"TOPLEFT"},
-    barHeight       = 4,
-    useBorder       = true,
-    borderColor     = {0,1,0,1},
-  }
-  rButtonAura:AddAura(aura)
-
-  --arms sweeping strikes
-  local aura = {
-    button          = ActionButton7,
-    unit            = "player",
-    caster          = "player",
-    spellid         = 260708,
-    filter          = "HELPFUL|PLAYER",
-    spec            = 1,
-    useBar          = true,
-    barColor        = {1,1,0,1},
-    barPoint        = {"TOPLEFT"},
-    barHeight       = 4,
-    useBorder       = true,
-    borderColor     = {0,1,0,1},
-  }
-  rButtonAura:AddAura(aura)
-
-  --arms colossus smash
-  local aura = {
-    button          = ActionButton8,
-    unit            = "target",
-    caster          = "player",
-    spellid         = 208086,
-    filter          = "HARMFUL|PLAYER",
-    spec            = 1,
-    useBar          = true,
-    barColor        = {1,1,0,1},
-    barPoint        = {"TOPLEFT"},
-    barHeight       = 4,
-    useBorder       = true,
-    borderColor     = {0,1,0,1},
-  }
-  rButtonAura:AddAura(aura)
-
-  --spell reflect
-  local aura = {
-    button          = ActionButton10,
-    unit            = "player",
-    caster          = "player",
-    spellid         = 23920,
-    filter          = "HELPFUL|PLAYER",
-    spec            = 3,
-    useBar          = true,
-    barColor        = {1,1,0,1},
-    barPoint        = {"TOPLEFT"},
-    barHeight       = 4,
-    useBorder       = true,
-    borderColor     = {0,1,0,1},
-  }
-  rButtonAura:AddAura(aura)
-
-  --battle shout
-  local aura = {
-    button          = MultiBarBottomLeftButton9,
-    unit            = "player",
-    caster          = "player",
-    spellid         = 6673,
-    filter          = "HELPFUL|PLAYER",
-    --spec            = 3,
-    useBar          = false,
-    barColor        = {1,1,0,1},
-    barPoint        = {"TOPLEFT"},
-    barHeight       = 4,
-    useBorder       = true,
-    borderColor     = {0,1,0,1},
-  }
-  rButtonAura:AddAura(aura)
-
-  --ignore pain
-  local aura = {
-    button          = ActionButton9,
-    unit            = "player",
-    caster          = "player",
-    spellid         = 190456,
-    filter          = "HELPFUL|PLAYER",
-    spec            = 3,
-    useBar          = true,
-    barColor        = {1,1,0,1},
-    barPoint        = {"TOPLEFT"},
-    barHeight       = 4,
-    useBorder       = true,
-    borderColor     = {0,1,0,1},
-  }
-  rButtonAura:AddAura(aura)
-
-  --avatar
-  local aura = {
-    button          = MultiBarBottomLeftButton8,
-    unit            = "player",
-    caster          = "player",
-    spellid         = 107574,
-    filter          = "HELPFUL|PLAYER",
-    spec            = 3,
-    useBar          = false,
-    barColor        = {1,1,0,1},
-    barPoint        = {"TOPLEFT"},
-    barHeight       = 4,
-    useBorder       = true,
-    borderColor     = {0,1,0,1},
-  }
-  rButtonAura:AddAura(aura)
-
-  --last stand
-  local aura = {
-    button          = MultiBarBottomLeftButton7,
-    unit            = "player",
-    caster          = "player",
-    spellid         = 12975,
-    filter          = "HELPFUL|PLAYER",
-    spec            = 3,
-    useBar          = true,
-    barColor        = {1,1,0,1},
-    barPoint        = {"TOPLEFT"},
-    barHeight       = 4,
-    useBorder       = true,
-    borderColor     = {0,1,0,1},
-  }
-  rButtonAura:AddAura(aura)
-
-  --shield wall
-  local aura = {
-    button          = MultiBarBottomLeftButton12,
-    unit            = "player",
-    caster          = "player",
-    spellid         = 871,
-    filter          = "HELPFUL|PLAYER",
-    spec            = 3,
-    useBar          = true,
-    barColor        = {1,1,0,1},
-    barPoint        = {"TOPLEFT"},
-    barHeight       = 4,
-    useBorder       = true,
-    borderColor     = {0,1,0,1},
-  }
-  rButtonAura:AddAura(aura)
-
-  --fury whirlwind
-  local aura = {
-    button          = ActionButton4,
-    unit            = "player",
-    caster          = "player",
-    spellid         = 85739,
-    filter          = "HELPFUL|PLAYER",
-    spec            = 2,
-    useBar          = true,
-    barColor        = {1,1,0,1},
-    barPoint        = {"TOPLEFT"},
-    barHeight       = 4,
-    useBorder       = true,
-    borderColor     = {0,1,0,1},
-  }
-  rButtonAura:AddAura(aura)
-
-  --fury enrage
-  local aura = {
-    button          = ActionButton2,
-    unit            = "player",
-    caster          = "player",
-    spellid         = 184362,
-    filter          = "HELPFUL|PLAYER",
-    spec            = 2,
-    useBar          = true,
-    barColor        = {1,1,0,1},
-    barPoint        = {"TOPLEFT"},
-    barHeight       = 4,
-    useBorder       = true,
-    borderColor     = {0,1,0,1},
-  }
-  rButtonAura:AddAura(aura)
-
-end
-
------------------------------
--- Aura config for Xia (Drood)
------------------------------
-
-if character == "Xia" then
-
-  --regrowth
-  local aura = {
-    button          = ActionButton1,
-    unit            = "player",
-    caster          = "player",
-    spellid         = 8936,
-    filter          = "HELPFUL|PLAYER",
-    spec            = 2,
-    form            = 0,
-    --requireSpell    = 5221, --only make the buff visible if this spell is available
-    useBar          = true,
-    barColor        = {1,1,0,1},
-    barPoint        = {"TOPLEFT"},
-    barHeight       = 4,
-    useBorder       = true,
-    borderColor     = {0,1,0,1},
-  }
-  rButtonAura:AddAura(aura)
-
-end
-
------------------------------
--- Aura config for Astone (WL)
------------------------------
-
-if character == "Astone" then
-
-  --Corruption
-  local aura = {
-    button          = "BT4Button63",
-    unit            = "target",
-    caster          = "player",
-    spellid         = 146739,
-    filter          = "HARMFUL|PLAYER",
-    spec            = 1,
-    useBar          = true,
-    barColor        = {1,1,0,1},
-    barPoint        = {"TOPLEFT"},
-    barHeight       = 4,
-    useBorder       = true,
-    borderColor     = {0,1,0,1},
-  }
-  rButtonAura:AddAura(aura)
-
-end
\ No newline at end of file
diff --git a/rButtonAura_Zork/rButtonAura_Zork.toc b/rButtonAura_Zork/rButtonAura_Zork.toc
deleted file mode 100644
index 02042a9..0000000
--- a/rButtonAura_Zork/rButtonAura_Zork.toc
+++ /dev/null
@@ -1,7 +0,0 @@
-## Interface: 30400
-## Title: rButtonAura_Zork |cff1a9fc0WLK|r
-## Author: zork
-## Notes: Zork's config for rButtonAura
-## RequiredDeps: rButtonAura
-
-config.lua
diff --git a/rButtonTemplate/core.lua b/rButtonTemplate/core.lua
index d5f0e04..29982c3 100644
--- a/rButtonTemplate/core.lua
+++ b/rButtonTemplate/core.lua
@@ -167,44 +167,77 @@ local function SetupBackdrop(button,backdrop)
   return bg
 end

+local function RangeUpdate(self, hasrange, inrange)
+	local icon = self.icon
+	local normalTexture = self.NormalTexture
+	local id = self.action
+
+	if not id then return end
+
+	local isUsable, notEnoughPower = IsUsableAction(id)
+
+	if isUsable then
+		if (hasrange and inrange == false) then
+			icon:SetVertexColor(0.8, 0.1, 0.1)
+			normalTexture:SetVertexColor(0.8, 0.1, 0.1)
+		else
+			icon:SetVertexColor(1.0, 1.0, 1.0)
+			normalTexture:SetVertexColor(1.0, 1.0, 1.0)
+		end
+	elseif notEnoughPower then
+		icon:SetVertexColor(0.1, 0.3, 1.0)
+		normalTexture:SetVertexColor(0.1, 0.3, 1.0)
+	else
+		icon:SetVertexColor(0.3, 0.3, 0.3)
+		normalTexture:SetVertexColor(0.3, 0.3, 0.3)
+	end
+end
+
 local function FormatHotkey(hotkey)
 	local text = hotkey:GetText()
 	if (not text) then return end

-	text = string.gsub(text, "(s%-)", "S")
-	text = string.gsub(text, "(a%-)", "A")
-	text = string.gsub(text, "(c%-)", "C")
-	text = string.gsub(text, KEY_MOUSEWHEELDOWN , "MDn")
-  text = string.gsub(text, KEY_MOUSEWHEELUP , "MUp")
-	text = string.gsub(text, KEY_BUTTON3, "M3")
-	text = string.gsub(text, KEY_BUTTON4, "M4")
-	text = string.gsub(text, KEY_BUTTON5, "M5")
-	text = string.gsub(text, KEY_MOUSEWHEELUP, "MU")
-	text = string.gsub(text, KEY_MOUSEWHEELDOWN, "MD")
+	local indicator = _G["RANGE_INDICATOR"]
+
+	text = string.gsub(text, "(s%-)", "|cffff8000s|r")
+	text = string.gsub(text, "(a%-)", "|cffff8000a|r")
+	text = string.gsub(text, "(c%-)", "|cffff8000c|r")
+	text = string.gsub(text, KEY_BUTTON3, "m3")
+	text = string.gsub(text, KEY_BUTTON4, "m4")
+	text = string.gsub(text, KEY_BUTTON5, "m5")
+	text = string.gsub(text, KEY_MOUSEWHEELUP, "mU")
+	text = string.gsub(text, KEY_MOUSEWHEELDOWN, "mD")
 	text = string.gsub(text, KEY_NUMPAD0, "N0")
-  text = string.gsub(text, KEY_NUMPAD1, "N1")
-  text = string.gsub(text, KEY_NUMPAD2, "N2")
-  text = string.gsub(text, KEY_NUMPAD3, "N3")
-  text = string.gsub(text, KEY_NUMPAD4, "N4")
-  text = string.gsub(text, KEY_NUMPAD5, "N5")
-  text = string.gsub(text, KEY_NUMPAD6, "N6")
-  text = string.gsub(text, KEY_NUMPAD7, "N7")
-  text = string.gsub(text, KEY_NUMPAD8, "N8")
-  text = string.gsub(text, KEY_NUMPAD9, "N9")
-  text = string.gsub(text, KEY_NUMPADDECIMAL, "N.")
-  text = string.gsub(text, KEY_NUMPADDIVIDE, "N/")
-  text = string.gsub(text, KEY_NUMPADMINUS, "N-")
-  text = string.gsub(text, KEY_NUMPADMULTIPLY, "N*")
-  text = string.gsub(text, KEY_NUMPADPLUS, "N+")
+	text = string.gsub(text, KEY_NUMPAD1, "N1")
+	text = string.gsub(text, KEY_NUMPAD2, "N2")
+	text = string.gsub(text, KEY_NUMPAD3, "N3")
+	text = string.gsub(text, KEY_NUMPAD4, "N4")
+	text = string.gsub(text, KEY_NUMPAD5, "N5")
+	text = string.gsub(text, KEY_NUMPAD6, "N6")
+	text = string.gsub(text, KEY_NUMPAD7, "N7")
+	text = string.gsub(text, KEY_NUMPAD8, "N8")
+	text = string.gsub(text, KEY_NUMPAD9, "N9")
+	text = string.gsub(text, KEY_NUMPADDECIMAL, "N.")
+	text = string.gsub(text, KEY_NUMPADDIVIDE, "N/")
+	text = string.gsub(text, KEY_NUMPADMINUS, "N-")
+	text = string.gsub(text, KEY_NUMPADMULTIPLY, "N*")
+	text = string.gsub(text, KEY_NUMPADPLUS, "N+")
 	text = string.gsub(text, KEY_PAGEUP, "PU")
 	text = string.gsub(text, KEY_PAGEDOWN, "PD")
-	text = string.gsub(text, KEY_SPACE, "Spc")
-	text = string.gsub(text, KEY_INSERT, "Ins")
-	text = string.gsub(text, KEY_HOME, "Hm")
-	text = string.gsub(text, KEY_DELETE, "Del")
-	text = string.gsub(text, KEY_INSERT_MAC, "Hlp") -- mac
-
-	hotkey:SetText(text)
+	text = string.gsub(text, KEY_SPACE, "SPB")
+	text = string.gsub(text, KEY_INSERT, "INS")
+	text = string.gsub(text, KEY_HOME, "HM")
+	text = string.gsub(text, KEY_DELETE, "DEL")
+	text = string.gsub(text, KEY_BACKSPACE, "BKS")
+	text = string.gsub(text, KEY_INSERT_MAC, "HLP") -- mac
+
+	if text == indicator then
+		hotkey:SetText("")
+	else
+		hotkey:SetText(text)
+	end
+
+	hotkey:SetVertexColor(1, 1, 1)
 end

 function rButtonTemplate:StyleActionButton(button, cfg)
@@ -355,9 +388,6 @@ function rButtonTemplate:UpdateHotkeys()
   FormatHotkey(hotkey)
 end

-hooksecurefunc("ActionButton_UpdateHotkeys", rButtonTemplate.UpdateHotkeys)
-hooksecurefunc("PetActionButton_SetHotkeys", rButtonTemplate.UpdateHotkeys)
-
 function rButtonTemplate:StyleAllActionButtons(cfg)
   for i = 1, NUM_ACTIONBAR_BUTTONS do
     rButtonTemplate:StyleActionButton(_G["ActionButton"..i],cfg)
@@ -387,6 +417,10 @@ function rButtonTemplate:StyleAllActionButtons(cfg)
   -- for i=1, NUM_POSSESS_SLOTS do
   --   rButtonTemplate:StyleActionButton(_G["PossessButton"..i],cfg)
   -- end
+
+  hooksecurefunc("ActionButton_UpdateRangeIndicator", RangeUpdate)
+  hooksecurefunc("ActionButton_UpdateHotkeys", rButtonTemplate.UpdateHotkeys)
+  hooksecurefunc("PetActionButton_SetHotkeys", rButtonTemplate.UpdateHotkeys)
 end

 function rButtonTemplate:StyleAuraButton(button, cfg)
diff --git a/rButtonTemplate_Zork/theme.lua b/rButtonTemplate_Zork/theme.lua
index 1d998de..043ab71 100644
--- a/rButtonTemplate_Zork/theme.lua
+++ b/rButtonTemplate_Zork/theme.lua
@@ -83,7 +83,6 @@ actionButtonConfig.normalTexture = {
   },
 }

---[[
 --pushedTexture
 actionButtonConfig.pushedTexture = {
   file = mediapath.."pushed",
@@ -108,7 +107,6 @@ actionButtonConfig.checkedTexture = {
     {"BOTTOMRIGHT", 0, 0 },
   },
 }
-]]--

 --cooldown
 actionButtonConfig.cooldown = {
diff --git a/rCombatText/rCombatText.lua b/rCombatText/rCombatText.lua
index 90867c3..8af6562 100644
--- a/rCombatText/rCombatText.lua
+++ b/rCombatText/rCombatText.lua
@@ -25,3 +25,8 @@ COMBAT_TEXT_REFLECT = "Reflect"
 COMBAT_TEXT_BLOCK = "Block"
 COMBAT_TEXT_ABSORB = "Absorb"
 COMBAT_TEXT_RESIST = "Resist"
+COMBAT_THREAT_DECREASE_0 = "-Target"
+COMBAT_THREAT_DECREASE_1 = "-Target"
+COMBAT_THREAT_DECREASE_2 = "-Threat"
+COMBAT_THREAT_INCREASE_1 = "+Threat"
+COMBAT_THREAT_INCREASE_3 = ">>> YOU! <<<"
\ No newline at end of file
diff --git a/rFilter/LICENSE.md b/rFilter/LICENSE.md
deleted file mode 100644
index 3d88403..0000000
--- a/rFilter/LICENSE.md
+++ /dev/null
@@ -1,21 +0,0 @@
-MIT License
-
-Copyright (c) 2011-2018 Erik Raetz
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
\ No newline at end of file
diff --git a/rFilter/README.md b/rFilter/README.md
deleted file mode 100644
index 4a1abc1..0000000
--- a/rFilter/README.md
+++ /dev/null
@@ -1,62 +0,0 @@
-# rFilter API
-
-rFilter provides a set of functions that can by used to spawn buttons to track buffs, debuffs on any unit and cooldowns of the player.
-
-## rFilter:CreateBuff
-
-Creates a button of type "buff" and returns it.
-
-* spellid: type:NUMBER, spellid of the buff you want to track
-* unit: type:STRING, unit on which the buff should be tracked
-* size: type:NUMBER, default size of the button
-* point: type:TABLE, default point http://wowprogramming.com/docs/widgets/Region/SetPoint
-* visibility: type:STRING, custom visibility state driver. example: "[combat] show; hide"
-* alpha: type:TABLE, table containing two numbers defining the alpha of the button when off and on. example: {0.2, 1} --off,on
-* desaturate: type:BOOLEAN, desaturate the button texture when the buff is not found
-* caster: type:STRING, additional unit check to test if a buff is casted by a specific unit. example: "player"
-
-```lua
-local button = rFilter:CreateBuff(spellid,unit,size,point,visibility,alpha,desaturate,caster)
-```
-
-## rFilter:CreateDebuff
-
-Creates a button of type "debuff" and returns it.
-
-* spellid: type:NUMBER, spellid of the debuffs you want to track
-* unit: type:STRING, unit on which the debuffs should be tracked
-* size: type:NUMBER, default size of the button
-* point: type:TABLE, default point http://wowprogramming.com/docs/widgets/Region/SetPoint
-* visibility: type:STRING, custom visibility state driver. example: "[combat] show; hide"
-* alpha: type:TABLE, table containing two numbers defining the alpha of the button when off and on. example: {0.2, 1} --off,on
-* desaturate: type:BOOLEAN, desaturate the button texture when the debuff is not found
-* caster: type:STRING, additional unit check to test if a debuff is casted by a specific unit. example: "player"
-
-```lua
-local button = rFilter:CreateDebuff(spellid,unit,size,point,visibility,alpha,desaturate,caster)
-```
-
-## rFilter:CreateCooldown
-
-Creates a button of type "cooldown" and returns it.
-
-* spellid: type:NUMBER, spellid of the cooldown you want to track
-* size: type:NUMBER, default size of the button
-* point: type:TABLE, default point http://wowprogramming.com/docs/widgets/Region/SetPoint
-* visibility: type:STRING, custom visibility state driver. example: "[combat] show; hide"
-* alpha: type:TABLE, table containing two numbers defining the alpha of the button when off and on. example: {0.2, 1} --off,on
-* desaturate: type:BOOLEAN, desaturate the button texture when the debuff is not found
-
-```lua
-local button = rFilter:CreateCooldown(spellid,size,point,visibility,alpha,desaturate)
-```
-
-## rFilter:SetTick
-
-Default rFilter tick rate is 0.1 seconds. If you want to change that you can provide a different value.
-
-* tick: type:NUMBER, tick rate in seconds.
-
-```lua
-rFilter:SetTick(0.5)
-```
\ No newline at end of file
diff --git a/rFilter/buff.lua b/rFilter/buff.lua
deleted file mode 100644
index 8517b69..0000000
--- a/rFilter/buff.lua
+++ /dev/null
@@ -1,20 +0,0 @@
-
--- rFilter: core/buff
--- zork, 2016
-
------------------------------
--- Variables
------------------------------
-
-local A, L = ...
-
------------------------------
--- CreateBuff
------------------------------
-
-function rFilter:CreateBuff(spellid,unit,size,point,visibility,alpha,desaturate,caster)
-  local button = L.F.CreateButton("buff","BuffButton",spellid,unit,size,point,visibility,alpha,desaturate,caster)
-  if not button then return end
-  table.insert(L.buffs,button)
-  return button
-end
diff --git a/rFilter/cooldown.lua b/rFilter/cooldown.lua
deleted file mode 100644
index 8123642..0000000
--- a/rFilter/cooldown.lua
+++ /dev/null
@@ -1,20 +0,0 @@
-
--- rFilter: core/cooldown
--- zork, 2016
-
------------------------------
--- Variables
------------------------------
-
-local A, L = ...
-
------------------------------
--- CreateCooldown
------------------------------
-
-function rFilter:CreateCooldown(spellid,size,point,visibility,alpha,desaturate)
-  local button = L.F.CreateButton("cooldown","CooldownButton",spellid,nil,size,point,visibility,alpha,desaturate,nil) --no unit and no caster
-  if not button then return end
-  table.insert(L.cooldowns,button)
-  return button
-end
diff --git a/rFilter/debuff.lua b/rFilter/debuff.lua
deleted file mode 100644
index ab27635..0000000
--- a/rFilter/debuff.lua
+++ /dev/null
@@ -1,20 +0,0 @@
-
--- rFilter: core/debuff
--- zork, 2016
-
------------------------------
--- Variables
------------------------------
-
-local A, L = ...
-
------------------------------
--- CreateDebuff
------------------------------
-
-function rFilter:CreateDebuff(spellid,unit,size,point,visibility,alpha,desaturate,caster)
-  local button = L.F.CreateButton("debuff","DebuffButton",spellid,unit,size,point,visibility,alpha,desaturate,caster)
-  if not button then return end
-  table.insert(L.debuffs,button)
-  return button
-end
diff --git a/rFilter/functions.lua b/rFilter/functions.lua
deleted file mode 100644
index 0a12e28..0000000
--- a/rFilter/functions.lua
+++ /dev/null
@@ -1,251 +0,0 @@
-
--- rFilter: core/functions
--- zork, 2016
-
------------------------------
--- Variables
------------------------------
-
-local A, L = ...
-
---functions container
-L.F = {}
-
------------------------------
--- Functions
------------------------------
-
-local floor,mod,format = floor,mod,format
-
-local function GetFormatedTime(time)
-  if time <= 0 then
-    return nil
-  elseif time < 2 then
-    return floor(time*10)/10
-  elseif time < 60 then
-    return format("%ds", mod(time, 60))
-  elseif time < 3600 then
-    return format("%dm", floor(mod(time, 3600) / 60 + 1))
-  else
-    return format("%dh", floor(time / 3600 + 1))
-  end
-end
-
-local function SetDuration(button,duration)
-  if duration <= 0 or duration > 10 then
-    button.duration:SetText(GetFormatedTime(duration))
-    button.duration:SetTextColor(1, 1, 1)
-  elseif duration < 2 then
-    button.duration:SetText(GetFormatedTime(duration))
-    button.duration:SetTextColor(1, 0.4, 0)
-  else
-    button.duration:SetText(GetFormatedTime(duration))
-    button.duration:SetTextColor(1, 0.8, 0)
-  end
-end
-
-local function SetCount(button,count)
-  if count and count > 1 then
-    button.count:SetText(count)
-  else
-    button.count:SetText("")
-  end
-end
-
---NumberFormat
-local function NumberFormat(v)
-  if not v then return nil end
-  if v > 1E10 then
-    return (floor(v/1E9)).."b"
-  elseif v > 1E9 then
-    return (floor((v/1E9)*10)/10).."b"
-  elseif v > 1E7 then
-    return (floor(v/1E6)).."m"
-  elseif v > 1E6 then
-    return (floor((v/1E6)*10)/10).."m"
-  elseif v > 1E4 then
-    return (floor(v/1E3)).."k"
-  elseif v > 1E3 then
-    return (floor((v/1E3)*10)/10).."k"
-  else
-    return v
-  end
-end
-
---UpdateFont
-local function UpdateFont(button,fontString,fontCfg,buttonSize)
-  local fontFamily,fontSize,fontOutline = unpack(fontCfg)
-  fontSize = buttonSize*fontSize/button.settings.size
-  fontString:SetFont(fontFamily,fontSize,fontOutline)
-end
-
---OnSizeChanged
-local function OnSizeChanged(button, width, height)
-  local size = math.max(width,button.settings.size)
-  button:SetSize(size,size)
-  --button.settings.durationFont
-  if not button.settings.durationFont then
-    button.settings.durationFont = {button.duration:GetFont()}
-  end
-  UpdateFont(button,button.duration,button.settings.durationFont,size)
-  --button.settings.countFont
-  if not button.settings.countFont then
-    button.settings.countFont = {button.count:GetFont()}
-  end
-  UpdateFont(button,button.count,button.settings.countFont,size)
-  --button.settings.extravalueFont
-  if not button.settings.extravalueFont then
-    button.settings.extravalueFont = {button.extravalue:GetFont()}
-  end
-  UpdateFont(button,button.extravalue,button.settings.extravalueFont,size)
-end
-
---CreateButton
-local function CreateButton(type,buttonName,spellid,unit,size,point,visibility,alpha,desaturate,caster)
-  local spellName, spellRank, spellIcon = GetSpellInfo(spellid)
-  if unit then
-    buttonName = A..buttonName..spellid..unit:sub(1,1):upper()..unit:sub(2)
-  else
-    buttonName = A..buttonName..spellid
-  end
-  if not spellName then print(A,"error",buttonName,"Spell not found",spellid) return end
-  local button = CreateFrame("CHECKBUTTON", buttonName, UIParent, "ActionButtonTemplate, SecureHandlerStateTemplate")
-  button.settings = {
-    type = type,
-    spellid = spellid,
-    unit = unit,
-    size = size,
-    alphaOff = alpha[1],
-    alphaOn = alpha[2],
-    desaturate = desaturate,
-    caster = caster,
-    spellName = spellName,
-    spellRank = spellRank,
-    spellIcon = spellIcon,
-  }
-  buttonName = button:GetName()
-  button.icon:SetTexture(spellIcon)
-  button.border = button.Border
-  button.border:Show()
-  button.duration = _G[buttonName.."Name"]
-  button.extravalue = _G[buttonName.."HotKey"]
-  button.count = _G[buttonName.."Count"]
-  button:EnableMouse(false)
-  button:SetSize(size,size)
-  button:SetPoint(unpack(point))
-  if visibility then
-    button.frameVisibility = visibility
-    RegisterStateDriver(button, "visibility", visibility)
-  end
-  --drag/resize frame
-  rLib:CreateDragResizeFrame(button, L.dragFrames, -2, true)
-  --onsizechanged
-  button:SetScript("OnSizeChanged", OnSizeChanged)
-  return button
-end
-L.F.CreateButton = CreateButton
-
---ResetButton
-local function ResetButton(button)
-  if button.state == 1 then return end
-  button.state = 1
-  button:SetAlpha(button.settings.alphaOff)
-  button.duration:SetText("")
-  button.extravalue:SetText("")
-  button.count:SetText("")
-  if button.settings.desaturate then
-    button.icon:SetDesaturated(1)
-  end
-  button.border:SetVertexColor(0.2,0.6,0.8,0)
-end
-
---PreviewButton
-local function PreviewButton(button)
-  if button.state == -1 then return end
-  button.state = -1
-  button:SetAlpha(1)
-  button.duration:SetText("30m")
-  if button.settings.type == "buff" or button.settings.type == "debuff" then
-    button.extravalue:SetText("146k")
-    button.count:SetText("3")
-  end
-  if button.settings.desaturate then
-    button.icon:SetDesaturated(nil)
-  end
-  button.border:SetVertexColor(0.2,0.6,0.8,0)
-end
-
---EnableButton
-local function EnableButton(button)
-  if button.state == 2 then return end
-  button.state = 2
-  button:SetAlpha(button.settings.alphaOn)
-  if button.settings.desaturate then
-    button.icon:SetDesaturated(nil)
-  end
-end
-
---UpdateAura
-local function UpdateAura(button, filter)
-  if button.dragFrame:IsShown() then
-    PreviewButton(button)
-    return
-  end
-  if button.settings.unit and not UnitExists(button.settings.unit) then
-    ResetButton(button)
-    return
-  end
-  local name, icon, count, dispelType, duration, expires, caster, isStealable, nameplateShowPersonal,
-    spellid, canApplyAura, isBossDebuff, _, nameplateShowAll, timeMod,
-    value1, value2, value3 = AuraUtil.FindAuraByName(button.settings.spellName, button.settings.unit, filter)
-  if not name or (button.settings.caster and caster ~= button.settings.caster) then
-    ResetButton(button)
-    return
-  end
-  SetDuration(button,expires-GetTime())
-  SetCount(button,count)
-  button.extravalue:SetText(NumberFormat(value1 or value2 or value3))
-  if button.settings.caster and caster == "player" then
-    button.border:SetVertexColor(0.2,0.6,0.8,1)
-  else
-    button.border:SetVertexColor(0.2,0.6,0.8,0)
-  end
-  EnableButton(button)
-end
-
---UpdateBuff
-local function UpdateBuff(button)
-  UpdateAura(button,"HELPFUL")
-end
-L.F.UpdateBuff = UpdateBuff
-
---UpdateDebuff
-local function UpdateDebuff(button)
-  UpdateAura(button,"HARMFUL")
-end
-L.F.UpdateDebuff = UpdateDebuff
-
---UpdateCooldown
-local function UpdateCooldown(button)
-  if button.dragFrame:IsShown() then
-    PreviewButton(button)
-    return
-  end
-  local start, cooldown, enable = GetSpellCooldown(button.settings.spellid)
-  local duration = start+cooldown-GetTime()
-  if duration > 0 and cooldown > 2 then
-    ResetButton(button)
-    SetDuration(button,duration)
-  else
-    local isUsable, notEnoughMana = IsUsableSpell(button.settings.spellName)
-    if not isUsable or notEnoughMana then
-      ResetButton(button)
-      return
-    end
-    button.duration:SetText("")
-    button.duration:SetTextColor(0, 0.8, 0)
-    button.border:SetVertexColor(0.2,0.6,0.8,0)
-    EnableButton(button)
-  end
-end
-L.F.UpdateCooldown = UpdateCooldown
\ No newline at end of file
diff --git a/rFilter/init.lua b/rFilter/init.lua
deleted file mode 100644
index a986f51..0000000
--- a/rFilter/init.lua
+++ /dev/null
@@ -1,41 +0,0 @@
-
--- rFilter: core/init
--- zork, 2016
-
------------------------------
--- Variables
------------------------------
-
-local A, L = ...
-
-L.addonName       = A
-L.dragFrames      = {}
-L.addonColor      = "0099FF00"
-L.addonShortcut   = "rfilter"
-
---tick
-L.tick = 0.1
-
---container for buff, debuffs, cooldown
-L.buffs = {}
-L.debuffs = {}
-L.cooldowns = {}
-
------------------------------
--- rFilter Global
------------------------------
-
-rFilter = {}
-rFilter.addonName = A
-
---give access to rfilter buffs, debuffs and cooldowns
-rFilter.buffs = L.buffs
-rFilter.debuffs = L.debuffs
-rFilter.cooldowns = L.cooldowns
-
------------------------------
--- rLib slash command
------------------------------
-
---create slash commands
-rLib:CreateSlashCmd(L.addonName, L.addonShortcut, L.dragFrames, L.addonColor)
\ No newline at end of file
diff --git a/rFilter/rFilter.toc b/rFilter/rFilter.toc
deleted file mode 100644
index b1cef74..0000000
--- a/rFilter/rFilter.toc
+++ /dev/null
@@ -1,12 +0,0 @@
-## Interface: 30400
-## Title: rFilter |cff1a9fc0WLK|r
-## Author: zork
-## Notes: Buff, debuff, raidbuff and cooldown filter. Eats puppies!
-## Dependencies: rLib
-
-init.lua
-functions.lua
-buff.lua
-debuff.lua
-cooldown.lua
-timer.lua
diff --git a/rFilter/timer.lua b/rFilter/timer.lua
deleted file mode 100644
index cce3e61..0000000
--- a/rFilter/timer.lua
+++ /dev/null
@@ -1,52 +0,0 @@
-
--- rFilter: core/timer
--- zork, 2016
-
------------------------------
--- Variables
------------------------------
-
-local A, L = ...
-
-local numBuffs, numDebuffs, numCooldowns = 0,0,0
-
------------------------------
--- CreateTimer
------------------------------
-
---optional function to change the tick
-function rFilter:SetTick(tick)
-  if type(tick) == "number" then
-    L.tick = tick
-  end
-end
-
---Update function
-local function Update()
-  if numBuffs > 0 then
-    for i, button in next, L.buffs do
-      L.F.UpdateBuff(button)
-    end
-  end
-  if numDebuffs > 0 then
-    for i, button in next, L.debuffs do
-      L.F.UpdateDebuff(button)
-    end
-  end
-  if numCooldowns > 0 then
-    for i, button in next, L.cooldowns do
-      L.F.UpdateCooldown(button)
-    end
-  end
-  C_Timer.After(L.tick, Update)
-end
-
---OnLogin function
-local function OnLogin()
-  numBuffs, numDebuffs, numCooldowns = #L.buffs, #L.debuffs, #L.cooldowns
-  if (numBuffs + numDebuffs + numCooldowns) == 0 then return end
-  Update()
-end
-
---RegisterCallback PLAYER_LOGIN
-rLib:RegisterCallback("PLAYER_LOGIN", OnLogin)
\ No newline at end of file
diff --git a/rFilter_Zork/LICENSE.md b/rFilter_Zork/LICENSE.md
deleted file mode 100644
index 3d88403..0000000
--- a/rFilter_Zork/LICENSE.md
+++ /dev/null
@@ -1,21 +0,0 @@
-MIT License
-
-Copyright (c) 2011-2018 Erik Raetz
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
\ No newline at end of file
diff --git a/rFilter_Zork/classes/hunter.lua b/rFilter_Zork/classes/hunter.lua
deleted file mode 100644
index 21728e6..0000000
--- a/rFilter_Zork/classes/hunter.lua
+++ /dev/null
@@ -1,71 +0,0 @@
-
--- rFilter_Zork: cooldown
--- zork, 2016
-
------------------------------
--- Variables
------------------------------
-
-local A, L = ...
-
-----------------------------
--- 匹配oUF_Simple_Zork 布局
--- 大图标 5 个 36x36
--- 小图标 7 个 24x24
--- buff - debuff - cooldown
--- 相同法术可以重合
--- 做到类似WA或者TMW的效果
--- 加上间隔一共 220px
-----------------------------
-
-----------------------------
--- HUNTER layout
--- change the spellids or
--- spec with ur own
-----------------------------
-if L.C.playerClass == "HUNTER" then
-  -- 狂野, row 1 col 1
-  rFilter:CreateBuff(34471,"player",36,{"TOPLEFT",oUF_SimplePlayer,"TOPRIGHT",8,0},"show",{0,1},true,nil)
-  rFilter:CreateCooldown(19574,36,{"TOPLEFT",oUF_SimplePlayer,"TOPRIGHT",8,0},"[combat]show;hide",{0.5,1},true)
-  -- 急速射击, row 1 col 2
-  rFilter:CreateBuff(3045,"player",36,{"TOPLEFT",oUF_SimplePlayer,"TOPRIGHT",50,0},"show",{0,1},true,nil)
-  rFilter:CreateCooldown(3045,36,{"TOPLEFT",oUF_SimplePlayer,"TOPRIGHT",50,0},"[combat]show;hide",{0.5,1},true)
-  -- 杀戮命令, row 1 col 3
-  rFilter:CreateCooldown(34026,36,{"TOPLEFT",oUF_SimplePlayer,"TOPRIGHT",92,0},"[combat]show;hide",{0.5,1},true)
-  -- 多重射击, row 1 col 4
-  rFilter:CreateCooldown(27021,36,{"TOPLEFT",oUF_SimplePlayer,"TOPRIGHT",134,0},"[combat]show;hide",{0.5,1},true)
-  -- 奥射, row 1 col 5 315496 212283
-  rFilter:CreateCooldown(14286,36,{"TOPLEFT",oUF_SimplePlayer,"TOPRIGHT",176,0},"[combat]show;hide",{0.5,1},true)
-
-  -- 震荡射击, row 2 col 1
-  rFilter:CreateDebuff(5116,"target",24,{"TOPLEFT",oUF_SimplePlayer,"TOPRIGHT",8,-42},"show",{0,1},true,nil)
-  rFilter:CreateCooldown(5116,24,{"TOPLEFT",oUF_SimplePlayer,"TOPRIGHT",8,-42},"[combat]show;hide",{0.5,1},true)
-  -- 误导, row 2 col 2
-  rFilter:CreateBuff(34477,"player",24,{"TOPLEFT",oUF_SimplePlayer,"TOPRIGHT",38,-42},"show",{0,1},true,nil)
-  rFilter:CreateCooldown(34477,24,{"TOPLEFT",oUF_SimplePlayer,"TOPRIGHT",38,-42},"[combat]show;hide",{0.5,1},true)
-  -- 假死, row 2 col 3
-  rFilter:CreateBuff(5384,"player",24,{"TOPLEFT",oUF_SimplePlayer,"TOPRIGHT",68,-42},"show",{0,1},true,nil)
-  rFilter:CreateCooldown(5384,24,{"TOPLEFT",oUF_SimplePlayer,"TOPRIGHT",68,-42},"[combat]show;hide",{0.5,1},true)
-  -- 冰冻陷阱, row 2 col 4
-  rFilter:CreateDebuff(14309,"target",24,{"TOPLEFT",oUF_SimplePlayer,"TOPRIGHT",98,-42},"show",{0,1},true,nil)
-  rFilter:CreateCooldown(14311,24,{"TOPLEFT",oUF_SimplePlayer,"TOPRIGHT",98,-42},"[combat]show;hide",{0.5,1},true)
-  -- 毒蛇钉刺, row 2 col 5
-  rFilter:CreateDebuff(13554,"target",24,{"TOPLEFT",oUF_SimplePlayer,"TOPRIGHT",128,-42},"show",{0,1},true,"player")
-  rFilter:CreateDebuff(3043,"target",24,{"TOPLEFT",oUF_SimplePlayer,"TOPRIGHT",128,-42},"show",{0,1},true,"player")
-  rFilter:CreateDebuff(27018,"target",24,{"TOPLEFT",oUF_SimplePlayer,"TOPRIGHT",128,-42},"show",{0,1},true,"player")
-  rFilter:CreateCooldown(27018,24,{"TOPLEFT",oUF_SimplePlayer, "TOPRIGHT",128,-42},"[combat]show;hide",{0.5,1},true)
-  -- 瞄准射击, row 2 col 6
-  rFilter:CreateDebuff(20904,"target",24,{"TOPLEFT",oUF_SimplePlayer,"TOPRIGHT",158,-42},"show",{0,1},true,"player")
-  rFilter:CreateCooldown(20904,24,{"TOPLEFT",oUF_SimplePlayer, "TOPRIGHT",158,-42},"[combat]show;hide",{0.5,1},true)
-  -- 胁迫, row 2 col 7
-  rFilter:CreateDebuff(19577,"target",24,{"TOPLEFT",oUF_SimplePlayer,"TOPRIGHT",188,-42},"show",{0,1},true,nil)
-  rFilter:CreateCooldown(19577,24,{"TOPLEFT",oUF_SimplePlayer,"TOPRIGHT",188,-42},"[combat]show;hide",{0.5,1},true)
-
-  -- extra target
-  -- 快速射击
-  rFilter:CreateBuff(6150,"player",24,{"BOTTOMLEFT",oUF_SimpleTarget,"TOPLEFT",0,40},"show",{0,1},true,nil)
-  -- 凶猛灵感
-  rFilter:CreateBuff(34456,"player",24,{"BOTTOMLEFT",oUF_SimpleTarget,"TOPLEFT",30,40},"show",{0,1},true,nil)
-  -- 龙脊
-  rFilter:CreateBuff(34775,"player",24,{"BOTTOMLEFT",oUF_SimpleTarget,"TOPLEFT",60,40},"show",{0,1},true,nil)
-end
diff --git a/rFilter_Zork/classes/rogue.lua b/rFilter_Zork/classes/rogue.lua
deleted file mode 100644
index f99498f..0000000
--- a/rFilter_Zork/classes/rogue.lua
+++ /dev/null
@@ -1,66 +0,0 @@
-
--- rFilter_Zork: cooldown
--- zork, 2016
-
------------------------------
--- Variables
------------------------------
-
-local A, L = ...
-
-----------------------------
--- 匹配oUF_Simple_Zork 布局
--- 大图标 5 个 36x36
--- 小图标 7 个 24x24
--- buff - debuff - cooldown
--- 相同法术可以重合
--- 做到类似WA或者TMW的效果
--- 加上间隔一共 220px
--- player: size = {265,26}, point = {"RIGHT",UIParent,"CENTER",-130,-210}, 110?
--- target: size = {265,26}, point = {"LEFT",UIParent,"CENTER",130,-210},  110?
-----------------------------
-
-----------------------------
--- ROGUE layout
--- change the spellids or
--- spec with ur own
-----------------------------
-if L.C.playerClass == "ROGUE" then
-  -- 暗影之舞, row 1 col 1
-  rFilter:CreateBuff(185313,"player",36,{"TOPLEFT",oUF_SimplePlayer,"TOPRIGHT",8,0},"show",{0,1},true,nil)
-  rFilter:CreateCooldown(185313,36,{"TOPLEFT",oUF_SimplePlayer,"TOPRIGHT",8,0},"[combat]show;hide",{0.2,1},true)
-  -- 切割, row 1 col 2
-  rFilter:CreateBuff(315496,"player",36,{"TOPLEFT",oUF_SimplePlayer,"TOPRIGHT",50,0},"show",{0,1},true,nil)
-  -- rFilter:CreateCooldown(315496,36,{"TOPLEFT",oUF_SimplePlayer,"TOPRIGHT",50,0},"[combat]show;hide",{1,1},true)
-  -- 割裂, row 1 col 3
-  rFilter:CreateDebuff(1943,"target",36,{"TOPLEFT",oUF_SimplePlayer,"TOPRIGHT",92,0},"show",{0,1},true,"player")
-  -- rFilter:CreateCooldown(3,36,{"TOPLEFT",oUF_SimplePlayer,"TOPRIGHT",92,0},"show",{1,1},true)
-  -- 盟约:狂热鞭策, row 1 col 4
-  rFilter:CreateDebuff(323654,"target",36,{"TOPLEFT",oUF_SimplePlayer,"TOPRIGHT",134,0},"show",{0,1},true,"player")
-  rFilter:CreateCooldown(323654,36,{"TOPLEFT",oUF_SimplePlayer,"TOPRIGHT",134,0},"[combat]show;hide",{0.2,1},true)
-  -- 死亡符记, row 1 col 5 315496 212283
-  rFilter:CreateBuff(212283,"player",36,{"TOPLEFT",oUF_SimplePlayer,"TOPRIGHT",176,0},"show",{0,1},true,nil)
-  rFilter:CreateCooldown(212283,36,{"TOPLEFT",oUF_SimplePlayer,"TOPRIGHT",176,0},"[combat]show;hide",{0.2,1},true)
-
-  -- 斗篷, row 2 col 1
-  rFilter:CreateBuff(31224,"player",24,{"TOPLEFT",oUF_SimplePlayer,"TOPRIGHT",8,-42},"show",{0,1},true,nil)
-  rFilter:CreateCooldown(31224,24,{"TOPLEFT",oUF_SimplePlayer,"TOPRIGHT",8,-42},"[combat]show;hide",{0.2,1},true)
-  -- 闪避, row 2 col 2
-  rFilter:CreateBuff(5277,"player",24,{"TOPLEFT",oUF_SimplePlayer,"TOPRIGHT",38,-42},"show",{0,1},true,nil)
-  rFilter:CreateCooldown(5277,24,{"TOPLEFT",oUF_SimplePlayer,"TOPRIGHT",38,-42},"[combat]show;hide",{0.2,1},true)
-  -- 血瓶, row 2 col 3
-  rFilter:CreateBuff(185311,"player",24,{"TOPLEFT",oUF_SimplePlayer,"TOPRIGHT",68,-42},"show",{0,1},true,nil)
-  rFilter:CreateCooldown(185311,24,{"TOPLEFT",oUF_SimplePlayer,"TOPRIGHT",68,-42},"[combat]show;hide",{0.2,1},true)
-  -- 暗影步, row 2 col 4
-  rFilter:CreateBuff(36554,"player",24,{"TOPLEFT",oUF_SimplePlayer,"TOPRIGHT",98,-42},"show",{0,1},true,nil)
-  rFilter:CreateCooldown(36554,24,{"TOPLEFT",oUF_SimplePlayer,"TOPRIGHT",98,-42},"[combat]show;hide",{0.2,1},true)
-  -- 疾跑, row 2 col 5
-  rFilter:CreateBuff(2983,"player",24,{"TOPLEFT",oUF_SimplePlayer,"TOPRIGHT",128,-42},"show",{0,1},true,nil)
-  rFilter:CreateCooldown(2983,24,{"TOPLEFT",oUF_SimplePlayer,"TOPRIGHT",128,-42},"[combat]show;hide",{0.2,1},true)
-  -- 嫁祸, row 2 col 6
-  -- rFilter:CreateBuff(11,"player",24,{"TOPLEFT",oUF_SimplePlayer,"TOPRIGHT",158,-42},"show",{0.2,1},true,nil)
-  rFilter:CreateCooldown(57934,24,{"TOPLEFT",oUF_SimplePlayer, "TOPRIGHT",158,-42},"[combat]show;hide",{0.2,1},true)
-  -- 致盲, row 2 col 7
-  rFilter:CreateDebuff(2094,"target",24,{"TOPLEFT",oUF_SimplePlayer,"TOPRIGHT",188,-42},"show",{0,1},true,nil)
-  rFilter:CreateCooldown(2094,24,{"TOPLEFT",oUF_SimplePlayer,"TOPRIGHT",188,-42},"[combat]show;hide",{0.2,1},true)
-end
diff --git a/rFilter_Zork/init.lua b/rFilter_Zork/init.lua
deleted file mode 100644
index d128738..0000000
--- a/rFilter_Zork/init.lua
+++ /dev/null
@@ -1,20 +0,0 @@
-
--- rFilter_Zork: init
--- zork, 2016
-
------------------------------
--- Variables
------------------------------
-
-local A, L = ...
-
---config container
-L.C = {}
-
---player name and class
-L.C.playerName = UnitName("player")
-local _, playerClass = UnitClass("player")
-L.C.playerClass = playerClass
-
---set tick or use the default from rFilter
---rFilter:SetTick(0.1)
\ No newline at end of file
diff --git a/rFilter_Zork/rFilter_Zork.toc b/rFilter_Zork/rFilter_Zork.toc
deleted file mode 100644
index 2c92bb9..0000000
--- a/rFilter_Zork/rFilter_Zork.toc
+++ /dev/null
@@ -1,11 +0,0 @@
-## Interface: 30400
-## Author: zork
-## Title: rFilter_Zork |cff1a9fc0WLK|r
-## Notes: Layout and optional theme for rFilter
-## RequiredDeps: rLib, rFilter
-## OptionalDeps: rButtonTemplate, rButtonTemplate_Zork
-
-init.lua
-classes/hunter.lua
-classes/rogue.lua
-theme.lua
diff --git a/rFilter_Zork/theme.lua b/rFilter_Zork/theme.lua
deleted file mode 100644
index d5bbfa5..0000000
--- a/rFilter_Zork/theme.lua
+++ /dev/null
@@ -1,85 +0,0 @@
-
--- rFilter_Zork: theme
--- zork, 2016
-
------------------------------
--- Variables
------------------------------
-
-local A, L = ...
-local expressway = rLib.mediapath.."expressway.ttf"
-
---check if the button template addon and the action button config theme is available
-if not rButtonTemplate_Zork_ActionButtonConfig then
-  print(A,"rButtonTemplate_Zork_ActionButtonConfig not found","styling not possible")
-  return
-else
-  print(A,"styling buttons using rButtonTemplate_Zork_ActionButtonConfig")
-end
-
-local copyTable = rLib.CopyTable
-
------------------------------
--- Actionbutton Config
------------------------------
-
---load the default button theme
-local actionButtonConfig = copyTable(rButtonTemplate_Zork_ActionButtonConfig)
-
---name, we use the default actionbutton.name fontstring and use it as our duration fontstring
-actionButtonConfig.name = {
-  font = { expressway, 13, "OUTLINE"},
-  points = {
-    {"LEFT", 0, 0 },
-    {"RIGHT", 0, 0 },
-  },
-  halign = "CENTER",
-  valign = "MIDDLE",
-  alpha = 1,
-}
-
---hotkey, we use the default actionbutton.hotkey fontstring and use it as our extra value fontstring (100k absorb shield etc.)
-actionButtonConfig.hotkey = {
-  font = { expressway, 11, "OUTLINE"},
-  points = {
-    {"TOPRIGHT", 0, 0 },
-    {"BOTTOMLEFT", 0, 0 },
-  },
-  halign = "RIGHT",
-  valign = "TOP",
-  alpha = 1,
-}
-
---count, aura stack count
-actionButtonConfig.count = {
-  font = { expressway, 11, "OUTLINE"},
-  points = {
-    {"BOTTOMRIGHT", 0, 0 },
-    {"BOTTOMLEFT", 0, 0 },
-  },
-  halign = "RIGHT",
-  valign = "BOTTOM",
-  alpha = 1,
-}
-
------------------------------
--- rButtonTemplate:StyleActionButton
------------------------------
-
---Style every single button we created
-local numBuffs, numDebuffs, numCooldowns = #rFilter.buffs, #rFilter.debuffs, #rFilter.cooldowns
-if numBuffs > 0 then
-  for i, button in next, rFilter.buffs do
-    rButtonTemplate:StyleActionButton(button,actionButtonConfig)
-  end
-end
-if numDebuffs > 0 then
-  for i, button in next, rFilter.debuffs do
-    rButtonTemplate:StyleActionButton(button,actionButtonConfig)
-  end
-end
-if numCooldowns > 0 then
-  for i, button in next, rFilter.cooldowns do
-    rButtonTemplate:StyleActionButton(button,actionButtonConfig)
-  end
-end
\ No newline at end of file
diff --git a/rMinimap/core.lua b/rMinimap/core.lua
index 76f3c00..b3d1785 100644
--- a/rMinimap/core.lua
+++ b/rMinimap/core.lua
@@ -79,6 +79,13 @@ MiniMapLFGFrame:SetHighlightTexture(nil)
 MiniMapLFGFrame:SetPushedTexture(nil)
 MiniMapLFGFrameBorder:Hide()  --wrath

+-- BG
+MiniMapBattlefieldFrame:SetParent(Minimap)
+MiniMapBattlefieldFrame:SetScale(.8)
+MiniMapBattlefieldFrame:ClearAllPoints()
+MiniMapBattlefieldFrame:SetPoint("BOTTOMLEFT",Minimap,10,30)
+MiniMapBattlefieldBorder:Hide()
+
 --garrison (DIEEEEEE!!!)
 --GarrisonLandingPageMinimapButton

diff --git a/readme.md b/readme.md
index 9db5411..462997e 100644
--- a/readme.md
+++ b/readme.md
@@ -1,7 +1,7 @@
-# ZorkUI Redux for BCC
+# ZorkUI for WotLKC

 ## Intro
-It is a bbc version/fix of [ZorkUI](https://www.wowinterface.com/downloads/info24252-ZorkUI.html). But I grabbed it from [Zork UI - Classic Redux](https://wowinterface.com/downloads/info25231-ZorkUI-ClassicRedux.html) which is more compatible with the classic wow.
+It is a wrath version/fix of [ZorkUI](https://www.wowinterface.com/downloads/info24252-ZorkUI.html).

 ## Install
 Download this package and extract it into your `_classic_/Interface/AddOns/` folder, that's it!
@@ -17,10 +17,10 @@ There is **NO** gui for configurating! So you SHOULD and MUST modify the lua fil
 - [rBuffFrame](https://github.com/zorker/rothui/blob/master/wow7.0/rBuffFrame/README.me) _style the buff frame_
 - [rButtonTemplate](https://github.com/zorker/rothui/blob/master/wow7.0/rButtonTemplate/README.me) _style buttons_
 - [rChat](https://www.wowinterface.com/downloads/info18319-rChat.html) _tweek the chatframe a little bit_
+- rChatPlus _an enchantment addon for rChat_
 - [rCombatText](https://www.wowinterface.com/downloads/info24251-rCombatText.html) _change the damage font_
 - [rEmote](https://www.wowinterface.com/downloads/info24254-rEmote.html) _notice the npc warning on the top center of screen_
-- [rError](https://www.wowinterface.com/downloads/info24253-rError.html) _hide some
-- [rFilter](https://www.wowinterface.com/downloads/info24279-rFilter_Zork.html) _monitor player's cooldown, or buffs and debuffs from player or enemy. Pls refer to hunter.lua, just change the spellid and cd/debuff/buff func to check the result, the points are well placed_
+- [rError](https://www.wowinterface.com/downloads/info24253-rError.html) _hide some error_
 - [rLib](https://github.com/zorker/rothui/blob/master/wow7.0/rLib/README.me) _basic library dependent by all zorkui addons_
 - [rMinimap](https://www.wowinterface.com/downloads/info11253-rMinimap.html) _style minimap_
 - [rSellPoor](https://www.wowinterface.com/downloads/info24775-rSellPoor.html) _just sell junk_
@@ -30,20 +30,13 @@ There is **NO** gui for configurating! So you SHOULD and MUST modify the lua fil

 ## Recommends
 1. Questie
-2. OmniCC
-3. tullaRange
-4. tdAuction
-5. DBM/BigWigs
-6. Details
-7. AtlasLootClassic
-8. GatherLite
-9. Leatrix_Maps
-10. Pawn
-11. ThreatClassic2
-
-## Further Plans
-1. skin 3rd party addons
-2. improve rChat module
+2. tdAuction
+3. DBM/BigWigs
+4. Details
+5. AtlasLootClassic
+6. GatherLite
+7. Leatrix_Maps
+8. ThreatClassic2

 ## Credit
 All credit goes to [zork](https://wowinterface.com/forums/member.php?userid=101381) and [cocovanana](https://wowinterface.com/forums/member.php?userid=342642)