changeset 32:821b2b7edff1

Removed FuBar_ReActionFu
author Flick <flickerstreak@gmail.com>
date Thu, 03 Apr 2008 16:59:16 +0000
parents 27dde2743f43
children c54c481ad0ed
files modules/FuBar_ReActionFu/FuBar_ReActionFu.lua modules/FuBar_ReActionFu/FuBar_ReActionFu.toc modules/FuBar_ReActionFu/FuBar_ReActionFu.xml modules/FuBar_ReActionFu/lib/AceLibrary/AceLibrary.lua modules/FuBar_ReActionFu/lib/AceLibrary/AceLibrary.toc modules/FuBar_ReActionFu/lib/Dewdrop-2.0/Dewdrop-2.0.lua modules/FuBar_ReActionFu/lib/LibFuBarPlugin-3.0/Changelog-LibFuBarPlugin-3.0-r63707.txt modules/FuBar_ReActionFu/lib/LibFuBarPlugin-3.0/LibFuBarPlugin-3.0.lua modules/FuBar_ReActionFu/lib/LibFuBarPlugin-3.0/LibFuBarPlugin-3.0.toc modules/FuBar_ReActionFu/lib/LibFuBarPlugin-3.0/lib.xml modules/FuBar_ReActionFu/lib/LibRock-1.0/Changelog-LibRock-1.0-r63317.txt modules/FuBar_ReActionFu/lib/LibRock-1.0/LibRock-1.0.lua modules/FuBar_ReActionFu/lib/LibRock-1.0/LibRock-1.0.toc modules/FuBar_ReActionFu/lib/LibRock-1.0/LibStub/LibStub.lua modules/FuBar_ReActionFu/lib/LibRock-1.0/lib.xml modules/FuBar_ReActionFu/lib/embeds.xml modules/modules.xml
diffstat 17 files changed, 0 insertions(+), 9634 deletions(-) [+]
line wrap: on
line diff
--- a/modules/FuBar_ReActionFu/FuBar_ReActionFu.lua	Wed Apr 02 23:44:06 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,98 +0,0 @@
---[[
-  FuBar plugin module for ReAction
-
---]]
-
--- local imports
-local ReAction = ReAction
-
--- module declaration
-local moduleID = "ReActionFu"
-local module = ReAction:NewModule( moduleID,
-  "FuBarPlugin-3.0"
-)
-
-local fubarOptions = {
-  iconPath = "Interface\\Icons\\INV_Qiraj_JewelEncased",
-  hasNoColor = true,
-  tooltipType = "Tablet-2.0",
-  configType = "Dewdrop-2.0",
-  hasNoText = true,
-  defaultPosition = "LEFT",
-  defaultMinimapPosition = 240, -- degrees
-  clickableTooltip = false,
-  independentProfile = true
-  cannotDetachTooltip = true
-  hideMenuTitle = true
-}
-
-function module:OnInitialize()
-  self.db = ReAction.db:RegisterNamespace(moduleID,
-    {
-      profile = {
-        requireFuBar = false
-      }
-    }
-  )
-  self.db.RegisterCallback(self,"OnProfileChanged")
-
-  if self.db.profile.requireFuBar == true then
-    self:Hide()
-  end
-
-  self.OnMenuRequest = {
-    type = "group",
-    handler = ReAction,
-    args = {
-      -- include profile management by default
-      profile = LibStub("AceDBOptions-3.0"):GetOptionsTable(ReAction.db)
-    }
-  }
-
-  -- insert each module's registered global opts into the table top level
-  local opts = self.OnMenuRequest
-  for m, tbl in pairs(ReAction:GetOptions("global")) do
-    if tbl.args then
-      for k, v in pairs(tbl.args) do
-        opts.args[k] = v
-      end
-    end
-  end
-
-  -- listen for new module adds
-  ReAction.RegisterCallback(self, "OnOptionsRegistered")
-
-  -- configure FuBarPlugin
-  for k, v in pairs(fubarOptions) do
-    self:SetFuBarOption(k,v)
-  end
-end
-
-function module:OnProfileChanged()
-  if self.db.profile.requireFuBar == true then
-    module:Hide()
-  else
-    self:Show()
-  end
-end
-
-function module:OnOptionsRegistered( evtName, context, module, opts )
-  if context == "global" then
-    if opts.args then
-      for k, v in pairs(tbl.args) do
-        opts.args[k] = v
-      end
-    end
-  end
-end
-
-function module:OnFuBarClick(button)
-  -- TODO:
-  -- alt, shift, ctrl clicks
-end
-
-function module:OnUpdateFuBarTooltip()
-  -- TODO:
-  -- display status of config mode, keybind mode, etc
-end
-
--- a/modules/FuBar_ReActionFu/FuBar_ReActionFu.toc	Wed Apr 02 23:44:06 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,12 +0,0 @@
-## Interface: 20300
-## Title: FuBar - |cffffffffReAction|r|cff00ff00Fu|r
-## Notes: FuBar plugin for ReAction
-## DefaultState: enabled
-## LoadOnDemand: 1
-## Author: Flick
-## Version: 1.0
-## X-Category: Action Bars
-## X-Embeds: FuBarPlugin-2.0, Tablet-2.0
-## Dependencies: ReAction
-
-FuBar_ReActionFu.xml
--- a/modules/FuBar_ReActionFu/FuBar_ReActionFu.xml	Wed Apr 02 23:44:06 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,8 +0,0 @@
-<Ui xmlns="http://www.blizzard.com/wow/ui/" 
-    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
-    xsi:schemaLocation="http://www.blizzard.com/wow/ui/..\FrameXML\UI.xsd">
-
-  <Include file="lib\embeds.xml"/>
-  <Script file="FuBar_ReActionFu.lua"/>
-
-</Ui>
\ No newline at end of file
--- a/modules/FuBar_ReActionFu/lib/AceLibrary/AceLibrary.lua	Wed Apr 02 23:44:06 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,856 +0,0 @@
---[[
-Name: AceLibrary
-Revision: $Rev: 49421 $
-Developed by: The Ace Development Team (http://www.wowace.com/index.php/The_Ace_Development_Team)
-Inspired By: Iriel (iriel@vigilance-committee.org)
-             Tekkub (tekkub@gmail.com)
-             Revision: $Rev: 49421 $
-Website: http://www.wowace.com/
-Documentation: http://www.wowace.com/index.php/AceLibrary
-SVN: http://svn.wowace.com/root/trunk/Ace2/AceLibrary
-Description: Versioning library to handle other library instances, upgrading,
-             and proper access.
-             It also provides a base for libraries to work off of, providing
-             proper error tools. It is handy because all the errors occur in the
-             file that called it, not in the library file itself.
-Dependencies: None
-License: LGPL v2.1
-]]
-
-local ACELIBRARY_MAJOR = "AceLibrary"
-local ACELIBRARY_MINOR = "$Revision: 49421 $"
-
-local _G = getfenv(0)
-local previous = _G[ACELIBRARY_MAJOR]
-if previous and not previous:IsNewVersion(ACELIBRARY_MAJOR, ACELIBRARY_MINOR) then return end
-
-do
-	-- LibStub is a simple versioning stub meant for use in Libraries.  http://www.wowace.com/wiki/LibStub for more info
-	-- LibStub is hereby placed in the Public Domain -- Credits: Kaelten, Cladhaire, ckknight, Mikk, Ammo, Nevcairiel, joshborke
-	local LIBSTUB_MAJOR, LIBSTUB_MINOR = "LibStub", 2  -- NEVER MAKE THIS AN SVN REVISION! IT NEEDS TO BE USABLE IN ALL REPOS!
-	local LibStub = _G[LIBSTUB_MAJOR]
-
-	if not LibStub or LibStub.minor < LIBSTUB_MINOR then
-		LibStub = LibStub or {libs = {}, minors = {} }
-		_G[LIBSTUB_MAJOR] = LibStub
-		LibStub.minor = LIBSTUB_MINOR
-		
-		function LibStub:NewLibrary(major, minor)
-			assert(type(major) == "string", "Bad argument #2 to `NewLibrary' (string expected)")
-			minor = assert(tonumber(strmatch(minor, "%d+")), "Minor version must either be a number or contain a number.")
-			local oldminor = self.minors[major]
-			if oldminor and oldminor >= minor then return nil end
-			self.minors[major], self.libs[major] = minor, self.libs[major] or {}
-			return self.libs[major], oldminor
-		end
-		
-		function LibStub:GetLibrary(major, silent)
-			if not self.libs[major] and not silent then
-				error(("Cannot find a library instance of %q."):format(tostring(major)), 2)
-			end
-			return self.libs[major], self.minors[major]
-		end
-		
-		function LibStub:IterateLibraries() return pairs(self.libs) end
-		setmetatable(LibStub, { __call = LibStub.GetLibrary })
-	end
-end
-local LibStub = _G.LibStub
-
--- If you don't want AceLibrary to enable libraries that are LoadOnDemand but
--- disabled in the addon screen, set this to true.
-local DONT_ENABLE_LIBRARIES = nil
-
-local function safecall(func,...)
-    local success, err = pcall(func,...)
-    if not success then geterrorhandler()(err:find("%.lua:%d+:") and err or (debugstack():match("\n(.-: )in.-\n") or "") .. err) end
-end
-
-local WoW22 = false
-if type(GetBuildInfo) == "function" then
-	local success, buildinfo = pcall(GetBuildInfo)
-	if success and type(buildinfo) == "string" then
-		local num = tonumber(buildinfo:match("^(%d+%.%d+)"))
-		if num and num >= 2.2 then
-			WoW22 = true
-		end
-	end
-end
-
--- @table AceLibrary
--- @brief System to handle all versioning of libraries.
-local AceLibrary = {}
-local AceLibrary_mt = {}
-setmetatable(AceLibrary, AceLibrary_mt)
-
-local function error(self, message, ...)
-	if type(self) ~= "table" then
-		return _G.error(("Bad argument #1 to `error' (table expected, got %s)"):format(type(self)), 2)
-	end
-	
-	local stack = debugstack()
-	if not message then
-		local second = stack:match("\n(.-)\n")
-		message = "error raised! " .. second
-	else
-		local arg = { ... } -- not worried about table creation, as errors don't happen often
-		
-		for i = 1, #arg do
-			arg[i] = tostring(arg[i])
-		end
-		for i = 1, 10 do
-			table.insert(arg, "nil")
-		end
-		message = message:format(unpack(arg))
-	end
-	
-	if getmetatable(self) and getmetatable(self).__tostring then
-		message = ("%s: %s"):format(tostring(self), message)
-	elseif type(rawget(self, 'GetLibraryVersion')) == "function" and AceLibrary:HasInstance(self:GetLibraryVersion()) then
-		message = ("%s: %s"):format(self:GetLibraryVersion(), message)
-	elseif type(rawget(self, 'class')) == "table" and type(rawget(self.class, 'GetLibraryVersion')) == "function" and AceLibrary:HasInstance(self.class:GetLibraryVersion()) then
-		message = ("%s: %s"):format(self.class:GetLibraryVersion(), message)
-	end
-	
-	local first = stack:gsub("\n.*", "")
-	local file = first:gsub(".*\\(.*).lua:%d+: .*", "%1")
-	file = file:gsub("([%(%)%.%*%+%-%[%]%?%^%$%%])", "%%%1")
-	
-	
-	local i = 0
-	for s in stack:gmatch("\n([^\n]*)") do
-		i = i + 1
-		if not s:find(file .. "%.lua:%d+:") and not s:find("%(tail call%)") then
-			file = s:gsub("^.*\\(.*).lua:%d+: .*", "%1")
-			file = file:gsub("([%(%)%.%*%+%-%[%]%?%^%$%%])", "%%%1")
-			break
-		end
-	end
-	local j = 0
-	for s in stack:gmatch("\n([^\n]*)") do
-		j = j + 1
-		if j > i and not s:find(file .. "%.lua:%d+:") and not s:find("%(tail call%)") then
-			return _G.error(message, j+1)
-		end
-	end
-	return _G.error(message, 2)
-end
-
-local assert
-if not WoW22 then
-	function assert(self, condition, message, ...)
-		if not condition then
-			if not message then
-				local stack = debugstack()
-				local second = stack:match("\n(.-)\n")
-				message = "assertion failed! " .. second
-			end
-			return error(self, message, ...)
-		end
-		return condition
-	end
-end
-
-local type = type
-local function argCheck(self, arg, num, kind, kind2, kind3, kind4, kind5)
-	if type(num) ~= "number" then
-		return error(self, "Bad argument #3 to `argCheck' (number expected, got %s)", type(num))
-	elseif type(kind) ~= "string" then
-		return error(self, "Bad argument #4 to `argCheck' (string expected, got %s)", type(kind))
-	end
-	arg = type(arg)
-	if arg ~= kind and arg ~= kind2 and arg ~= kind3 and arg ~= kind4 and arg ~= kind5 then
-		local stack = debugstack()
-		local func = stack:match("`argCheck'.-([`<].-['>])")
-		if not func then
-			func = stack:match("([`<].-['>])")
-		end
-		if kind5 then
-			return error(self, "Bad argument #%s to %s (%s, %s, %s, %s, or %s expected, got %s)", tonumber(num) or 0/0, func, kind, kind2, kind3, kind4, kind5, arg)
-		elseif kind4 then
-			return error(self, "Bad argument #%s to %s (%s, %s, %s, or %s expected, got %s)", tonumber(num) or 0/0, func, kind, kind2, kind3, kind4, arg)
-		elseif kind3 then
-			return error(self, "Bad argument #%s to %s (%s, %s, or %s expected, got %s)", tonumber(num) or 0/0, func, kind, kind2, kind3, arg)
-		elseif kind2 then
-			return error(self, "Bad argument #%s to %s (%s or %s expected, got %s)", tonumber(num) or 0/0, func, kind, kind2, arg)
-		else
-			return error(self, "Bad argument #%s to %s (%s expected, got %s)", tonumber(num) or 0/0, func, kind, arg)
-		end
-	end
-end
-
-local pcall
-do
-	local function check(self, ret, ...)
-		if not ret then
-			local s = ...
-			return error(self, (s:gsub(".-%.lua:%d-: ", "")))
-		else
-			return ...
-		end
-	end
-
-	function pcall(self, func, ...)
-		return check(self, _G.pcall(func, ...))
-	end
-end
-
-local recurse = {}
-local function addToPositions(t, major)
-	if not AceLibrary.positions[t] or AceLibrary.positions[t] == major then
-		rawset(t, recurse, true)
-		AceLibrary.positions[t] = major
-		for k,v in pairs(t) do
-			if type(v) == "table" and not rawget(v, recurse) then
-				addToPositions(v, major)
-			end
-			if type(k) == "table" and not rawget(k, recurse) then
-				addToPositions(k, major)
-			end
-		end
-		local mt = getmetatable(t)
-		if mt and not rawget(mt, recurse) then
-			addToPositions(mt, major)
-		end
-		rawset(t, recurse, nil)
-	end
-end
-
-local function svnRevisionToNumber(text)
-	local kind = type(text)
-	if kind == "number" or tonumber(text) then
-		return tonumber(text)
-	elseif kind == "string" then
-		if text:find("^%$Revision: (%d+) %$$") then
-			return tonumber((text:match("^%$Revision: (%d+) %$$")))
-		elseif text:find("^%$Rev: (%d+) %$$") then
-			return tonumber((text:match("^%$Rev: (%d+) %$$")))
-		elseif text:find("^%$LastChangedRevision: (%d+) %$$") then
-			return tonumber((text:match("^%$LastChangedRevision: (%d+) %$$")))
-		end
-	end
-	return nil
-end
-
-local crawlReplace
-do
-	local recurse = {}
-	local function func(t, to, from)
-		if recurse[t] then
-			return
-		end
-		recurse[t] = true
-		local mt = getmetatable(t)
-		setmetatable(t, nil)
-		rawset(t, to, rawget(t, from))
-		rawset(t, from, nil)
-		for k,v in pairs(t) do
-			if v == from then
-				t[k] = to
-			elseif type(v) == "table" then
-				if not recurse[v] then
-					func(v, to, from)
-				end
-			end
-			
-			if type(k) == "table" then
-				if not recurse[k] then
-					func(k, to, from)
-				end
-			end
-		end
-		setmetatable(t, mt)
-		if mt then
-			if mt == from then
-				setmetatable(t, to)
-			elseif not recurse[mt] then
-				func(mt, to, from)
-			end
-		end
-	end
-	function crawlReplace(t, to, from)
-		func(t, to, from)
-		for k in pairs(recurse) do
-			recurse[k] = nil
-		end
-	end
-end
-
--- @function destroyTable
--- @brief    remove all the contents of a table
--- @param t  table to destroy
-local function destroyTable(t)
-	setmetatable(t, nil)
-	for k,v in pairs(t) do
-		t[k] = nil 
-	end
-end
-
-local function isFrame(frame)
-	return type(frame) == "table" and type(rawget(frame, 0)) == "userdata" and type(rawget(frame, 'IsFrameType')) == "function" and getmetatable(frame) and type(rawget(getmetatable(frame), '__index')) == "function"
-end
-
--- @function   copyTable
--- @brief      Create a shallow copy of a table and return it.
--- @param from The table to copy from
--- @return     A shallow copy of the table
-local function copyTable(from, to)
-	if not to then
-		to = {}
-	end
-	for k,v in pairs(from) do
-		to[k] = v
-	end
-	setmetatable(to, getmetatable(from))
-	return to
-end
-
--- @function         deepTransfer
--- @brief            Fully transfer all data, keeping proper previous table
---                   backreferences stable.
--- @param to         The table with which data is to be injected into
--- @param from       The table whose data will be injected into the first
--- @param saveFields If available, a shallow copy of the basic data is saved
---                   in here.
--- @param list       The account of table references
--- @param list2      The current status on which tables have been traversed.
-local deepTransfer
-do
-	-- @function   examine
-	-- @brief      Take account of all the table references to be shared
-	--             between the to and from tables.
-	-- @param to   The table with which data is to be injected into
-	-- @param from The table whose data will be injected into the first
-	-- @param list An account of the table references
-	local function examine(to, from, list, major)
-		list[from] = to
-		for k,v in pairs(from) do
-			if rawget(to, k) and type(from[k]) == "table" and type(to[k]) == "table" and not list[from[k]] then
-				if from[k] == to[k] then
-					list[from[k]] = to[k]
-				elseif AceLibrary.positions[from[v]] ~= major and AceLibrary.positions[from[v]] then
-					list[from[k]] = from[k]
-				elseif not list[from[k]] then
-					examine(to[k], from[k], list, major)
-				end
-			end
-		end
-		return list
-	end
-	
-	function deepTransfer(to, from, saveFields, major, list, list2)
-		setmetatable(to, nil)
-		if not list then
-			list = {}
-			list2 = {}
-			examine(to, from, list, major)
-		end
-		list2[to] = to
-		for k,v in pairs(to) do
-			if type(rawget(from, k)) ~= "table" or type(v) ~= "table" or isFrame(v) then
-				if saveFields then
-					saveFields[k] = v
-				end
-				to[k] = nil
-			elseif v ~= _G then
-				if saveFields then
-					saveFields[k] = copyTable(v)
-				end
-			end
-		end
-		for k in pairs(from) do
-			if rawget(to, k) and to[k] ~= from[k] and AceLibrary.positions[to[k]] == major and from[k] ~= _G then
-				if not list2[to[k]] then
-					deepTransfer(to[k], from[k], nil, major, list, list2)
-				end
-				to[k] = list[to[k]] or list2[to[k]]
-			else
-				rawset(to, k, from[k])
-			end
-		end
-		setmetatable(to, getmetatable(from))
-		local mt = getmetatable(to)
-		if mt then
-			if list[mt] then
-				setmetatable(to, list[mt])
-			elseif mt.__index and list[mt.__index] then
-				mt.__index = list[mt.__index]
-			end
-		end
-		destroyTable(from)
-	end
-end
-
-local function TryToEnable(addon)
-	if DONT_ENABLE_LIBRARIES then return end
-	local isondemand = IsAddOnLoadOnDemand(addon)
-	if isondemand then
-		local _, _, _, enabled = GetAddOnInfo(addon)
-		EnableAddOn(addon)
-		local _, _, _, _, loadable = GetAddOnInfo(addon)
-		if not loadable and not enabled then
-			DisableAddOn(addon)
-		end
-
-		return loadable
-	end
-end
-
--- @method      TryToLoadStandalone
--- @brief       Attempt to find and load a standalone version of the requested library
--- @param major A string representing the major version
--- @return      If library is found and loaded, true is return. If not loadable, false is returned.
---              If the library has been requested previously, nil is returned.
-local function TryToLoadStandalone(major)
-	if not AceLibrary.scannedlibs then AceLibrary.scannedlibs = {} end
-	if AceLibrary.scannedlibs[major] then return end
-
-	AceLibrary.scannedlibs[major] = true
-
-	local name, _, _, enabled, loadable = GetAddOnInfo(major)
-	
-	loadable = (enabled and loadable) or TryToEnable(name)
-	
-	local loaded = false
-	if loadable then
-		loaded = true
-		LoadAddOn(name)
-	end
-	
-	local field = "X-AceLibrary-" .. major 
-	for i = 1, GetNumAddOns() do
-		if GetAddOnMetadata(i, field) then
-			name, _, _, enabled, loadable = GetAddOnInfo(i)
-			
-			loadable = (enabled and loadable) or TryToEnable(name)
-			if loadable then
-				loaded = true
-				LoadAddOn(name)
-			end
-		end
-	end
-	return loaded
-end
-
--- @method      IsNewVersion
--- @brief       Obtain whether the supplied version would be an upgrade to the
---              current version. This allows for bypass code in library
---              declaration.
--- @param major A string representing the major version
--- @param minor An integer or an svn revision string representing the minor version
--- @return      whether the supplied version would be newer than what is
---              currently available.
-function AceLibrary:IsNewVersion(major, minor)
-	argCheck(self, major, 2, "string")
-	TryToLoadStandalone(major)
-
-	if type(minor) == "string" then
-		local m = svnRevisionToNumber(minor)
-		if m then
-			minor = m
-		else
-			_G.error(("Bad argument #3 to  `IsNewVersion'. Must be a number or SVN revision string. %q is not appropriate"):format(minor), 2)
-		end
-	end
-	argCheck(self, minor, 3, "number")
-	local lib, oldMinor = LibStub:GetLibrary(major, true)
-	if lib then
-		return oldMinor < minor
-	end
-	local data = self.libs[major]
-	if not data then
-		return true
-	end
-	return data.minor < minor
-end
-
--- @method      HasInstance
--- @brief       Returns whether an instance exists. This allows for optional support of a library.
--- @param major A string representing the major version.
--- @param minor (optional) An integer or an svn revision string representing the minor version.
--- @return      Whether an instance exists.
-function AceLibrary:HasInstance(major, minor)
-	argCheck(self, major, 2, "string")
-	if minor ~= false then
-		TryToLoadStandalone(major)
-	end
-	
-	local lib, ver = LibStub:GetLibrary(major, true)
-	if not lib and self.libs[major] then
-		lib, ver = self.libs[major].instance, self.libs[major].minor
-	end
-	if minor then
-		if type(minor) == "string" then
-			local m = svnRevisionToNumber(minor)
-			if m then
-				minor = m
-			else
-				_G.error(("Bad argument #3 to  `HasInstance'. Must be a number or SVN revision string. %q is not appropriate"):format(minor), 2)
-			end
-		end
-		argCheck(self, minor, 3, "number")
-		if not lib then
-			return false
-		end
-		return ver == minor
-	end
-	return not not lib
-end
-
--- @method      GetInstance
--- @brief       Returns the library with the given major/minor version.
--- @param major A string representing the major version.
--- @param minor (optional) An integer or an svn revision string representing the minor version.
--- @return      The library with the given major/minor version.
-function AceLibrary:GetInstance(major, minor)
-	argCheck(self, major, 2, "string")
-	if minor ~= false then
-		TryToLoadStandalone(major)
-	end
-
-	local data, ver = LibStub:GetLibrary(major, true)
-	if not data then
-		if self.libs[major] then
-			data, ver = self.libs[major].instance, self.libs[major].minor
-		else
-			_G.error(("Cannot find a library instance of %s."):format(major), 2)
-			return
-		end
-	end
-	if minor then
-		if type(minor) == "string" then
-			local m = svnRevisionToNumber(minor)
-			if m then
-				minor = m
-			else
-				_G.error(("Bad argument #3 to  `GetInstance'. Must be a number or SVN revision string. %q is not appropriate"):format(minor), 2)
-			end
-		end
-		argCheck(self, minor, 2, "number")
-		if ver ~= minor then
-			_G.error(("Cannot find a library instance of %s, minor version %d."):format(major, minor), 2)
-		end
-	end
-	return data
-end
-
--- Syntax sugar.  AceLibrary("FooBar-1.0")
-AceLibrary_mt.__call = AceLibrary.GetInstance
-
-local donothing = function() end
-
-local AceEvent
-
-local tmp = {}
-
--- @method               Register
--- @brief                Registers a new version of a given library.
--- @param newInstance    the library to register
--- @param major          the major version of the library
--- @param minor          the minor version of the library
--- @param activateFunc   (optional) A function to be called when the library is
---                       fully activated. Takes the arguments
---                       (newInstance [, oldInstance, oldDeactivateFunc]). If
---                       oldInstance is given, you should probably call
---                       oldDeactivateFunc(oldInstance).
--- @param deactivateFunc (optional) A function to be called by a newer library's
---                       activateFunc.
--- @param externalFunc   (optional) A function to be called whenever a new
---                       library is registered.
-function AceLibrary:Register(newInstance, major, minor, activateFunc, deactivateFunc, externalFunc)
-	argCheck(self, newInstance, 2, "table")
-	argCheck(self, major, 3, "string")
-	if major ~= ACELIBRARY_MAJOR then
-		for k,v in pairs(_G) do
-			if v == newInstance then
-				geterrorhandler()((debugstack():match("(.-: )in.-\n") or "") .. ("Cannot register library %q. It is part of the global table in _G[%q]."):format(major, k))
-			end
-		end
-	end
-	if major ~= ACELIBRARY_MAJOR and not major:find("^[%a%-][%a%d%-]*%-%d+%.%d+$") then
-		_G.error(string.format("Bad argument #3 to `Register'. Must be in the form of \"Name-1.0\". %q is not appropriate", major), 2)
-	end
-	if type(minor) == "string" then
-		local m = svnRevisionToNumber(minor)
-		if m then
-			minor = m
-		else
-			_G.error(("Bad argument #4 to `Register'. Must be a number or SVN revision string. %q is not appropriate"):format(minor), 2)
-		end
-	end
-	argCheck(self, minor, 4, "number")
-	if math.floor(minor) ~= minor or minor < 0 then
-		error(self, "Bad argument #4 to `Register' (integer >= 0 expected, got %s)", minor)
-	end
-	argCheck(self, activateFunc, 5, "function", "nil")
-	argCheck(self, deactivateFunc, 6, "function", "nil")
-	argCheck(self, externalFunc, 7, "function", "nil")
-	if not deactivateFunc then
-		deactivateFunc = donothing
-	end
-	local data = self.libs[major]
-	if not data then
-		-- This is new
-		if LibStub:GetLibrary(major, true) then
-			error(self, "Cannot register library %q. It is already registered with LibStub.", major)
-		end
-		local instance = LibStub:NewLibrary(major, minor)
-		copyTable(newInstance, instance)
-		crawlReplace(instance, instance, newInstance)
-		destroyTable(newInstance)
-		if AceLibrary == newInstance then
-			self = instance
-			AceLibrary = instance
-		end
-		self.libs[major] = {
-			instance = instance,
-			minor = minor,
-			deactivateFunc = deactivateFunc,
-			externalFunc = externalFunc,
-		}
-		rawset(instance, 'GetLibraryVersion', function(self)
-			return major, minor
-		end)
-		if not rawget(instance, 'error') then
-			rawset(instance, 'error', error)
-		end
-		if not WoW22 and not rawget(instance, 'assert') then
-			rawset(instance, 'assert', assert)
-		end
-		if not rawget(instance, 'argCheck') then
-			rawset(instance, 'argCheck', argCheck)
-		end
-		if not rawget(instance, 'pcall') then
-			rawset(instance, 'pcall', pcall)
-		end
-		addToPositions(instance, major)
-		if activateFunc then
-			safecall(activateFunc, instance, nil, nil) -- no old version, so explicit nil
-			
---[[			if major ~= ACELIBRARY_MAJOR then
-				for k,v in pairs(_G) do
-					if v == instance then
-						geterrorhandler()((debugstack():match("(.-: )in.-\n") or "") .. ("Cannot register library %q. It is part of the global table in _G[%q]."):format(major, k))
-					end
-				end
-			end]]
-		end
-		
-		if externalFunc then
-			for k, data_instance in LibStub:IterateLibraries() do -- all libraries
-				tmp[k] = data_instance
-			end
-			for k, data in pairs(self.libs) do -- Ace libraries which may not have been registered with LibStub
-				tmp[k] = data.instance
-			end
-			for k, data_instance in pairs(tmp) do
-				if k ~= major then
-					safecall(externalFunc, instance, k, data_instance)
-				end
-				tmp[k] = nil
-			end
-		end
-		
-		for k,data in pairs(self.libs) do -- only Ace libraries
-			if k ~= major and data.externalFunc then
-				safecall(data.externalFunc, data.instance, major, instance)
-			end
-		end
-		if major == "AceEvent-2.0" then
-			AceEvent = instance
-		end
-		if AceEvent then
-			AceEvent.TriggerEvent(self, "AceLibrary_Register", major, instance)
-		end
-		
-		return instance
-	end
-	if minor <= data.minor then
-		-- This one is already obsolete, raise an error.
-		_G.error(("Obsolete library registered. %s is already registered at version %d. You are trying to register version %d. Hint: if not AceLibrary:IsNewVersion(%q, %d) then return end"):format(major, data.minor, minor, major, minor), 2)
-		return
-	end
-	local instance = data.instance
-	-- This is an update
-	local oldInstance = {}
-	
-	local libStubInstance = LibStub:GetLibrary(major, true)
-	if not libStubInstance then -- non-LibStub AceLibrary registered the library
-		-- pass
-	elseif libStubInstance ~= instance then	
-		error(self, "Cannot register library %q. It is already registered with LibStub.", major)
-	else
-		LibStub:NewLibrary(major, minor) -- upgrade the minor version
-	end
-	
-	addToPositions(newInstance, major)
-	local isAceLibrary = (AceLibrary == newInstance)
-	local old_error, old_assert, old_argCheck, old_pcall
-	if isAceLibrary then
-		self = instance
-		AceLibrary = instance
-		
-		old_error = instance.error
-		if not WoW22 then
-			old_assert = instance.assert
-		end
-		old_argCheck = instance.argCheck
-		old_pcall = instance.pcall
-		
-		self.error = error
-		if not WoW22 then
-			self.assert = assert
-		end
-		self.argCheck = argCheck
-		self.pcall = pcall
-	end
-	deepTransfer(instance, newInstance, oldInstance, major)
-	crawlReplace(instance, instance, newInstance)
-	local oldDeactivateFunc = data.deactivateFunc
-	data.minor = minor
-	data.deactivateFunc = deactivateFunc
-	data.externalFunc = externalFunc
-	rawset(instance, 'GetLibraryVersion', function()
-		return major, minor
-	end)
-	if not rawget(instance, 'error') then
-		rawset(instance, 'error', error)
-	end
-	if not WoW22 and not rawget(instance, 'assert') then
-		rawset(instance, 'assert', assert)
-	end
-	if not rawget(instance, 'argCheck') then
-		rawset(instance, 'argCheck', argCheck)
-	end
-	if not rawget(instance, 'pcall') then
-		rawset(instance, 'pcall', pcall)
-	end
-	if isAceLibrary then
-		for _,v in pairs(self.libs) do
-			local i = type(v) == "table" and v.instance
-			if type(i) == "table" then
-				if not rawget(i, 'error') or i.error == old_error then
-					rawset(i, 'error', error)
-				end
-				if not WoW22 and (not rawget(i, 'assert') or i.assert == old_assert) then
-					rawset(i, 'assert', assert)
-				end
-				if not rawget(i, 'argCheck') or i.argCheck == old_argCheck then
-					rawset(i, 'argCheck', argCheck)
-				end
-				if not rawget(i, 'pcall') or i.pcall == old_pcall then
-					rawset(i, 'pcall', pcall)
-				end
-			end
-		end
-	end
-	if activateFunc then
-		safecall(activateFunc, instance, oldInstance, oldDeactivateFunc)	
-				
---[[		if major ~= ACELIBRARY_MAJOR then
-			for k,v in pairs(_G) do
-				if v == instance then
-					geterrorhandler()((debugstack():match("(.-: )in.-\n") or "") .. ("Cannot register library %q. It is part of the global table in _G[%q]."):format(major, k))
-				end
-			end
-		end]]
-	else
-		safecall(oldDeactivateFunc, oldInstance)
-	end
-	oldInstance = nil
-	
-	if externalFunc then
-		for k, data_instance in LibStub:IterateLibraries() do -- all libraries
-			tmp[k] = data_instance
-		end
-		for k, data in pairs(self.libs) do -- Ace libraries which may not have been registered with LibStub
-			tmp[k] = data.instance
-		end
-		for k, data_instance in pairs(tmp) do
-			if k ~= major then
-				safecall(externalFunc, instance, k, data_instance)
-			end
-			tmp[k] = nil
-		end
-	end
-	
-	return instance
-end
-
-function AceLibrary:IterateLibraries()
-	local t = {}
-	for major, instance in LibStub:IterateLibraries() do
-		t[major] = instance
-	end
-	for major, data in pairs(self.libs) do
-		t[major] = data.instance
-	end
-	return pairs(t)
-end
-
-local function manuallyFinalize(major, instance)
-	if AceLibrary.libs[major] then
-		-- don't work on Ace libraries
-		return
-	end
-	local finalizedExternalLibs = AceLibrary.finalizedExternalLibs
-	if finalizedExternalLibs[major] then
-		return
-	end
-	finalizedExternalLibs[major] = true
-	
-	for k,data in pairs(AceLibrary.libs) do -- only Ace libraries
-		if k ~= major and data.externalFunc then
-			safecall(data.externalFunc, data.instance, major, instance)
-		end
-	end
-end
-
--- @function            Activate
--- @brief               The activateFunc for AceLibrary itself. Called when
---                      AceLibrary properly registers.
--- @param self          Reference to AceLibrary
--- @param oldLib        (optional) Reference to an old version of AceLibrary
--- @param oldDeactivate (optional) Function to deactivate the old lib
-local function activate(self, oldLib, oldDeactivate)
-	AceLibrary = self
-	if not self.libs then
-		self.libs = oldLib and oldLib.libs or {}
-		self.scannedlibs = oldLib and oldLib.scannedlibs or {}
-	end
-	if not self.positions then
-		self.positions = oldLib and oldLib.positions or setmetatable({}, { __mode = "k" })
-	end
-	self.finalizedExternalLibs = oldLib and oldLib.finalizedExternalLibs or {}
-	self.frame = oldLib and oldLib.frame or CreateFrame("Frame")
-	self.frame:UnregisterAllEvents()
-	self.frame:RegisterEvent("ADDON_LOADED")
-	self.frame:SetScript("OnEvent", function()
-		for major, instance in LibStub:IterateLibraries() do
-			manuallyFinalize(major, instance)
-		end
-	end)
-	for major, instance in LibStub:IterateLibraries() do
-		manuallyFinalize(major, instance)
-	end
-	
-	-- Expose the library in the global environment
-	_G[ACELIBRARY_MAJOR] = self
-	
-	if oldDeactivate then
-		oldDeactivate(oldLib)
-	end
-end
-
-if not previous then
-	previous = AceLibrary
-end
-if not previous.libs then
-	previous.libs = {}
-end
-AceLibrary.libs = previous.libs
-if not previous.positions then
-	previous.positions = setmetatable({}, { __mode = "k" })
-end
-AceLibrary.positions = previous.positions
-AceLibrary:Register(AceLibrary, ACELIBRARY_MAJOR, ACELIBRARY_MINOR, activate, nil)
--- a/modules/FuBar_ReActionFu/lib/AceLibrary/AceLibrary.toc	Wed Apr 02 23:44:06 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,10 +0,0 @@
-## Interface: 20200
-
-## Title: Lib: AceLibrary
-## Notes: AddOn development framework
-## Author: Ace Development Team
-## X-Website: http://www.wowace.com
-## X-Category: Library
-## X-License: LGPL v2.1 + MIT for AceOO-2.0
- 
-AceLibrary.lua
--- a/modules/FuBar_ReActionFu/lib/Dewdrop-2.0/Dewdrop-2.0.lua	Wed Apr 02 23:44:06 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3487 +0,0 @@
---[[
-Name: Dewdrop-2.0
-Revision: $Rev: 56529 $
-Author(s): ckknight (ckknight@gmail.com)
-Website: http://ckknight.wowinterface.com/
-Documentation: http://wiki.wowace.com/index.php/Dewdrop-2.0
-SVN: http://svn.wowace.com/root/trunk/DewdropLib/Dewdrop-2.0
-Description: A library to provide a clean dropdown menu interface.
-Dependencies: AceLibrary
-License: LGPL v2.1
-]]
-
-local MAJOR_VERSION = "Dewdrop-2.0"
-local MINOR_VERSION = "$Revision: 56529 $"
-
-if not AceLibrary then error(MAJOR_VERSION .. " requires AceLibrary") end
-if not AceLibrary:IsNewVersion(MAJOR_VERSION, MINOR_VERSION) then return end
-
-local Dewdrop = {}
-
-local SharedMedia
-
-local CLOSE = "Close"
-local CLOSE_DESC = "Close the menu."
-local VALIDATION_ERROR = "Validation error."
-local USAGE_TOOLTIP = "Usage: %s."
-local RANGE_TOOLTIP = "Note that you can scroll your mouse wheel while over the slider to step by one."
-local RESET_KEYBINDING_DESC = "Hit escape to clear the keybinding."
-local KEY_BUTTON1 = "Left Mouse"
-local KEY_BUTTON2 = "Right Mouse"
-local DISABLED = "Disabled"
-local DEFAULT_CONFIRM_MESSAGE = "Are you sure you want to perform `%s'?"
-
-if GetLocale() == "deDE" then
-	CLOSE = "Schlie\195\159en"
-	CLOSE_DESC = "Men\195\188 schlie\195\159en."
-	VALIDATION_ERROR = "Validierungsfehler."
-	USAGE_TOOLTIP = "Benutzung: %s."
-	RANGE_TOOLTIP = "Beachte das du mit dem Mausrad scrollen kannst solange du mit dem Mauszeiger \195\188ber dem Schieberegler bist, um feinere Spr\195\188nge zu machen."
-	RESET_KEYBINDING_DESC = "Escape dr\195\188cken, um die Tastenbelegung zu l\195\182schen."
-	KEY_BUTTON1 = "Linke Maustaste"
-	KEY_BUTTON2 = "Rechte Maustaste"
-	DISABLED = "Deaktiviert"
-	DEFAULT_CONFIRM_MESSAGE = "Bist du sicher das du `%s' machen willst?"
-elseif GetLocale() == "koKR" then
-	CLOSE = "닫기"
-	CLOSE_DESC = "메뉴를 닫습니다."
-	VALIDATION_ERROR = "오류 확인."
-	USAGE_TOOLTIP = "사용법: %s."
-	RANGE_TOOLTIP = "알림 : 슬라이더 위에서 마우스 휠을 사용하면 한단계씩 조절할 수 있습니다."
-	RESET_KEYBINDING_DESC = "단축키를 해제하려면 ESC키를 누르세요."
-	KEY_BUTTON1 = "왼쪽 마우스"
-	KEY_BUTTON2 = "오른쪽 마우스"
-	DISABLED = "비활성화됨"
-	DEFAULT_CONFIRM_MESSAGE = "정말로 `%s' 실행을 하시겠습니까 ?"
-elseif GetLocale() == "frFR" then
-	CLOSE = "Fermer"
-	CLOSE_DESC = "Ferme le menu."
-	VALIDATION_ERROR = "Erreur de validation."
-	USAGE_TOOLTIP = "Utilisation : %s."
-	RANGE_TOOLTIP = "Vous pouvez aussi utiliser la molette de la souris pour pour modifier progressivement."
-	RESET_KEYBINDING_DESC = "Appuyez sur la touche Echappement pour effacer le raccourci."
-	KEY_BUTTON1 = "Clic gauche"
-	KEY_BUTTON2 = "Clic droit"
-	DISABLED = "D\195\169sactiv\195\169"
-	DEFAULT_CONFIRM_MESSAGE = "\195\138tes-vous s\195\187r de vouloir effectuer '%s' ?"
-elseif GetLocale() == "esES" then
-	CLOSE = "Cerrar"
-	CLOSE_DESC = "Cierra el menú."
-	VALIDATION_ERROR = "Error de validación."
-	USAGE_TOOLTIP = "Uso: %s."
-	RANGE_TOOLTIP = "Puedes desplazarte verticalmente con la rueda del ratón sobre el desplazador."
-	RESET_KEYBINDING_DESC = "Pulsa Escape para borrar la asignación de tecla."
-	KEY_BUTTON1 = "Clic Izquierdo"
-	KEY_BUTTON2 = "Clic Derecho"
-	DISABLED = "Desactivado"
-	DEFAULT_CONFIRM_MESSAGE = "¿Estás seguro de querer realizar `%s'?"
-elseif GetLocale() == "zhTW" then
-	CLOSE = "關閉"
-	CLOSE_DESC = "關閉選單。"
-	VALIDATION_ERROR = "驗證錯誤。"
-	USAGE_TOOLTIP = "用法: %s。"
-	RANGE_TOOLTIP = "你可以在捲動條上使用滑鼠滾輪來捲動。"
-	RESET_KEYBINDING_DESC = "按Esc鍵清除快捷鍵。"
-	KEY_BUTTON1 = "滑鼠左鍵"
-	KEY_BUTTON2 = "滑鼠右鍵"
-	DISABLED = "停用"
-	DEFAULT_CONFIRM_MESSAGE = "是否執行「%s」?"
-elseif GetLocale() == "zhCN" then
-	CLOSE = "关闭"
-	CLOSE_DESC = "关闭菜单"
-	VALIDATION_ERROR = "验证错误."
-	USAGE_TOOLTIP = "用法: %s."
-	RANGE_TOOLTIP = "你可以在滚动条上使用鼠标滚轮来翻页."
-	RESET_KEYBINDING_DESC = "按ESC键清除按键绑定"
-	KEY_BUTTON1 = "鼠标左键"
-	KEY_BUTTON2 = "鼠标右键"
-	DISABLED = "禁用"
-	DEFAULT_CONFIRM_MESSAGE = "是否执行'%s'?"
-end
-
-Dewdrop.KEY_BUTTON1 = KEY_BUTTON1
-Dewdrop.KEY_BUTTON2 = KEY_BUTTON2
-
-local function new(...)
-	local t = {}
-	for i = 1, select('#', ...), 2 do
-		local k = select(i, ...)
-		if k then
-			t[k] = select(i+1, ...)
-		else
-			break
-		end
-	end
-	return t
-end
-
-local tmp
-do
-	local t = {}
-	function tmp(...)
-		for k in pairs(t) do
-			t[k] = nil
-		end
-		for i = 1, select('#', ...), 2 do
-			local k = select(i, ...)
-			if k then
-				t[k] = select(i+1, ...)
-			else
-				break
-			end
-		end
-		return t
-	end
-end
-local tmp2
-do
-	local t = {}
-	function tmp2(...)
-		for k in pairs(t) do
-			t[k] = nil
-		end
-		for i = 1, select('#', ...), 2 do
-			local k = select(i, ...)
-			if k then
-				t[k] = select(i+1, ...)
-			else
-				break
-			end
-		end
-		return t
-	end
-end
-local levels
-local buttons
-
-
--- Secure frame handling:
--- Rather than using secure buttons in the menu (has problems), we have one
--- master secureframe that we pop onto menu items on mouseover. This requires
--- some dark magic with OnLeave etc, but it's not too bad.
-
-local secureFrame = CreateFrame("Button", nil, nil, "SecureActionButtonTemplate")
-secureFrame:Hide()
-
-local function secureFrame_Show(self)
-  local owner = self.owner
-
-  if self.secure then	-- Leftovers from previos owner, clean up! ("Shouldn't" happen but does..)
-	  for k,v in pairs(self.secure) do
-	    self:SetAttribute(k, nil)
-	  end
-  end
-  self.secure = owner.secure;	-- Grab hold of new secure data
-
-  local scale = owner:GetEffectiveScale()
-
-  self:SetPoint("TOPLEFT", nil, "BOTTOMLEFT", owner:GetLeft() * scale, owner:GetTop() * scale)
-  self:SetPoint("BOTTOMRIGHT", nil, "BOTTOMLEFT", owner:GetRight() * scale, owner:GetBottom() * scale)
-  self:EnableMouse(true)
-  for k,v in pairs(self.secure) do
-    self:SetAttribute(k, v)
-  end
-
-	secureFrame:SetFrameStrata(owner:GetFrameStrata())
-	secureFrame:SetFrameLevel(owner:GetFrameLevel()+1)
-
-  self:Show()
-end
-
-local function secureFrame_Hide(self)
-  self:Hide()
-  if self.secure then
-	  for k,v in pairs(self.secure) do
-	    self:SetAttribute(k, nil)
-	  end
-	end
-  self.secure = nil
-end
-
-secureFrame:SetScript("OnEvent",
-	function()
-		if event=="PLAYER_REGEN_ENABLED" then
-			this.combat = false
-			if not this:IsShown() and this.owner then
-				secureFrame_Show(this)
-			end
-		elseif event=="PLAYER_REGEN_DISABLED" then
-			this.combat = true
-			if this:IsShown() then
-				secureFrame_Hide(this)
-			end
-		end
-	end
-)
-secureFrame:RegisterEvent("PLAYER_REGEN_ENABLED")
-secureFrame:RegisterEvent("PLAYER_REGEN_DISABLED")
-
-secureFrame:SetScript("OnLeave",
-	function()
-		local owner=this.owner
-		this:Deactivate()
-		owner:GetScript("OnLeave")()
-	end
-)
-
-secureFrame:HookScript("OnClick",
-	function()
-		local realthis = this
-		this = this.owner
-		this:GetScript("OnClick")()
-	end
-)
-
-function secureFrame:IsOwnedBy(frame)
-	return self.owner == frame
-end
-
-function secureFrame:Activate(owner)
-	if self.owner then		-- "Shouldn't" happen but apparently it does and I cba to troubleshoot...
-		if not self.combat then
-			secureFrame_Hide(self)
-		end
-	end
-	self.owner = owner
-	if not self.combat then
-		secureFrame_Show(self)
-	end
-end
-
-function secureFrame:Deactivate()
-	if not self.combat then
-		secureFrame_Hide(self)
-	end
-	self.owner = nil
-end
-
--- END secure frame utilities
-
-
--- Underline on mouseover - use a single global underline that we move around, no point in creating lots of copies
-local underlineFrame = CreateFrame("Frame", nil)
-underlineFrame.tx = underlineFrame:CreateTexture()
-underlineFrame.tx:SetTexture(1,1,0.5,0.75)
-underlineFrame:SetScript("OnHide", function(this) this:Hide(); end)
-underlineFrame:SetScript("OnShow", function(this) 	-- change sizing on the fly to catch runtime uiscale changes
-    underlineFrame.tx:SetPoint("TOPLEFT", -1, -2/this:GetEffectiveScale())
-    underlineFrame.tx:SetPoint("RIGHT", 1,0)
-    underlineFrame.tx:SetHeight(0.6 / this:GetEffectiveScale());
-end)
-underlineFrame:SetHeight(1)
-
--- END underline on mouseover
-
-
-local function GetScaledCursorPosition()
-	local x, y = GetCursorPosition()
-	local scale = UIParent:GetEffectiveScale()
-	return x / scale, y / scale
-end
-
-local function StartCounting(self, level)
-	for i = level, 1, -1 do
-		if levels[i] then
-			levels[i].count = 3
-		end
-	end
-end
-
-local function StopCounting(self, level)
-	for i = level, 1, -1 do
-		if levels[i] then
-			levels[i].count = nil
-		end
-	end
-end
-
-local function OnUpdate(self, elapsed)
-	for _,level in ipairs(levels) do
-		local count = level.count
-		if count then
-			count = count - elapsed
-			if count < 0 then
-				level.count = nil
-				self:Close(level.num)
-			else
-				level.count = count
-			end
-		end
-	end
-end
-
-local function CheckDualMonitor(self, frame)
-	local ratio = GetScreenWidth() / GetScreenHeight()
-	if ratio >= 2.4 and frame:GetRight() > GetScreenWidth() / 2 and frame:GetLeft() < GetScreenWidth() / 2 then
-		local offsetx
-		if GetCursorPosition() / GetScreenHeight() * 768 < GetScreenWidth() / 2 then
-			offsetx = GetScreenWidth() / 2 - frame:GetRight()
-		else
-			offsetx = GetScreenWidth() / 2 - frame:GetLeft()
-		end
-		local point, parent, relativePoint, x, y = frame:GetPoint(1)
-		frame:SetPoint(point, parent, relativePoint, (x or 0) + offsetx, y or 0)
-	end
-end
-
-local function CheckSize(self, level)
-	if not level.buttons then
-		return
-	end
-	local height = 20
-	for _, button in ipairs(level.buttons) do
-		height = height + button:GetHeight()
-	end
-	level:SetHeight(height)
-	local width = 160
-	for _, button in ipairs(level.buttons) do
-		local extra = 1
-		if button.hasArrow or button.hasColorSwatch then
-			extra = extra + 16
-		end
-		if not button.notCheckable then
-			extra = extra + 24
-		end
-		button.text:SetFont(STANDARD_TEXT_FONT, button.textHeight)
-		if button.text:GetWidth() + extra > width then
-			width = button.text:GetWidth() + extra
-		end
-	end
-	level:SetWidth(width + 20)
-	if level:GetLeft() and level:GetRight() and level:GetTop() and level:GetBottom() and (level:GetLeft() < 0 or level:GetRight() > GetScreenWidth() or level:GetTop() > GetScreenHeight() or level:GetBottom() < 0) then
-		level:ClearAllPoints()
-		local parent = level.parent or level:GetParent()
-		if type(parent) ~= "table" then
-			parent = UIParent
-		end
-		if level.lastDirection == "RIGHT" then
-			if level.lastVDirection == "DOWN" then
-				level:SetPoint("TOPLEFT", parent, "TOPRIGHT", 5, 10)
-			else
-				level:SetPoint("BOTTOMLEFT", parent, "BOTTOMRIGHT", 5, -10)
-			end
-		else
-			if level.lastVDirection == "DOWN" then
-				level:SetPoint("TOPRIGHT", parent, "TOPLEFT", -5, 10)
-			else
-				level:SetPoint("BOTTOMRIGHT", parent, "BOTTOMLEFT", -5, -10)
-			end
-		end
-	end
-	local dirty = false
-	if not level:GetRight() then
-		self:Close()
-		return
-	end
-	if level:GetRight() > GetScreenWidth() and level.lastDirection == "RIGHT" then
-		level.lastDirection = "LEFT"
-		dirty = true
-	elseif level:GetLeft() < 0 and level.lastDirection == "LEFT" then
-		level.lastDirection = "RIGHT"
-		dirty = true
-	end
-	if level:GetTop() > GetScreenHeight() and level.lastVDirection == "UP" then
-		level.lastVDirection = "DOWN"
-		dirty = true
-	elseif level:GetBottom() < 0 and level.lastVDirection == "DOWN" then
-		level.lastVDirection = "UP"
-		dirty = true
-	end
-	if dirty then
-		level:ClearAllPoints()
-		local parent = level.parent or level:GetParent()
-		if type(parent) ~= "table" then
-			parent = UIParent
-		end
-		if level.lastDirection == "RIGHT" then
-			if level.lastVDirection == "DOWN" then
-				level:SetPoint("TOPLEFT", parent, "TOPRIGHT", 5, 10)
-			else
-				level:SetPoint("BOTTOMLEFT", parent, "BOTTOMRIGHT", 5, -10)
-			end
-		else
-			if level.lastVDirection == "DOWN" then
-				level:SetPoint("TOPRIGHT", parent, "TOPLEFT", -5, 10)
-			else
-				level:SetPoint("BOTTOMRIGHT", parent, "BOTTOMLEFT", -5, -10)
-			end
-		end
-	end
-	if level:GetTop() > GetScreenHeight() then
-		local top = level:GetTop()
-		local point, parent, relativePoint, x, y = level:GetPoint(1)
-		level:ClearAllPoints()
-		level:SetPoint(point, parent, relativePoint, x or 0, (y or 0) + GetScreenHeight() - top)
-	elseif level:GetBottom() < 0 then
-		local bottom = level:GetBottom()
-		local point, parent, relativePoint, x, y = level:GetPoint(1)
-		level:ClearAllPoints()
-		level:SetPoint(point, parent, relativePoint, x or 0, (y or 0) - bottom)
-	end
-	CheckDualMonitor(self, level)
-	if mod(level.num, 5) == 0 then
-		local left, bottom = level:GetLeft(), level:GetBottom()
-		level:ClearAllPoints()
-		level:SetPoint("BOTTOMLEFT", UIParent, "BOTTOMLEFT", left, bottom)
-	end
-end
-
-local Open
-local OpenSlider
-local OpenEditBox
-local Refresh
-local Clear
-local function ReleaseButton(self, level, index)
-	if not level.buttons then
-		return
-	end
-	if not level.buttons[index] then
-		return
-	end
-	local button = level.buttons[index]
-	button:Hide()
-	if button.highlight then
-		button.highlight:Hide()
-	end
---	button.arrow:SetVertexColor(1, 1, 1)
---	button.arrow:SetHeight(16)
---	button.arrow:SetWidth(16)
-	table.remove(level.buttons, index)
-	table.insert(buttons, button)
-	for k in pairs(button) do
-		if k ~= 0 and k ~= "text" and k ~= "check" and k ~= "arrow" and k ~= "colorSwatch" and k ~= "highlight" and k ~= "radioHighlight" then
-			button[k] = nil
-		end
-	end
-	return true
-end
-
-local function Scroll(self, level, down)
-	if down then
-		if level:GetBottom() < 0 then
-			local point, parent, relativePoint, x, y = level:GetPoint(1)
-			level:SetPoint(point, parent, relativePoint, x, y + 50)
-			if level:GetBottom() > 0 then
-				level:SetPoint(point, parent, relativePoint, x, y + 50 - level:GetBottom())
-			end
-		end
-	else
-		if level:GetTop() > GetScreenHeight() then
-			local point, parent, relativePoint, x, y = level:GetPoint(1)
-			level:SetPoint(point, parent, relativePoint, x, y - 50)
-			if level:GetTop() < GetScreenHeight() then
-				level:SetPoint(point, parent, relativePoint, x, y - 50 + GetScreenHeight() - level:GetTop())
-			end
-		end
-	end
-end
-
-local function getArgs(t, str, num, ...)
-	local x = t[str .. num]
-	if x == nil then
-		return ...
-	else
-		return x, getArgs(t, str, num + 1, ...)
-	end
-end
-
-local sliderFrame
-local editBoxFrame
-
-local normalFont
-local lastSetFont
-local justSetFont = false
-local regionTmp = {}
-local function fillRegionTmp(...)
-	for i = 1, select('#', ...) do
-		regionTmp[i] = select(i, ...)
-	end
-end
-
-local function showGameTooltip(this)
-	if this.tooltipTitle or this.tooltipText then
-		GameTooltip_SetDefaultAnchor(GameTooltip, this)
-		local disabled = not this.isTitle and this.disabled
-		local font
-		if this.tooltipTitle then
-			if SharedMedia and SharedMedia:IsValid("font", this.tooltipTitle) then
-				font = SharedMedia:Fetch("font", this.tooltipTitle)
-			end
-			if disabled then
-				GameTooltip:SetText(this.tooltipTitle, 0.5, 0.5, 0.5, 1)
-			else
-				GameTooltip:SetText(this.tooltipTitle, 1, 1, 1, 1)
-			end
-			if this.tooltipText then
-				if not font and SharedMedia and SharedMedia:IsValid("font", this.tooltipText) then
-					font = SharedMedia:Fetch("font", this.tooltipText)
-				end
-				if disabled then
-					GameTooltip:AddLine(this.tooltipText, (NORMAL_FONT_COLOR.r + 0.5) / 2, (NORMAL_FONT_COLOR.g + 0.5) / 2, (NORMAL_FONT_COLOR.b + 0.5) / 2, 1)
-				else
-					GameTooltip:AddLine(this.tooltipText, NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b, 1)
-				end
-			end
-		else
-			if SharedMedia and SharedMedia:IsValid("font", this.tooltipText) then
-				font = SharedMedia:Fetch("font", this.tooltipText)
-			end
-			if disabled then
-				GameTooltip:SetText(this.tooltipText, 0.5, 0.5, 0.5, 1)
-			else
-				GameTooltip:SetText(this.tooltipText, 1, 1, 1, 1)
-			end
-		end
-		if font then
-			fillRegionTmp(GameTooltip:GetRegions())
-			lastSetFont = font
-			justSetFont = true
-			for i,v in ipairs(regionTmp) do
-				if v.SetFont then
-					local norm,size,outline = v:GetFont()
-					v:SetFont(font, size, outline)
-					if not normalFont then
-						normalFont = norm
-					end
-				end
-				regionTmp[i] = nil
-			end
-		elseif not normalFont then
-			fillRegionTmp(GameTooltip:GetRegions())
-			for i,v in ipairs(regionTmp) do
-				if v.GetFont and not normalFont then
-					normalFont = v:GetFont()
-				end
-				regionTmp[i] = nil
-			end
-		end
-		GameTooltip:Show()
-	end
-	if this.tooltipFunc then
-		GameTooltip:SetOwner(this, "ANCHOR_NONE")
-		GameTooltip:SetPoint("TOPLEFT", this, "TOPRIGHT", 5, 0)
-		this.tooltipFunc(getArgs(this, 'tooltipArg', 1))
-		GameTooltip:Show()
-	end
-end
-
-local tmpt = setmetatable({}, {mode='v'})
-local numButtons = 0
-local function AcquireButton(self, level)
-	if not levels[level] then
-		return
-	end
-	level = levels[level]
-	if not level.buttons then
-		level.buttons = {}
-	end
-	local button
-	if #buttons == 0 then
-		numButtons = numButtons + 1
-		button = CreateFrame("Button", "Dewdrop20Button" .. numButtons, nil)
-		button:SetFrameStrata("FULLSCREEN_DIALOG")
-		button:SetHeight(16)
-		local highlight = button:CreateTexture(nil, "BACKGROUND")
-		highlight:SetTexture("Interface\\QuestFrame\\UI-QuestTitleHighlight")
-		button.highlight = highlight
-		highlight:SetBlendMode("ADD")
-		highlight:SetAllPoints(button)
-		highlight:Hide()
-		local check = button:CreateTexture(nil, "ARTWORK")
-		button.check = check
-		check:SetTexture("Interface\\Buttons\\UI-CheckBox-Check")
-		check:SetPoint("CENTER", button, "LEFT", 12, 0)
-		check:SetWidth(24)
-		check:SetHeight(24)
-		local radioHighlight = button:CreateTexture(nil, "ARTWORK")
-		button.radioHighlight = radioHighlight
-		radioHighlight:SetTexture("Interface\\Buttons\\UI-RadioButton")
-		radioHighlight:SetAllPoints(check)
-		radioHighlight:SetBlendMode("ADD")
-		radioHighlight:SetTexCoord(0.5, 0.75, 0, 1)
-		radioHighlight:Hide()
-		button:SetScript("OnEnter", function()
-			if (sliderFrame and sliderFrame:IsShown() and sliderFrame.mouseDown and sliderFrame.level == this.level.num + 1) or (editBoxFrame and editBoxFrame:IsShown() and editBoxFrame.mouseDown and editBoxFrame.level == this.level.num + 1) then
-				for i = 1, this.level.num do
-					Refresh(self, levels[i])
-				end
-				return
-			end
-			self:Close(this.level.num + 1)
-			if not this.disabled then
-				if this.secure then
-					secureFrame:Activate(this)
-				elseif this.hasSlider then
-					OpenSlider(self, this)
-				elseif this.hasEditBox then
-					OpenEditBox(self, this)
-				elseif this.hasArrow then
-					Open(self, this, nil, this.level.num + 1, this.value)
-				end
-			end
-			if not this.level then -- button reclaimed
-				return
-			end
-			StopCounting(self, this.level.num + 1)
-			if not this.disabled then
-				highlight:Show()
-				if this.isRadio then
-					button.radioHighlight:Show()
-				end
-				if this.mouseoverUnderline then
-					underlineFrame:SetParent(this)
-					underlineFrame:SetPoint("BOTTOMLEFT",this.text,0,0)
-					underlineFrame:SetWidth(this.text:GetWidth())
-					underlineFrame:Show()
-				end
-			end
-			showGameTooltip(this)
-		end)
-		button:SetScript("OnHide", function()
-			if this.secure and secureFrame:IsOwnedBy(this) then
-				secureFrame:Deactivate()
-			end
-		end)
-		button:SetScript("OnLeave", function()
-			if this.secure and secureFrame:IsShown() then
-				return;	-- it's ok, we didn't actually mouse out of the button, only onto the secure frame on top of it
-			end
-			underlineFrame:Hide()
-			if not this.selected then
-				highlight:Hide()
-			end
-			button.radioHighlight:Hide()
-			if this.level then
-				StartCounting(self, this.level.num)
-			end
-			GameTooltip:Hide()
-		end)
-		local first = true
-		button:SetScript("OnClick", function()
-			if not this.disabled then
-				if this.hasColorSwatch then
-					local func = button.colorFunc
-					local hasOpacity = this.hasOpacity
-					local this = this
-					for k in pairs(tmpt) do
-						tmpt[k] = nil
-					end
-					for i = 1, 1000 do
-						local x = this['colorArg'..i]
-						if x == nil then
-							break
-						else
-							tmpt[i] = x
-						end
-					end
-					ColorPickerFrame.func = function()
-						if func then
-							local r,g,b = ColorPickerFrame:GetColorRGB()
-							local a = hasOpacity and 1 - OpacitySliderFrame:GetValue() or nil
-							local n = #tmpt
-							tmpt[n+1] = r
-							tmpt[n+2] = g
-							tmpt[n+3] = b
-							tmpt[n+4] = a
-							func(unpack(tmpt))
-							tmpt[n+1] = nil
-							tmpt[n+2] = nil
-							tmpt[n+3] = nil
-							tmpt[n+4] = nil
-						end
-					end
-					ColorPickerFrame.hasOpacity = this.hasOpacity
-					ColorPickerFrame.opacityFunc = ColorPickerFrame.func
-					ColorPickerFrame.opacity = 1 - this.opacity
-					ColorPickerFrame:SetColorRGB(this.r, this.g, this.b)
-					local r, g, b, a = this.r, this.g, this.b, this.opacity
-					ColorPickerFrame.cancelFunc = function()
-						if func then
-							local n = #tmpt
-							tmpt[n+1] = r
-							tmpt[n+2] = g
-							tmpt[n+3] = b
-							tmpt[n+4] = a
-							func(unpack(tmpt))
-							for i = 1, n+4 do
-								tmpt[i] = nil
-							end
-						end
-					end
-					self:Close(1)
-					ShowUIPanel(ColorPickerFrame)
-				elseif this.func then
-					local level = this.level
-					if type(this.func) == "string" then
-						if type(this.arg1[this.func]) ~= "function" then
-							self:error("Cannot call method %q", this.func)
-						end
-						this.arg1[this.func](this.arg1, getArgs(this, 'arg', 2))
-					else
-						this.func(getArgs(this, 'arg', 1))
-					end
-					if this.closeWhenClicked then
-						self:Close()
-					elseif level:IsShown() then
-						for i = 1, level.num do
-							Refresh(self, levels[i])
-						end
-						local value = levels[level.num].value
-						for i = level.num-1, 1, -1 do
-							local level = levels[i]
-							local good = false
-							for _,button in ipairs(level.buttons) do
-								if button.value == value then
-									good = true
-									break
-								end
-							end
-							if not good then
-								Dewdrop:Close(i+1)
-							end
-							value = levels[i].value
-						end
-					end
-				elseif this.closeWhenClicked then
-					self:Close()
-				end
-			end
-		end)
-		local text = button:CreateFontString(nil, "ARTWORK")
-		button.text = text
-		text:SetFontObject(GameFontHighlightSmall)
-		button.text:SetFont(STANDARD_TEXT_FONT, UIDROPDOWNMENU_DEFAULT_TEXT_HEIGHT)
-		button:SetScript("OnMouseDown", function()
-			if not this.disabled and (this.func or this.colorFunc or this.closeWhenClicked) then
-				text:SetPoint("LEFT", button, "LEFT", this.notCheckable and 1 or 25, -1)
-			end
-		end)
-		button:SetScript("OnMouseUp", function()
-			if not this.disabled and (this.func or this.colorFunc or this.closeWhenClicked) then
-				text:SetPoint("LEFT", button, "LEFT", this.notCheckable and 0 or 24, 0)
-			end
-		end)
-		local arrow = button:CreateTexture(nil, "ARTWORK")
-		button.arrow = arrow
-		arrow:SetPoint("LEFT", button, "RIGHT", -16, 0)
-		arrow:SetWidth(16)
-		arrow:SetHeight(16)
-		arrow:SetTexture("Interface\\ChatFrame\\ChatFrameExpandArrow")
-		local colorSwatch = button:CreateTexture(nil, "ARTWORK")
-		button.colorSwatch = colorSwatch
-		colorSwatch:SetWidth(20)
-		colorSwatch:SetHeight(20)
-		colorSwatch:SetTexture("Interface\\ChatFrame\\ChatFrameColorSwatch")
-		local texture = button:CreateTexture(nil, "OVERLAY")
-		colorSwatch.texture = texture
-		texture:SetTexture("Interface\\Buttons\\WHITE8X8")
-		texture:SetWidth(11.5)
-		texture:SetHeight(11.5)
-		texture:Show()
-		texture:SetPoint("CENTER", colorSwatch, "CENTER")
-		colorSwatch:SetPoint("RIGHT", button, "RIGHT", 0, 0)
-	else
-		button = table.remove(buttons)
-	end
-	button:ClearAllPoints()
-	button:SetParent(level)
-	button:SetFrameStrata(level:GetFrameStrata())
-	button:SetFrameLevel(level:GetFrameLevel() + 1)
-	button:SetPoint("LEFT", level, "LEFT", 10, 0)
-	button:SetPoint("RIGHT", level, "RIGHT", -10, 0)
-	if #level.buttons == 0 then
-		button:SetPoint("TOP", level, "TOP", 0, -10)
-	else
-		button:SetPoint("TOP", level.buttons[#level.buttons], "BOTTOM", 0, 0)
-	end
-	button.text:SetPoint("LEFT", button, "LEFT", 24, 0)
-	button:Show()
-	button.level = level
-	table.insert(level.buttons, button)
-	if not level.parented then
-		level.parented = true
-		level:ClearAllPoints()
-		if level.num == 1 then
-			if level.parent ~= UIParent and type(level.parent) == "table" then
-				level:SetPoint("TOPRIGHT", level.parent, "TOPLEFT")
-			else
-				level:SetPoint("CENTER", UIParent, "CENTER")
-			end
-		else
-			if level.lastDirection == "RIGHT" then
-				if level.lastVDirection == "DOWN" then
-					level:SetPoint("TOPLEFT", level.parent, "TOPRIGHT", 5, 10)
-				else
-					level:SetPoint("BOTTOMLEFT", level.parent, "BOTTOMRIGHT", 5, -10)
-				end
-			else
-				if level.lastVDirection == "DOWN" then
-					level:SetPoint("TOPRIGHT", level.parent, "TOPLEFT", -5, 10)
-				else
-					level:SetPoint("BOTTOMRIGHT", level.parent, "BOTTOMLEFT", -5, -10)
-				end
-			end
-		end
-		level:SetFrameStrata("FULLSCREEN_DIALOG")
-	end
-	button:SetAlpha(1)
-	return button
-end
-
-local numLevels = 0
-local function AcquireLevel(self, level)
-	if not levels[level] then
-		for i = #levels + 1, level, -1 do
-			local i = i
-			numLevels = numLevels + 1
-			local frame = CreateFrame("Button", "Dewdrop20Level" .. numLevels, nil)
-			if i == 1 then
-				local old_CloseSpecialWindows = CloseSpecialWindows
-				function CloseSpecialWindows()
-					local found = old_CloseSpecialWindows()
-					if levels[1]:IsShown() then
-						self:Close()
-						return 1
-					end
-					return found
-				end
-			end
-			levels[i] = frame
-			frame.num = i
-			frame:SetParent(UIParent)
-			frame:SetFrameStrata("FULLSCREEN_DIALOG")
-			frame:Hide()
-			frame:SetWidth(180)
-			frame:SetHeight(10)
-			frame:SetFrameLevel(i * 3)
-			frame:SetScript("OnHide", function()
-				self:Close(level + 1)
-			end)
-			if frame.SetTopLevel then
-				frame:SetTopLevel(true)
-			end
-			frame:EnableMouse(true)
-			frame:EnableMouseWheel(true)
-			local backdrop = CreateFrame("Frame", nil, frame)
-			backdrop:SetAllPoints(frame)
-			backdrop:SetBackdrop(tmp(
-				'bgFile', "Interface\\Tooltips\\UI-Tooltip-Background",
-				'edgeFile', "Interface\\Tooltips\\UI-Tooltip-Border",
-				'tile', true,
-				'insets', tmp2(
-					'left', 5,
-					'right', 5,
-					'top', 5,
-					'bottom', 5
-				),
-				'tileSize', 16,
-				'edgeSize', 16
-			))
-			backdrop:SetBackdropBorderColor(TOOLTIP_DEFAULT_COLOR.r, TOOLTIP_DEFAULT_COLOR.g, TOOLTIP_DEFAULT_COLOR.b)
-			backdrop:SetBackdropColor(TOOLTIP_DEFAULT_BACKGROUND_COLOR.r, TOOLTIP_DEFAULT_BACKGROUND_COLOR.g, TOOLTIP_DEFAULT_BACKGROUND_COLOR.b)
-			frame:SetScript("OnClick", function()
-				self:Close(i)
-			end)
-			frame:SetScript("OnEnter", function()
-				StopCounting(self, i)
-			end)
-			frame:SetScript("OnLeave", function()
-				StartCounting(self, i)
-			end)
-			frame:SetScript("OnMouseWheel", function()
-				Scroll(self, frame, arg1 < 0)
-			end)
-			if i == 1 then
-				frame:SetScript("OnUpdate", function(this, arg1)
-					OnUpdate(self, arg1)
-				end)
-				levels[1].lastDirection = "RIGHT"
-				levels[1].lastVDirection = "DOWN"
-			else
-				levels[i].lastDirection = levels[i - 1].lastDirection
-				levels[i].lastVDirection = levels[i - 1].lastVDirection
-			end
-		end
-	end
-	local fullscreenFrame = GetUIPanel("fullscreen")
-	local l = levels[level]
-	local strata, framelevel = l:GetFrameStrata(), l:GetFrameLevel()
-	if fullscreenFrame then
-		l:SetParent(fullscreenFrame)
-	else
-		l:SetParent(UIParent)
-	end
-	l:SetFrameStrata(strata)
-	l:SetFrameLevel(framelevel)
-	l:SetAlpha(1)
-	return l
-end
-
-local function validateOptions(options, position, baseOptions, fromPass)
-	if not baseOptions then
-		baseOptions = options
-	end
-	if type(options) ~= "table" then
-		return "Options must be a table.", position
-	end
-	local kind = options.type
-	if type(kind) ~= "string" then
-		return '"type" must be a string.', position
-	elseif kind ~= "group" and kind ~= "range" and kind ~= "text" and kind ~= "execute" and kind ~= "toggle" and kind ~= "color" and kind ~= "dragLink" and kind ~= "header" then
-		return '"type" must either be "range", "text", "group", "toggle", "execute", "color", "dragLink", or "header".', position
-	end
-	if options.aliases then
-		if type(options.aliases) ~= "table" and type(options.aliases) ~= "string" then
-			return '"alias" must be a table or string', position
-		end
-	end
-	if not fromPass then
-		if kind == "execute" then
-			if type(options.func) ~= "string" and type(options.func) ~= "function" then
-				return '"func" must be a string or function', position
-			end
-		elseif kind == "range" or kind == "text" or kind == "toggle" then
-			if type(options.set) ~= "string" and type(options.set) ~= "function" then
-				return '"set" must be a string or function', position
-			end
-			if kind == "text" and options.get == false then
-			elseif type(options.get) ~= "string" and type(options.get) ~= "function" then
-				return '"get" must be a string or function', position
-			end
-		elseif kind == "group" and options.pass then
-			if options.pass ~= true then
-				return '"pass" must be either nil, true, or false', position
-			end
-			if not options.func then
-				if type(options.set) ~= "string" and type(options.set) ~= "function" then
-					return '"set" must be a string or function', position
-				end
-				if type(options.get) ~= "string" and type(options.get) ~= "function" then
-					return '"get" must be a string or function', position
-				end
-			elseif type(options.func) ~= "string" and type(options.func) ~= "function" then
-				return '"func" must be a string or function', position
-			end
-		end
-	end
-	if options ~= baseOptions then
-		if kind == "header" then
-		elseif type(options.desc) ~= "string" then
-			return '"desc" must be a string', position
-		elseif options.desc:len() == 0 then
-			return '"desc" cannot be a 0-length string', position
-		end
-	end
-	if options ~= baseOptions or kind == "range" or kind == "text" or kind == "toggle" or kind == "color" then
-		if options.type == "header" and not options.cmdName and not options.name then
-		elseif options.cmdName then
-			if type(options.cmdName) ~= "string" then
-				return '"cmdName" must be a string or nil', position
-			elseif options.cmdName:len() == 0 then
-				return '"cmdName" cannot be a 0-length string', position
-			end
-			if type(options.guiName) ~= "string" then
-				if not options.guiNameIsMap then
-					return '"guiName" must be a string or nil', position
-				end
-			elseif options.guiName:len() == 0 then
-				return '"guiName" cannot be a 0-length string', position
-			end
-		else
-			if type(options.name) ~= "string" then
-				return '"name" must be a string', position
-			elseif options.name:len() == 0 then
-				return '"name" cannot be a 0-length string', position
-			end
-		end
-	end
-	if options.guiNameIsMap then
-		if type(options.guiNameIsMap) ~= "boolean" then
-			return '"guiNameIsMap" must be a boolean or nil', position
-		elseif options.type ~= "toggle" then
-			return 'if "guiNameIsMap" is true, then "type" must be set to \'toggle\'', position
-		elseif type(options.map) ~= "table" then
-			return '"map" must be a table', position
-		end
-	end
-	if options.message and type(options.message) ~= "string" then
-		return '"message" must be a string or nil', position
-	end
-	if options.error and type(options.error) ~= "string" then
-		return '"error" must be a string or nil', position
-	end
-	if options.current and type(options.current) ~= "string" then
-		return '"current" must be a string or nil', position
-	end
-	if options.order then
-		if type(options.order) ~= "number" or (-1 < options.order and options.order < 0.999) then
-			return '"order" must be a non-zero number or nil', position
-		end
-	end
-	if options.disabled then
-		if type(options.disabled) ~= "function" and type(options.disabled) ~= "string" and options.disabled ~= true then
-			return '"disabled" must be a function, string, or boolean', position
-		end
-	end
-	if options.cmdHidden then
-		if type(options.cmdHidden) ~= "function" and type(options.cmdHidden) ~= "string" and options.cmdHidden ~= true then
-			return '"cmdHidden" must be a function, string, or boolean', position
-		end
-	end
-	if options.guiHidden then
-		if type(options.guiHidden) ~= "function" and type(options.guiHidden) ~= "string" and options.guiHidden ~= true then
-			return '"guiHidden" must be a function, string, or boolean', position
-		end
-	end
-	if options.hidden then
-		if type(options.hidden) ~= "function" and type(options.hidden) ~= "string" and options.hidden ~= true then
-			return '"hidden" must be a function, string, or boolean', position
-		end
-	end
-	if kind == "text" then
-		if type(options.validate) == "table" then
-			local t = options.validate
-			local iTable = nil
-			for k,v in pairs(t) do
-				if type(k) == "number" then
-					if iTable == nil then
-						iTable = true
-					elseif not iTable then
-						return '"validate" must either have all keys be indexed numbers or strings', position
-					elseif k < 1 or k > #t then
-						return '"validate" numeric keys must be indexed properly. >= 1 and <= #t', position
-					end
-				else
-					if iTable == nil then
-						iTable = false
-					elseif iTable then
-						return '"validate" must either have all keys be indexed numbers or strings', position
-					end
-				end
-				if type(v) ~= "string" then
-					return '"validate" values must all be strings', position
-				end
-			end
-			if options.multiToggle and options.multiToggle ~= true then
-				return '"multiToggle" must be a boolean or nil if "validate" is a table', position
-			end
-		elseif options.validate == "keybinding" then
-			-- no other checks
-		else
-			if type(options.usage) ~= "string" then
-				return '"usage" must be a string', position
-			elseif options.validate and type(options.validate) ~= "string" and type(options.validate) ~= "function" then
-				return '"validate" must be a string, function, or table', position
-			end
-		end
-		if options.multiToggle and type(options.validate) ~= "table" then
-			return '"validate" must be a table if "multiToggle" is true', position
-		end
-	elseif kind == "range" then
-		if options.min or options.max then
-			if type(options.min) ~= "number" then
-				return '"min" must be a number', position
-			elseif type(options.max) ~= "number" then
-				return '"max" must be a number', position
-			elseif options.min >= options.max then
-				return '"min" must be less than "max"', position
-			end
-		end
-		if options.step then
-			if type(options.step) ~= "number" then
-				return '"step" must be a number', position
-			elseif options.step < 0 then
-				return '"step" must be nonnegative', position
-			end
-		end
-		if options.bigStep then
-			if type(options.bigStep) ~= "number" then
-				return '"bigStep" must be a number', position
-			elseif options.bigStep < 0 then
-				return '"bigStep" must be nonnegative', position
-			end
-		end
-		if options.isPercent and options.isPercent ~= true then
-			return '"isPercent" must either be nil, true, or false', position
-		end
-	elseif kind == "toggle" then
-		if options.map then
-			if type(options.map) ~= "table" then
-				return '"map" must be a table', position
-			elseif type(options.map[true]) ~= "string" then
-				return '"map[true]" must be a string', position
-			elseif type(options.map[false]) ~= "string" then
-				return '"map[false]" must be a string', position
-			end
-		end
-	elseif kind == "color" then
-		if options.hasAlpha and options.hasAlpha ~= true then
-			return '"hasAlpha" must be nil, true, or false', position
-		end
-	elseif kind == "group" then
-		if options.pass and options.pass ~= true then
-			return '"pass" must be nil, true, or false', position
-		end
-		if type(options.args) ~= "table" then
-			return '"args" must be a table', position
-		end
-		for k,v in pairs(options.args) do
-			if type(k) ~= "number" then
-				if type(k) ~= "string" then
-					return '"args" keys must be strings or numbers', position
-				elseif k:len() == 0 then
-					return '"args" keys must not be 0-length strings.', position
-				end
-			end
-			if type(v) ~= "table" then
-				return '"args" values must be tables', position and position .. "." .. k or k
-			end
-			local newposition
-			if position then
-				newposition = position .. ".args." .. k
-			else
-				newposition = "args." .. k
-			end
-			local err, pos = validateOptions(v, newposition, baseOptions, options.pass)
-			if err then
-				return err, pos
-			end
-		end
-	elseif kind == "execute" then
-		if type(options.confirm) ~= "string" and type(options.confirm) ~= "boolean" and type(options.confirm) ~= "nil" then
-			return '"confirm" must be a string, boolean, or nil', position
-		end
-	end
-	if options.icon and type(options.icon) ~= "string" then
-		return'"icon" must be a string', position
-	end
-	if options.iconWidth or options.iconHeight then
-		if type(options.iconWidth) ~= "number" or type(options.iconHeight) ~= "number" then
-			return '"iconHeight" and "iconWidth" must be numbers', position
-		end
-	end
-	if options.iconCoordLeft or options.iconCoordRight or options.iconCoordTop or options.iconCoordBottom then
-		if type(options.iconCoordLeft) ~= "number" or type(options.iconCoordRight) ~= "number" or type(options.iconCoordTop) ~= "number" or type(options.iconCoordBottom) ~= "number" then
-			return '"iconCoordLeft", "iconCoordRight", "iconCoordTop", and "iconCoordBottom" must be numbers', position
-		end
-	end
-end
-
-local validatedOptions
-
-local values
-local mysort_args
-local mysort
-local othersort
-local othersort_validate
-
-local baseFunc, currentLevel
-
-local function confirmPopup(message, func, ...)
-	if not StaticPopupDialogs["DEWDROP20_CONFIRM_DIALOG"] then
-		StaticPopupDialogs["DEWDROP20_CONFIRM_DIALOG"] = {}
-	end
-	local t = StaticPopupDialogs["DEWDROP20_CONFIRM_DIALOG"]
-	for k in pairs(t) do
-		t[k] = nil
-	end
-	t.text = message
-	t.button1 = ACCEPT or "Accept"
-	t.button2 = CANCEL or "Cancel"
-	t.OnAccept = function()
-		func(unpack(t))
-	end
-	for i = 1, select('#', ...) do
-		t[i] = select(i, ...)
-	end
-	t.timeout = 0
-	t.whileDead = 1
-	t.hideOnEscape = 1
-
-	Dewdrop:Close()
-	StaticPopup_Show("DEWDROP20_CONFIRM_DIALOG")
-end
-
-
-local function getMethod(settingname, handler, v, methodName, ...)	-- "..." is simply returned straight out cause you can't do "a,b,c = 111,f(),222"
-	assert(v and type(v)=="table")
-	assert(methodName and type(methodName)=="string")
-
-	local method = v[methodName]
-	if type(method)=="function" then
-		return method, ...
-	elseif type(method)=="string" then
-		if not handler then
-			Dewdrop:error("[%s] 'handler' is required if providing a method name: %q", tostring(settingname), method)
-		elseif not handler[method] then
-			Dewdrop:error("[%s] 'handler' method %q not defined", tostring(settingname), method)
-		end
-		return handler[method], handler, ...
-	end
-
-	Dewdrop:error("[%s] Missing %q directive", tostring(settingname), methodName)
-end
-
-local function callMethod(settingname, handler, v, methodName, ...)
-	assert(v and type(v)=="table")
-	assert(methodName and type(methodName)=="string")
-
-	local method = v[methodName]
-	if type(method)=="function" then
-		local success, ret,ret2,ret3,ret4 = pcall(v[methodName], ...)
-		if not success then
-			geterrorhandler()(ret)
-			return nil
-		end
-		return ret,ret2,ret3,ret4
-
-	elseif type(method)=="string" then
-
-		local neg = method:match("^~(.-)$")
-		if neg then
-			method = neg
-		end
-		if not handler then
-			Dewdrop:error("[%s] 'handler' is required if providing a method name: %q", tostring(settingname), method)
-		elseif not handler[method] then
-			Dewdrop:error("[%s] 'handler' (%q) method %q not defined", tostring(settingname), handler.name or "(unnamed)", method)
-		end
-		local success, ret,ret2,ret3,ret4 = pcall(handler[method], handler, ...)
-		if not success then
-			geterrorhandler()(ret)
-			return nil
-		end
-		if neg then
-			return not ret
-		end
-		return ret,ret2,ret3,ret4
-	elseif method == false then
-		return nil
-	end
-
-	Dewdrop:error("[%s] Missing %q directive in %q", tostring(settingname), methodName, v.name or "(unnamed)")
-end
-
-local function skip1Nil(...)
-	if select(1,...)==nil then
-		return select(2,...)
-	end
-	return ...
-end
-
-function Dewdrop:FeedAceOptionsTable(options, difference)
-	self:argCheck(options, 2, "table")
-	self:argCheck(difference, 3, "nil", "number")
-	if not currentLevel then
-		self:error("Cannot call `FeedAceOptionsTable' outside of a Dewdrop declaration")
-	end
-	if not difference then
-		difference = 0
-	end
-	if not validatedOptions then
-		validatedOptions = {}
-	end
-	if not validatedOptions[options] then
-		local err, position = validateOptions(options)
-
-		if err then
-			if position then
-				Dewdrop:error(position .. ": " .. err)
-			else
-				Dewdrop:error(err)
-			end
-		end
-
-		validatedOptions[options] = true
-	end
-	local level = levels[currentLevel]
-	if not level then
-		self:error("Improper level given")
-	end
-	if not values then
-		values = {}
-	else
-		for k,v in pairs(values) do
-			values[k] = nil
-		end
-	end
-
-	local current = level
-	while current do		-- this traverses from higher level numbers to lower, building "values" with leaf nodes first and trunk nodes later
-		if current.num == difference + 1 then
-			break
-		end
-		table.insert(values, current.value)
-		current = levels[current.num - 1]
-	end
-
-	local realOptions = options
-	local handler = options.handler
-	local passTable
-	local passValue
-	while #values > 0 do	-- This loop traverses values from the END (trunk nodes first, then onto leaf nodes)
-		if options.pass then
-			if options.get and options.set then
-				passTable = options
-			elseif not passTable then
-				passTable = options
-			end
-		else
-			passTable = nil
-		end
-		local value = table.remove(values)
-		options = options.args and options.args[value]
-		if not options then
-			return
-		end
-		handler = options.handler or handler
-		passValue = passTable and value or nil
-	end
-
-	if options.type == "group" then
-		local hidden = options.hidden
-		if type(hidden) == "function" or type(hidden) == "string" then
-			hidden = callMethod(options.name or "(options root)", handler, options, "hidden", options.passValue) or false
-		end
-		if hidden then
-			return
-		end
-		local disabled = options.disabled
-		if type(disabled) == "function" or type(disabled) == "string" then
-			disabled = callMethod(options.name or "(options root)", handler, options, "disabled", options.passValue) or false
-		end
-		if disabled then
-			self:AddLine(
-				'text', DISABLED,
-				'disabled', true
-			)
-			return
-		end
-		for k in pairs(options.args) do
-			table.insert(values, k)
-		end
-		if options.pass then
-			if options.get and options.set then
-				passTable = options
-			elseif not passTable then
-				passTable = options
-			end
-		else
-			passTable = nil
-		end
-		if not mysort then
-			mysort = function(a, b)
-				local alpha, bravo = mysort_args[a], mysort_args[b]
-				local alpha_order = alpha.order or 100
-				local bravo_order = bravo.order or 100
-				local alpha_name = alpha.guiName or alpha.name
-				local bravo_name = bravo.guiName or bravo.name
-				if alpha_order == bravo_order then
-					if not alpha_name then
-						return bravo_name
-					elseif not bravo_name then
-						return false
-					else
-						return alpha_name:gsub("|c%x%x%x%x%x%x%x%x", ""):gsub("|r", ""):upper() < bravo_name:gsub("|c%x%x%x%x%x%x%x%x", ""):gsub("|r", ""):upper()
-					end
-				else
-					if alpha_order < 0 then
-						if bravo_order > 0 then
-							return false
-						end
-					else
-						if bravo_order < 0 then
-							return true
-						end
-					end
-					return alpha_order < bravo_order
-				end
-			end
-		end
-		mysort_args = options.args
-		table.sort(values, mysort)
-		mysort_args = nil
-		local hasBoth = #values >= 1 and (options.args[values[1]].order or 100) > 0 and (options.args[values[#values]].order or 100) < 0
-		local last_order = 1
-		for _,k in ipairs(values) do
-			local v = options.args[k]
-			local handler = v.handler or handler
-			if hasBoth and last_order > 0 and (v.order or 100) < 0 then
-				hasBoth = false
-				self:AddLine()
-			end
-			local hidden, disabled = v.guiHidden or v.hidden, v.disabled
-
-			if type(hidden) == "function" or type(hidden) == "string" then
-				hidden = callMethod(k, handler, v, "hidden", v.passValue) or false
-			end
-			if not hidden then
-				if type(disabled) == "function" or type(disabled) == "string" then
-					disabled = callMethod(k, handler, v, "disabled", v.passValue) or false
-				end
-				local name = (v.guiIconOnly and v.icon) and "" or (v.guiName or v.name)
-				local desc = v.guiDesc or v.desc
-				local iconHeight = v.iconHeight or 16
-				local iconWidth = v.iconWidth or 16
-				local iconCoordLeft = v.iconCoordLeft
-				local iconCoordRight = v.iconCoordRight
-				local iconCoordBottom = v.iconCoordBottom
-				local iconCoordTop = v.iconCoordTop
-				local tooltipTitle, tooltipText
-				tooltipTitle = name
-				if name ~= desc then
-					tooltipText = desc
-				end
-				if type(v.usage) == "string" and v.usage:trim():len() > 0 then
-					if tooltipText then
-						tooltipText = tooltipText .. "\n\n" .. USAGE_TOOLTIP:format(v.usage)
-					else
-						tooltipText = USAGE_TOOLTIP:format(v.usage)
-					end
-				end
-				local v_p = passTable
-				if not v_p or (v.type ~= "execute" and v.get and v.set) or (v.type == "execute" and v.func) then
-					v_p = v
-				end
-				local passValue = v.passValue or (v_p~=v and k) or nil
-				if v.type == "toggle" then
-					local checked = callMethod(name, handler, v_p, "get", passValue) or false
-					local checked_arg = checked
-					if type(v_p.get)=="string" and v_p.get:match("^~") then
-						checked_arg = not checked
-					end
-					local func, arg1, arg2, arg3 = getMethod(name, handler, v_p, "set",   skip1Nil(passValue, not checked_arg))
-					if v.guiNameIsMap then
-						checked = checked and true or false
-						name = tostring(v.map and v.map[checked]):gsub("|c%x%x%x%x%x%x%x%x(.-)|r", "%1")
-						tooltipTitle = name
-						checked = true--nil
-					end
-					self:AddLine(
-						'text', name,
-						'checked', checked,
-						'isRadio', v.isRadio,
-						'func', func,
-						'arg1', arg1,
-						'arg2', arg2,
-						'arg3', arg3,
-						'disabled', disabled,
-						'tooltipTitle', tooltipTitle,
-						'tooltipText', tooltipText
-					)
-				elseif v.type == "execute" then
-					local func, arg1, arg2, arg3, arg4
-					local confirm = v.confirm
-					if confirm == true then
-						confirm = DEFAULT_CONFIRM_MESSAGE:format(tooltipText or tooltipTitle)
-						func,arg1,arg2,arg3,arg4 = confirmPopup, confirm, getMethod(name, handler, v_p, "func", passValue)
-					elseif type(confirm) == "string" then
-						func,arg1,arg2,arg3,arg4 = confirmPopup, confirm, getMethod(name, handler, v_p, "func", passValue)
-					else
-						func,arg1,arg2 = getMethod(name, handler, v_p, "func", passValue)
-					end
-					self:AddLine(
-						'text', name,
-						'checked', checked,
-						'func', func,
-						'arg1', arg1,
-						'arg2', arg2,
-						'arg3', arg3,
-						'arg4', arg4,
-						'disabled', disabled,
-						'tooltipTitle', tooltipTitle,
-						'tooltipText', tooltipText,
-						'icon', v.icon,
-						'iconHeight', iconHeight,
-						'iconWidth', iconWidth,
-						'iconCoordLeft', iconCoordLeft,
-						'iconCoordRight', iconCoordRight,
-						'iconCoordTop', iconCoordTop,
-						'iconCoordBottom', iconCoordBottom
-					)
-				elseif v.type == "range" then
-					local sliderValue
-					sliderValue = callMethod(name, handler, v_p, "get", passValue) or 0
-					local sliderFunc, sliderArg1, sliderArg2 = getMethod(name, handler, v_p, "set",    passValue)
-					if tooltipText then
-						tooltipText = format("%s\n\n%s", tooltipText, RANGE_TOOLTIP)
-					else
-						tooltipText = RANGE_TOOLTIP
-					end
-					self:AddLine(
-						'text', name,
-						'hasArrow', true,
-						'hasSlider', true,
-						'sliderMin', v.min or 0,
-						'sliderMax', v.max or 1,
-						'sliderStep', v.step or 0,
-						'sliderBigStep', v.bigStep or nil,
-						'sliderIsPercent', v.isPercent or false,
-						'sliderValue', sliderValue,
-						'sliderFunc', sliderFunc,
-						'sliderArg1', sliderArg1,
-						'sliderArg2', sliderArg2,
-						'fromAceOptions', true,
-						'disabled', disabled,
-						'tooltipTitle', tooltipTitle,
-						'tooltipText', tooltipText,
-						'icon', v.icon,
-						'iconHeight', iconHeight,
-						'iconWidth', iconWidth,
-						'iconCoordLeft', iconCoordLeft,
-						'iconCoordRight', iconCoordRight,
-						'iconCoordTop', iconCoordTop,
-						'iconCoordBottom', iconCoordBottom
-					)
-				elseif v.type == "color" then
-					local r,g,b,a = callMethod(name, handler, v_p, "get", passValue)
-					if not r then
-						r,g,b,a = 0,0,0,0
-					end
-					local colorFunc, colorArg1, colorArg2 = getMethod(name, handler, v_p, "set",    passValue)
-					self:AddLine(
-						'text', name,
-						'hasArrow', true,
-						'hasColorSwatch', true,
-						'r', r,
-						'g', g,
-						'b', b,
-						'opacity', v.hasAlpha and a or nil,
-						'hasOpacity', v.hasAlpha,
-						'colorFunc', colorFunc,
-						'colorArg1', colorArg1,
-						'colorArg2', colorArg2,
-						'disabled', disabled,
-						'tooltipTitle', tooltipTitle,
-						'tooltipText', tooltipText
-					)
-				elseif v.type == "text" then
-						if type(v.validate) == "table" then
-						local func,arg1,arg2
-						if v.onClick then
-							func,arg1,arg2 = getMethod(name, handler, v, "onClick",    passValue)
-						end
-						local checked
-						if v.isChecked then
-							checked = callMethod(name, handler, v, "isChecked",    passValue) or false
-						end
-						self:AddLine(
-							'text', name,
-							'hasArrow', true,
-							'value', k,
-							'func', func,
-							'arg1', arg1,
-							'arg2', arg2,
-							'mouseoverUnderline', func and true or nil,
-							'disabled', disabled,
-							'checked', checked,
-							'tooltipTitle', tooltipTitle,
-							'tooltipText', tooltipText,
-							'icon', v.icon,
-							'iconHeight', iconHeight,
-							'iconWidth', iconWidth,
-							'iconCoordLeft', iconCoordLeft,
-							'iconCoordRight', iconCoordRight,
-							'iconCoordTop', iconCoordTop,
-							'iconCoordBottom', iconCoordBottom
-						)
-					else
-						local editBoxText
-						editBoxText = callMethod(name, handler, v_p, "get", passValue) or ""
-						local editBoxFunc, editBoxArg1, editBoxArg2 = getMethod(name, handler, v_p, "set",    passValue)
-
-						local editBoxValidateFunc, editBoxValidateArg1
-
-						if v.validate and v.validate ~= "keybinding" then
-							if v.validate == "keybinding" then
-								if tooltipText then
-									tooltipText = format("%s\n\n%s", tooltipText, RESET_KEYBINDING_DESC)
-								else
-									tooltipText = RESET_KEYBINDING_DESC
-								end
-							else
-								editBoxValidateFunc, editBoxValidateArg1 = getMethod(name, handler, v, "validate") -- no passvalue!
-							end
-						end
-
-						self:AddLine(
-							'text', name,
-							'hasArrow', true,
-							'icon', v.icon,
-							'iconHeight', iconHeight,
-							'iconWidth', iconWidth,
-							'iconCoordLeft', iconCoordLeft,
-							'iconCoordRight', iconCoordRight,
-							'iconCoordTop', iconCoordTop,
-							'iconCoordBottom', iconCoordBottom,
-							'hasEditBox', true,
-							'editBoxText', editBoxText,
-							'editBoxFunc', editBoxFunc,
-							'editBoxArg1', editBoxArg1,
-							'editBoxArg2', editBoxArg2,
-							'editBoxValidateFunc', editBoxValidateFunc,
-							'editBoxValidateArg1', editBoxValidateArg1,
-							'editBoxIsKeybinding', v.validate == "keybinding",
-							'editBoxKeybindingOnly', v.keybindingOnly,
-							'editBoxKeybindingExcept', v.keybindingExcept,
-							'disabled', disabled,
-							'tooltipTitle', tooltipTitle,
-							'tooltipText', tooltipText
-						)
-					end
-				elseif v.type == "group" then
-					local func,arg1,arg2
-					if v.onClick then
-						func,arg1,arg2 = getMethod(name, handler, v, "onClick",    passValue)
-					end
-					local checked
-					if v.isChecked then
-						checked = callMethod(name, handler, v, "isChecked",    passValue) or false
-					end
-					self:AddLine(
-						'text', name,
-						'hasArrow', true,
-						'value', k,
-						'func', func,
-						'arg1', arg1,
-						'arg2', arg2,
-						'mouseoverUnderline', func and true or nil,
-						'disabled', disabled,
-						'checked', checked,
-						'tooltipTitle', tooltipTitle,
-						'tooltipText', tooltipText,
-						'icon', v.icon,
-						'iconHeight', iconHeight,
-						'iconWidth', iconWidth,
-						'iconCoordLeft', iconCoordLeft,
-						'iconCoordRight', iconCoordRight,
-						'iconCoordTop', iconCoordTop,
-						'iconCoordBottom', iconCoordBottom
-					)
-				elseif v.type == "header" then
-					if name == "" or not name then
-						self:AddLine(
-							'isTitle', true,
-							'icon', v.icon,
-							'iconHeight', iconHeight,
-							'iconWidth', iconWidth,
-							'iconCoordLeft', iconCoordLeft,
-							'iconCoordRight', iconCoordRight,
-							'iconCoordTop', iconCoordTop,
-							'iconCoordBottom', iconCoordBottom
-						)
-					else
-						self:AddLine(
-							'text', name,
-							'isTitle', true,
-							'icon', v.icon,
-							'iconHeight', iconHeight,
-							'iconWidth', iconWidth,
-							'iconCoordLeft', iconCoordLeft,
-							'iconCoordRight', iconCoordRight,
-							'iconCoordTop', iconCoordTop,
-							'iconCoordBottom', iconCoordBottom
-						)
-					end
-				end
-			end
-			last_order = v.order or 100
-		end
-	elseif options.type == "text" and type(options.validate) == "table" then
-		local current
-		local options_p = passTable
-		if not options_p or (options.get and options.set) then
-			options_p = options
-			passTable = nil
-			passValue = nil
-		end
-		local multiToggle = options.multiToggle
-		local passValue = options.passValue or passValue
-		if not multiToggle then
-			current = callMethod(k, handler, options_p, "get", passValue)
-		end
-		local indexed = true
-		for k,v in pairs(options.validate) do
-			if type(k) ~= "number" then
-				indexed = false
-			end
-			table.insert(values, k)
-		end
-		if not indexed then
-			if not othersort then
-				othersort = function(alpha, bravo)
-					return othersort_validate[alpha]:gsub("|c%x%x%x%x%x%x%x%x", ""):gsub("|r", ""):upper() < othersort_validate[bravo]:gsub("|c%x%x%x%x%x%x%x%x", ""):gsub("|r", ""):upper()
-				end
-			end
-			othersort_validate = options.validate
-			table.sort(values, othersort)
-			othersort_validate = nil
-		end
-		for _,k in ipairs(values) do
-			local v = options.validate[k]
-			if type(k) == "number" then
-				k = v
-			end
-			local func, arg1, arg2, arg3, arg4 = getMethod(k, handler, options_p, "set",    skip1Nil(passValue, k))
-			local checked
-			if multiToggle then
-				checked = callMethod(k, handler, options_p, "get", skip1Nil(passValue, k)) or false
-				if arg2 == nil then
-					arg2 = not checked
-				elseif arg3 == nil then
-					arg3 = not checked
-				else
-					arg4 = not checked
-				end
-			else
-				checked = (k == current or (type(k) == "string" and type(current) == "string" and k:lower() == current:lower()))
-				if checked then
-					func, arg1, arg2, arg3, arg4 = nil, nil, nil, nil, nil
-				end
-			end
-			local tooltipTitle
-			local tooltipText
-			if options.validateDesc then
-				tooltipTitle = v
-				tooltipText = options.validateDesc[k]
-			else
-				tooltipTitle = options.guiName or options.name
-				tooltipText = v
-			end
-			self:AddLine(
-				'text', v,
-				'func', func,
-				'arg1', arg1,
-				'arg2', arg2,
-				'arg3', arg3,
-				'arg4', arg4,
-				'isRadio', not multiToggle,
-				'checked',  checked,
-				'tooltipTitle', tooltipTitle,
-				'tooltipText', tooltipText
-			)
-		end
-		for k in pairs(values) do
-			values[k] = nil
-		end
-	else
-		return false
-	end
-	return true
-end
-
-function Dewdrop:FeedTable(s, difference)
-	self:argCheck(s, 2, "table")
-	self:argCheck(difference, 3, "nil", "number")
-	if not currentLevel then
-		self:error("Cannot call `FeedTable' outside of a Dewdrop declaration")
-	end
-	if not difference then
-		difference = 0
-	end
-	local level = levels[currentLevel]
-	if not level then
-		self:error("Improper level given")
-	end
-	if not values then
-		values = {}
-	else
-		for k,v in pairs(values) do
-			values[k] = nil
-		end
-	end
-	local t = s.subMenu and s or {subMenu = s}
-	local current = level
-	while current do
-		if current.num == difference + 1 then
-			break
-		end
-		table.insert(values, current.value)
-		current = levels[current.num - 1]
-	end
-
-	while #values > 0 do
-		local value = table.remove(values)
-		t = t.subMenu and t.subMenu[value]
-		if not t then
-			return
-		end
-	end
-
-	if t.subMenu or current.num == 1 then
-		for k in pairs(t.subMenu) do
-			table.insert(values, k)
-		end
-		table.sort(values)
-		for _,k in ipairs(values) do
-			local argTable = {"value", k}
-			for key, val in pairs(t.subMenu[k]) do
-				table.insert(argTable, key)
-				table.insert(argTable, val)
-			end
-			self:AddLine(unpack(argTable))
-		end
-		for k in pairs(values) do
-			values[k] = nil
-		end
-		return false
-	end
-	return true
-end
-
-function Refresh(self, level)
-	if type(level) == "number" then
-		level = levels[level]
-	end
-	if not level then
-		return
-	end
-	if baseFunc then
-		Clear(self, level)
-		currentLevel = level.num
-		if type(baseFunc) == "table" then
-			if currentLevel == 1 then
-				local handler = baseFunc.handler
-				if handler then
-					local name = tostring(handler)
-					if not name:find('^table:') and not handler.hideMenuTitle then
-						name = name:gsub("|c%x%x%x%x%x%x%x%x(.-)|r", "%1")
-						self:AddLine(
-							'text', name,
-							'isTitle', true
-						)
-					end
-				end
---			elseif level.parentText then
---				self:AddLine(
---					'text', level.parentText,
---					'tooltipTitle', level.parentTooltipTitle,
---					'tooltipText', level.parentTooltipText,
---					'tooltipFunc', level.parentTooltipFunc,
---					'isTitle', true
---				)
-			end
-			self:FeedAceOptionsTable(baseFunc)
-			if currentLevel == 1 then
-				self:AddLine(
-					'text', CLOSE,
-					'tooltipTitle', CLOSE,
-					'tooltipText', CLOSE_DESC,
-					'closeWhenClicked', true
-				)
-			end
-		else
---			if level.parentText then
---				self:AddLine(
---					'text', level.parentText,
---					'tooltipTitle', level.parentTooltipTitle,
---					'tooltipText', level.parentTooltipText,
---					'tooltipFunc', level.parentTooltipFunc,
---					'isTitle', true
---				)
---			end
-			baseFunc(currentLevel, level.value, levels[level.num - 1] and levels[level.num - 1].value, levels[level.num - 2] and levels[level.num - 2].value, levels[level.num - 3] and levels[level.num - 3].value, levels[level.num - 4] and levels[level.num - 4].value)
-		end
-		currentLevel = nil
-		CheckSize(self, level)
-	end
-end
-
-function Dewdrop:Refresh(level)
-	self:argCheck(level, 2, "number", "nil")
-	if not level then
-		for k,v in pairs(levels) do
-			Refresh(self, v)
-		end
-	else
-		Refresh(self, levels[level])
-	end
-end
-
-function OpenSlider(self, parent)
-	if not sliderFrame then
-		sliderFrame = CreateFrame("Frame", nil, nil)
-		sliderFrame:SetWidth(100)
-		sliderFrame:SetHeight(170)
-		sliderFrame:SetScale(UIParent:GetScale())
-		sliderFrame:SetBackdrop(tmp(
-			'bgFile', "Interface\\Tooltips\\UI-Tooltip-Background",
-			'edgeFile', "Interface\\Tooltips\\UI-Tooltip-Border",
-			'tile', true,
-			'insets', tmp2(
-				'left', 5,
-				'right', 5,
-				'top', 5,
-				'bottom', 5
-			),
-			'tileSize', 16,
-			'edgeSize', 16
-		))
-		sliderFrame:SetFrameStrata("FULLSCREEN_DIALOG")
-		if sliderFrame.SetTopLevel then
-			sliderFrame:SetTopLevel(true)
-		end
-		sliderFrame:SetBackdropBorderColor(TOOLTIP_DEFAULT_COLOR.r, TOOLTIP_DEFAULT_COLOR.g, TOOLTIP_DEFAULT_COLOR.b)
-		sliderFrame:SetBackdropColor(TOOLTIP_DEFAULT_BACKGROUND_COLOR.r, TOOLTIP_DEFAULT_BACKGROUND_COLOR.g, TOOLTIP_DEFAULT_BACKGROUND_COLOR.b)
-		sliderFrame:EnableMouse(true)
-		sliderFrame:EnableMouseWheel(true)
-		sliderFrame:Hide()
-		sliderFrame:SetPoint("CENTER", UIParent, "CENTER")
-		local slider = CreateFrame("Slider", nil, sliderFrame)
-		sliderFrame.slider = slider
-		slider:SetOrientation("VERTICAL")
-		slider:SetMinMaxValues(0, 1)
-		slider:SetValueStep(0.000000001)
-		slider:SetValue(0.5)
-		slider:SetWidth(16)
-		slider:SetHeight(128)
-		slider:SetPoint("LEFT", sliderFrame, "LEFT", 15, 0)
-		slider:SetBackdrop(tmp(
-			'bgFile', "Interface\\Buttons\\UI-SliderBar-Background",
-			'edgeFile', "Interface\\Buttons\\UI-SliderBar-Border",
-			'tile', true,
-			'edgeSize', 8,
-			'tileSize', 8,
-			'insets', tmp2(
-				'left', 3,
-				'right', 3,
-				'top', 3,
-				'bottom', 3
-			)
-		))
-		local texture = slider:CreateTexture()
-		slider:SetThumbTexture("Interface\\Buttons\\UI-SliderBar-Button-Vertical")
-		local text = slider:CreateFontString(nil, "ARTWORK")
-		sliderFrame.topText = text
-		text:SetFontObject(GameFontGreenSmall)
-		text:SetText("100%")
-		text:SetPoint("BOTTOM", slider, "TOP")
-		local text = slider:CreateFontString(nil, "ARTWORK")
-		sliderFrame.bottomText = text
-		text:SetFontObject(GameFontGreenSmall)
-		text:SetText("0%")
-		text:SetPoint("TOP", slider, "BOTTOM")
-		local editBox = CreateFrame("EditBox", nil, sliderFrame)
-		sliderFrame.currentText = editBox
-		editBox:SetFontObject(ChatFontNormal)
-		editBox:SetHeight(13)
-		editBox:SetPoint("RIGHT", sliderFrame, "RIGHT", -16, 0)
-		editBox:SetPoint("LEFT", slider, "RIGHT", 12, 0)
-		editBox:SetText("50%")
-		editBox:SetJustifyH("CENTER")
-
-		local width = editBox:GetWidth()/2 + 10
-		local left = editBox:CreateTexture(nil, "BACKGROUND")
-		left:SetTexture("Interface\\ChatFrame\\UI-ChatInputBorder-Left")
-		left:SetTexCoord(0, width / 256, 0, 1)
-		left:SetWidth(width)
-		left:SetHeight(32)
-		left:SetPoint("LEFT", editBox, "LEFT", -10, 0)
-		local right = editBox:CreateTexture(nil, "BACKGROUND")
-		right:SetTexture("Interface\\ChatFrame\\UI-ChatInputBorder-Right")
-		right:SetTexCoord(1 - width / 256, 1, 0, 1)
-		right:SetWidth(width)
-		right:SetHeight(32)
-		right:SetPoint("RIGHT", editBox, "RIGHT", 10, 0)
-
-		local changed = false
-		local inside = false
-		slider:SetScript("OnValueChanged", function()
-			if sliderFrame.changing then
-				return
-			end
-			changed = true
-			local done = false
-			if sliderFrame.parent and sliderFrame.parent.sliderFunc then
-				local min = sliderFrame.parent.sliderMin or 0
-				local max = sliderFrame.parent.sliderMax or 1
-				local step
-				if sliderFrame.fineStep then
-					step = sliderFrame.parent.sliderStep or (max - min) / 100
-				else
-					step = sliderFrame.parent.sliderBigStep or sliderFrame.parent.sliderStep or (max - min) / 100
-				end
-				local value = (1 - slider:GetValue()) * (max - min) + min
-				if step > 0 then
-					value = math.floor((value - min) / step + 0.5) * step + min
-					if value > max then
-						value = max
-					elseif value < min then
-						value = min
-					end
-				end
-				if value == sliderFrame.lastValue then
-					return
-				end
-				sliderFrame.lastValue = value
-				local text = sliderFrame.parent.sliderFunc(getArgs(sliderFrame.parent, 'sliderArg', 1, value))
-				if sliderFrame.parent.fromAceOptions then
-					text = nil
-				elseif type(text) == "string" or type(text) == "number" then
-					sliderFrame.currentText:SetText(text)
-					done = true
-				end
-			end
-			if not done then
-				local min = sliderFrame.parent.sliderMin or 0
-				local max = sliderFrame.parent.sliderMax or 1
-				local step
-				if sliderFrame.fineStep then
-					step = sliderFrame.parent.sliderStep or (max - min) / 100
-				else
-					step = sliderFrame.parent.sliderBigStep or sliderFrame.parent.sliderStep or (max - min) / 100
-				end
-				local value = (1 - slider:GetValue()) * (max - min) + min
-				if step > 0 then
-					value = math.floor((value - min) / step + 0.5) * step + min
-					if value > max then
-						value = max
-					elseif value < min then
-						value = min
-					end
-				end
-				if sliderFrame.parent.sliderIsPercent then
-					sliderFrame.currentText:SetText(string.format("%.0f%%", value * 100))
-				else
-					if step < 0.1 then
-						sliderFrame.currentText:SetText(string.format("%.2f", value))
-					elseif step < 1 then
-						sliderFrame.currentText:SetText(string.format("%.1f", value))
-					else
-						sliderFrame.currentText:SetText(string.format("%.0f", value))
-					end
-				end
-			end
-		end)
-		local function onEnter()
-			StopCounting(self, sliderFrame.level)
-			showGameTooltip(sliderFrame.parent)
-		end
-		local function onLeave()
-			GameTooltip:Hide()
-		end
-		sliderFrame:SetScript("OnEnter", onEnter)
-		sliderFrame:SetScript("OnLeave", function()
-			GameTooltip:Hide()
-			if changed then
-				local parent = sliderFrame.parent
-				local sliderFunc = parent.sliderFunc
-				for i = 1, sliderFrame.level - 1 do
-					Refresh(self, levels[i])
-				end
-				local newParent
-				for _,button in ipairs(levels[sliderFrame.level-1].buttons) do
-					if button.sliderFunc == sliderFunc then
-						newParent = button
-						break
-					end
-				end
-				if newParent then
-					OpenSlider(self, newParent)
-				else
-					sliderFrame:Hide()
-				end
-			end
-		end)
-		editBox:SetScript("OnEnter", onEnter)
-		editBox:SetScript("OnLeave", onLeave)
-		slider:SetScript("OnMouseDown", function()
-			sliderFrame.mouseDown = true
-			GameTooltip:Hide()
-		end)
-		slider:SetScript("OnMouseUp", function()
-			sliderFrame.mouseDown = false
-			if changed--[[ and not inside]] then
-				local parent = sliderFrame.parent
-				local sliderFunc = parent.sliderFunc
-				for i = 1, sliderFrame.level - 1 do
-					Refresh(self, levels[i])
-				end
-				local newParent
-				for _,button in ipairs(levels[sliderFrame.level-1].buttons) do
-					if button.sliderFunc == sliderFunc then
-						newParent = button
-						break
-					end
-				end
-				if newParent then
-					OpenSlider(self, newParent)
-				else
-					sliderFrame:Hide()
-				end
-			end
-			if inside then
-				showGameTooltip(sliderFrame.parent)
-			end
-		end)
-		slider:SetScript("OnEnter", function()
-			inside = true
-			StopCounting(self, sliderFrame.level)
-			showGameTooltip(sliderFrame.parent)
-		end)
-		slider:SetScript("OnLeave", function()
-			inside = false
-			GameTooltip:Hide()
-			if changed and not sliderFrame.mouseDown then
-				local parent = sliderFrame.parent
-				local sliderFunc = parent.sliderFunc
-				for i = 1, sliderFrame.level - 1 do
-					Refresh(self, levels[i])
-				end
-				local newParent
-				for _,button in ipairs(levels[sliderFrame.level-1].buttons) do
-					if button.sliderFunc == sliderFunc then
-						newParent = button
-						break
-					end
-				end
-				if newParent then
-					OpenSlider(self, newParent)
-				else
-					sliderFrame:Hide()
-				end
-
-				changed = false
-			end
-		end)
-		sliderFrame:SetScript("OnMouseWheel", function(t, a1)
-			local arg1 = a1 or arg1
-			local up = arg1 > 0
-
-			local min = sliderFrame.parent.sliderMin or 0
-			local max = sliderFrame.parent.sliderMax or 1
-			local step = sliderFrame.parent.sliderStep or (max - min) / 100
-			if step <= 0 then
-				step = (max - min) / 100
-			end
-
-			local value = (1 - slider:GetValue()) * (max - min) + min
-			if up then
-				value = value + step
-			else
-				value = value - step
-			end
-			if value > max then
-				value = max
-			elseif value < min then
-				value = min
-			end
-			sliderFrame.fineStep = true
-			if max<=min then
-				slider:SetValue(0)
-			else
-				slider:SetValue(1 - (value - min) / (max - min))
-			end
-			sliderFrame.fineStep = nil
-		end)
-		slider:SetScript("OnMouseWheel", sliderFrame:GetScript("OnMouseWheel"))
-		editBox:SetScript("OnEnterPressed", function(t, a1)
-			local value = editBox:GetNumber()
-
-			if sliderFrame.parent.sliderIsPercent then
-				value = value / 100
-			end
-
-			local min = sliderFrame.parent.sliderMin or 0
-			local max = sliderFrame.parent.sliderMax or 1
-
-			if value > max then
-				value = max
-			elseif value < min then
-				value = min
-			end
-			sliderFrame.fineStep = true
-			if max <= min then
-				slider:SetValue(0)
-			else
-				slider:SetValue(1 - (value - min) / (max - min))
-			end
-			sliderFrame.fineStep = nil
-
-			StartCounting(self, sliderFrame.level)
-		end)
-		editBox:SetScript("OnEscapePressed", function()
-			self:Close(sliderFrame.level)
-			StartCounting(self, sliderFrame.level)
-		end)
-		editBox:SetAutoFocus(false)
-	end
-	sliderFrame.parent = parent
-	sliderFrame.level = parent.level.num + 1
-	sliderFrame.parentValue = parent.level.value
-	sliderFrame:SetFrameLevel(parent.level:GetFrameLevel() + 3)
-	sliderFrame.slider:SetFrameLevel(sliderFrame:GetFrameLevel() + 1)
-	sliderFrame.currentText:SetFrameLevel(sliderFrame:GetFrameLevel() + 1)
-	sliderFrame.currentText:ClearFocus()
-	sliderFrame.changing = true
-	if not parent.sliderMin or not parent.sliderMax then
-		return
-	end
-
-	if parent.arrow then
---		parent.arrow:SetVertexColor(0.2, 0.6, 0)
---		parent.arrow:SetHeight(24)
---		parent.arrow:SetWidth(24)
-		parent.selected = true
-		parent.highlight:Show()
-	end
-
-	sliderFrame:SetClampedToScreen(false)
-	if not parent.sliderValue then
-		parent.sliderValue = (parent.sliderMin + parent.sliderMax) / 2
-	end
-	if parent.sliderMax <= parent.sliderMin then
-		sliderFrame.slider:SetValue(0)
-	else
-		sliderFrame.slider:SetValue(1 - (parent.sliderValue - parent.sliderMin) / (parent.sliderMax - parent.sliderMin))
-	end
-	sliderFrame.changing = false
-	sliderFrame.bottomText:SetText(parent.sliderMinText or "0")
-	sliderFrame.topText:SetText(parent.sliderMaxText or "1")
-	local text
-	if parent.sliderFunc and not parent.fromAceOptions then
-		text = parent.sliderFunc(getArgs(parent, 'sliderArg', 1, parent.sliderValue))
-	end
-	if type(text) == "number" or type(text) == "string" then
-		sliderFrame.currentText:SetText(text)
-	elseif parent.sliderIsPercent then
-		sliderFrame.currentText:SetText(string.format("%.0f%%", parent.sliderValue * 100))
-	else
-		if parent.sliderStep < 0.1 then
-			sliderFrame.currentText:SetText(string.format("%.2f", parent.sliderValue))
-		elseif parent.sliderStep < 1 then
-			sliderFrame.currentText:SetText(string.format("%.1f", parent.sliderValue))
-		else
-			sliderFrame.currentText:SetText(string.format("%.0f", parent.sliderValue))
-		end
-	end
-
-
-	sliderFrame.lastValue = parent.sliderValue
-
-	local level = parent.level
-	sliderFrame:Show()
-	sliderFrame:ClearAllPoints()
-	if level.lastDirection == "RIGHT" then
-		if level.lastVDirection == "DOWN" then
-			sliderFrame:SetPoint("TOPLEFT", parent, "TOPRIGHT", 5, 10)
-		else
-			sliderFrame:SetPoint("BOTTOMLEFT", parent, "BOTTOMRIGHT", 5, -10)
-		end
-	else
-		if level.lastVDirection == "DOWN" then
-			sliderFrame:SetPoint("TOPRIGHT", parent, "TOPLEFT", -5, 10)
-		else
-			sliderFrame:SetPoint("BOTTOMRIGHT", parent, "BOTTOMLEFT", -5, -10)
-		end
-	end
-	local dirty
-	if level.lastDirection == "RIGHT" then
-		if sliderFrame:GetRight() > GetScreenWidth() then
-			level.lastDirection = "LEFT"
-			dirty = true
-		end
-	elseif sliderFrame:GetLeft() < 0 then
-		level.lastDirection = "RIGHT"
-		dirty = true
-	end
-	if level.lastVDirection == "DOWN" then
-		if sliderFrame:GetBottom() < 0 then
-			level.lastVDirection = "UP"
-			dirty = true
-		end
-	elseif sliderFrame:GetTop() > GetScreenWidth() then
-		level.lastVDirection = "DOWN"
-		dirty = true
-	end
-	if dirty then
-		sliderFrame:ClearAllPoints()
-		if level.lastDirection == "RIGHT" then
-			if level.lastVDirection == "DOWN" then
-				sliderFrame:SetPoint("TOPLEFT", parent, "TOPRIGHT", 5, 10)
-			else
-				sliderFrame:SetPoint("BOTTOMLEFT", parent, "BOTTOMRIGHT", 5, -10)
-			end
-		else
-			if level.lastVDirection == "DOWN" then
-				sliderFrame:SetPoint("TOPRIGHT", parent, "TOPLEFT", -5, 10)
-			else
-				sliderFrame:SetPoint("BOTTOMRIGHT", parent, "BOTTOMLEFT", -5, -10)
-			end
-		end
-	end
-	local left, bottom = sliderFrame:GetLeft(), sliderFrame:GetBottom()
-	sliderFrame:ClearAllPoints()
-	sliderFrame:SetPoint("BOTTOMLEFT", UIParent, "BOTTOMLEFT", left, bottom)
-	if mod(level.num, 5) == 0 then
-		local left, bottom = level:GetLeft(), level:GetBottom()
-		level:ClearAllPoints()
-		level:SetPoint("BOTTOMLEFT", UIParent, "BOTTOMLEFT", left, bottom)
-	end
-	sliderFrame:SetClampedToScreen(true)
-end
-
-function OpenEditBox(self, parent)
-	if not editBoxFrame then
-		editBoxFrame = CreateFrame("Frame", nil, nil)
-		editBoxFrame:SetWidth(200)
-		editBoxFrame:SetHeight(40)
-		editBoxFrame:SetScale(UIParent:GetScale())
-		editBoxFrame:SetBackdrop(tmp(
-			'bgFile', "Interface\\Tooltips\\UI-Tooltip-Background",
-			'edgeFile', "Interface\\Tooltips\\UI-Tooltip-Border",
-			'tile', true,
-			'insets', tmp2(
-				'left', 5,
-				'right', 5,
-				'top', 5,
-				'bottom', 5
-			),
-			'tileSize', 16,
-			'edgeSize', 16
-		))
-		editBoxFrame:SetFrameStrata("FULLSCREEN_DIALOG")
-		if editBoxFrame.SetTopLevel then
-			editBoxFrame:SetTopLevel(true)
-		end
-		editBoxFrame:SetBackdropBorderColor(TOOLTIP_DEFAULT_COLOR.r, TOOLTIP_DEFAULT_COLOR.g, TOOLTIP_DEFAULT_COLOR.b)
-		editBoxFrame:SetBackdropColor(TOOLTIP_DEFAULT_BACKGROUND_COLOR.r, TOOLTIP_DEFAULT_BACKGROUND_COLOR.g, TOOLTIP_DEFAULT_BACKGROUND_COLOR.b)
-		editBoxFrame:EnableMouse(true)
-		editBoxFrame:EnableMouseWheel(true)
-		editBoxFrame:Hide()
-		editBoxFrame:SetPoint("CENTER", UIParent, "CENTER")
-
-		local editBox = CreateFrame("EditBox", nil, editBoxFrame)
-		editBoxFrame.editBox = editBox
-		editBox:SetFontObject(ChatFontNormal)
-		editBox:SetWidth(160)
-		editBox:SetHeight(13)
-		editBox:SetPoint("CENTER", editBoxFrame, "CENTER", 0, 0)
-
-		local left = editBox:CreateTexture(nil, "BACKGROUND")
-		left:SetTexture("Interface\\ChatFrame\\UI-ChatInputBorder-Left")
-		left:SetTexCoord(0, 100 / 256, 0, 1)
-		left:SetWidth(100)
-		left:SetHeight(32)
-		left:SetPoint("LEFT", editBox, "LEFT", -10, 0)
-		local right = editBox:CreateTexture(nil, "BACKGROUND")
-		right:SetTexture("Interface\\ChatFrame\\UI-ChatInputBorder-Right")
-		right:SetTexCoord(156/256, 1, 0, 1)
-		right:SetWidth(100)
-		right:SetHeight(32)
-		right:SetPoint("RIGHT", editBox, "RIGHT", 10, 0)
-
-		editBox:SetScript("OnEnterPressed", function()
-			if editBoxFrame.parent and editBoxFrame.parent.editBoxValidateFunc then
-				local t = editBox.realText or editBox:GetText() or ""
-				local result = editBoxFrame.parent.editBoxValidateFunc(getArgs(editBoxFrame.parent, 'editBoxValidateArg', 1, t))
-				if not result then
-					UIErrorsFrame:AddMessage(VALIDATION_ERROR, 1, 0, 0)
-					return
-				end
-			end
-			if editBoxFrame.parent and editBoxFrame.parent.editBoxFunc then
-				local t
-				if editBox.realText ~= "NONE" then
-					t = editBox.realText or editBox:GetText() or ""
-				end
-				editBoxFrame.parent.editBoxFunc(getArgs(editBoxFrame.parent, 'editBoxArg', 1, t))
-			end
-			self:Close(editBoxFrame.level)
-			for i = 1, editBoxFrame.level - 1 do
-				Refresh(self, levels[i])
-			end
-			StartCounting(self, editBoxFrame.level-1)
-		end)
-		editBox:SetScript("OnEscapePressed", function()
-			self:Close(editBoxFrame.level)
-			StartCounting(self, editBoxFrame.level-1)
-		end)
-		editBox:SetScript("OnReceiveDrag", function(this)
-			if GetCursorInfo then
-				local type, alpha, bravo = GetCursorInfo()
-				local text
-				if type == "spell" then
-					text = GetSpellName(alpha, bravo)
-				elseif type == "item" then
-					text = bravo
-				end
-				if not text then
-					return
-				end
-				ClearCursor()
-				editBox:SetText(text)
-			end
-		end)
-		local changing = false
-		local skipNext = false
-
-		function editBox:SpecialSetText(text)
-			local oldText = editBox:GetText() or ""
-			if not text then
-				text = ""
-			end
-			if text ~= oldText then
-				changing = true
-				self:SetText(tostring(text))
-				changing = false
-				skipNext = true
-			end
-		end
-
-		editBox:SetScript("OnTextChanged", function()
-			if skipNext then
-				skipNext = false
-			elseif not changing and editBoxFrame.parent and editBoxFrame.parent.editBoxChangeFunc then
-				local t
-				if editBox.realText ~= "NONE" then
-					t = editBox.realText or editBox:GetText() or ""
-				end
-				local text = editBoxFrame.parent.editBoxChangeFunc(getArgs(editBoxFrame.parent, 'editBoxChangeArg', 1, t))
-				if text then
-					editBox:SpecialSetText(text)
-				end
-			end
-		end)
-		editBoxFrame:SetScript("OnEnter", function()
-			StopCounting(self, editBoxFrame.level)
-			showGameTooltip(editBoxFrame.parent)
-		end)
-		editBoxFrame:SetScript("OnLeave", function()
-			GameTooltip:Hide()
-		end)
-		editBox:SetScript("OnEnter", function()
-			StopCounting(self, editBoxFrame.level)
-			showGameTooltip(editBoxFrame.parent)
-		end)
-		editBox:SetScript("OnLeave", function()
-			GameTooltip:Hide()
-		end)
-		editBoxFrame:SetScript("OnKeyDown", function(this, a1)
-			if not editBox.keybinding then
-				return
-			end
-			local arg1 = a1 or arg1
-			local screenshotKey = GetBindingKey("SCREENSHOT")
-			if screenshotKey and arg1 == screenshotKey then
-				Screenshot()
-				return
-			end
-
-			if arg1 == "LeftButton" then
-				arg1 = "BUTTON1"
-			elseif arg1 == "RightButton" then
-				arg1 = "BUTTON2"
-			elseif arg1 == "MiddleButton" then
-				arg1 = "BUTTON3"
-			elseif arg1 == "Button4" then
-				arg1 = "BUTTON4"
-			elseif arg1 == "Button5" then
-				arg1 = "BUTTON5"
-			end
-			if arg1 == "UNKNOWN" then
-				return
-			elseif arg1 == "SHIFT" or arg1 == "CTRL" or arg1 == "ALT" then
-				return
-			elseif arg1 == "ENTER" then
-				if editBox.keybindingOnly and not editBox.keybindingOnly[editBox.realText] then
-					return editBox:GetScript("OnEscapePressed")()
-				elseif editBox.keybindingExcept and editBox.keybindingExcept[editBox.realText] then
-					return editBox:GetScript("OnEscapePressed")()
-				else
-					return editBox:GetScript("OnEnterPressed")()
-				end
-			elseif arg1 == "ESCAPE" then
-				if editBox.realText == "NONE" then
-					return editBox:GetScript("OnEscapePressed")()
-				else
-					editBox:SpecialSetText(NONE or "NONE")
-					editBox.realText = "NONE"
-					return
-				end
-			elseif editBox.keybindingOnly and not editBox.keybindingOnly[arg1] then
-				return
-			elseif editBox.keybindingExcept and editBox.keybindingExcept[arg1] then
-				return
-			end
-			local s = GetBindingText(arg1, "KEY_")
-			if s == "BUTTON1" then
-				s = KEY_BUTTON1
-			elseif s == "BUTTON2" then
-				s = KEY_BUTTON2
-			end
-			local real = arg1
-			if IsShiftKeyDown() then
-				s = "Shift-" .. s
-				real = "SHIFT-" .. real
-			end
-			if IsControlKeyDown() then
-				s = "Ctrl-" .. s
-				real = "CTRL-" .. real
-			end
-			if IsAltKeyDown() then
-				s = "Alt-" .. s
-				real = "ALT-" .. real
-			end
-			if editBox:GetText() ~= s then
-				editBox:SpecialSetText("-")
-				editBox:SpecialSetText(s)
-				editBox.realText = real
-				return editBox:GetScript("OnTextChanged")()
-			end
-		end)
-		editBoxFrame:SetScript("OnMouseDown", editBoxFrame:GetScript("OnKeyDown"))
-		editBox:SetScript("OnMouseDown", function(this, ...)
-			if GetCursorInfo and (CursorHasItem() or CursorHasSpell()) then
-				return editBox:GetScript("OnReceiveDrag")(this, ...)
-			end
-			return editBoxFrame:GetScript("OnKeyDown")(this, ...)
-		end)
-		editBoxFrame:SetScript("OnMouseWheel", function(t, a1)
-			local arg1 = a1 or arg1
-			local up = arg1 > 0
-			arg1 = up and "MOUSEWHEELUP" or "MOUSEWHEELDOWN"
-			return editBoxFrame:GetScript("OnKeyDown")(t or this, arg1)
-		end)
-		editBox:SetScript("OnMouseWheel", editBoxFrame:GetScript("OnMouseWheel"))
-	end
-	editBoxFrame.parent = parent
-	editBoxFrame.level = parent.level.num + 1
-	editBoxFrame.parentValue = parent.level.value
-	editBoxFrame:SetFrameLevel(parent.level:GetFrameLevel() + 3)
-	editBoxFrame.editBox:SetFrameLevel(editBoxFrame:GetFrameLevel() + 1)
-	editBoxFrame.editBox.realText = nil
-	editBoxFrame:SetClampedToScreen(false)
-
-	editBoxFrame.editBox:SpecialSetText("")
-	if parent.editBoxIsKeybinding then
-		local s = parent.editBoxText
-		if s == "" then
-			s =  "NONE"
-		end
-		editBoxFrame.editBox.realText = s
-		if s and s ~= "NONE" then
-			local alpha,bravo = s:match("^(.+)%-(.+)$")
-			if not bravo then
-				alpha = nil
-				bravo = s
-			end
-			bravo = GetBindingText(bravo, "KEY_")
-			if alpha then
-				editBoxFrame.editBox:SpecialSetText(alpha:upper() .. "-" .. bravo)
-			else
-				editBoxFrame.editBox:SpecialSetText(bravo)
-			end
-		else
-			editBoxFrame.editBox:SpecialSetText(NONE or "NONE")
-		end
-	else
-		editBoxFrame.editBox:SpecialSetText(parent.editBoxText)
-	end
-
-	editBoxFrame.editBox.keybinding = parent.editBoxIsKeybinding
-	editBoxFrame.editBox.keybindingOnly = parent.editBoxKeybindingOnly
-	editBoxFrame.editBox.keybindingExcept = parent.editBoxKeybindingExcept
-	editBoxFrame.editBox:EnableKeyboard(not parent.editBoxIsKeybinding)
-	editBoxFrame:EnableKeyboard(parent.editBoxIsKeybinding)
-
-	if parent.arrow then
---		parent.arrow:SetVertexColor(0.2, 0.6, 0)
---		parent.arrow:SetHeight(24)
---		parent.arrow:SetWidth(24)
-		parent.selected = true
-		parent.highlight:Show()
-	end
-
-	local level = parent.level
-	editBoxFrame:Show()
-	editBoxFrame:ClearAllPoints()
-	if level.lastDirection == "RIGHT" then
-		if level.lastVDirection == "DOWN" then
-			editBoxFrame:SetPoint("TOPLEFT", parent, "TOPRIGHT", 5, 10)
-		else
-			editBoxFrame:SetPoint("BOTTOMLEFT", parent, "BOTTOMRIGHT", 5, -10)
-		end
-	else
-		if level.lastVDirection == "DOWN" then
-			editBoxFrame:SetPoint("TOPRIGHT", parent, "TOPLEFT", -5, 10)
-		else
-			editBoxFrame:SetPoint("BOTTOMRIGHT", parent, "BOTTOMLEFT", -5, -10)
-		end
-	end
-	local dirty
-	if level.lastDirection == "RIGHT" then
-		if editBoxFrame:GetRight() > GetScreenWidth() then
-			level.lastDirection = "LEFT"
-			dirty = true
-		end
-	elseif editBoxFrame:GetLeft() < 0 then
-		level.lastDirection = "RIGHT"
-		dirty = true
-	end
-	if level.lastVDirection == "DOWN" then
-		if editBoxFrame:GetBottom() < 0 then
-			level.lastVDirection = "UP"
-			dirty = true
-		end
-	elseif editBoxFrame:GetTop() > GetScreenWidth() then
-		level.lastVDirection = "DOWN"
-		dirty = true
-	end
-	if dirty then
-		editBoxFrame:ClearAllPoints()
-		if level.lastDirection == "RIGHT" then
-			if level.lastVDirection == "DOWN" then
-				editBoxFrame:SetPoint("TOPLEFT", parent, "TOPRIGHT", 5, 10)
-			else
-				editBoxFrame:SetPoint("BOTTOMLEFT", parent, "BOTTOMRIGHT", 5, -10)
-			end
-		else
-			if level.lastVDirection == "DOWN" then
-				editBoxFrame:SetPoint("TOPRIGHT", parent, "TOPLEFT", -5, 10)
-			else
-				editBoxFrame:SetPoint("BOTTOMRIGHT", parent, "BOTTOMLEFT", -5, -10)
-			end
-		end
-	end
-	local left, bottom = editBoxFrame:GetLeft(), editBoxFrame:GetBottom()
-	editBoxFrame:ClearAllPoints()
-	editBoxFrame:SetPoint("BOTTOMLEFT", UIParent, "BOTTOMLEFT", left, bottom)
-	if mod(level.num, 5) == 0 then
-		local left, bottom = level:GetLeft(), level:GetBottom()
-		level:ClearAllPoints()
-		level:SetPoint("BOTTOMLEFT", UIParent, "BOTTOMLEFT", left, bottom)
-	end
-	editBoxFrame:SetClampedToScreen(true)
-end
-
-function Dewdrop:EncodeKeybinding(text)
-	if text == nil or text == "NONE" then
-		return nil
-	end
-	text = tostring(text):upper()
-	local shift, ctrl, alt
-	local modifier
-	while true do
-		if text == "-" then
-			break
-		end
-		modifier, text = strsplit('-', text, 2)
-		if text then
-			if modifier ~= "SHIFT" and modifier ~= "CTRL" and modifier ~= "ALT" then
-				return false
-			end
-			if modifier == "SHIFT" then
-				if shift then
-					return false
-				end
-				shift = true
-			end
-			if modifier == "CTRL" then
-				if ctrl then
-					return false
-				end
-				ctrl = true
-			end
-			if modifier == "ALT" then
-				if alt then
-					return false
-				end
-				alt = true
-			end
-		else
-			text = modifier
-			break
-		end
-	end
-	if not text:find("^F%d+$") and text ~= "CAPSLOCK" and text:len() ~= 1 and (text:len() == 0 or text:byte() < 128 or text:len() > 4) and not _G["KEY_" .. text] and text ~= "BUTTON1" and text ~= "BUTTON2" then
-		return false
-	end
-	local s = GetBindingText(text, "KEY_")
-	if s == "BUTTON1" then
-		s = KEY_BUTTON1
-	elseif s == "BUTTON2" then
-		s = KEY_BUTTON2
-	end
-	if shift then
-		s = "Shift-" .. s
-	end
-	if ctrl then
-		s = "Ctrl-" .. s
-	end
-	if alt then
-		s = "Alt-" .. s
-	end
-	return s
-end
-
-function Dewdrop:IsOpen(parent)
-	self:argCheck(parent, 2, "table", "string", "nil")
-	return levels[1] and levels[1]:IsShown() and (not parent or parent == levels[1].parent or parent == levels[1]:GetParent())
-end
-
-function Dewdrop:GetOpenedParent()
-	return (levels[1] and levels[1]:IsShown()) and (levels[1].parent or levels[1]:GetParent())
-end
-
-function Open(self, parent, func, level, value, point, relativePoint, cursorX, cursorY)
-	self:Close(level)
-	if DewdropLib then
-		local d = DewdropLib:GetInstance('1.0')
-		local ret, val = pcall(d, IsOpen, d)
-		if ret and val then
-			DewdropLib:GetInstance('1.0'):Close()
-		end
-	end
-	if type(parent) == "table" then
-		parent:GetCenter()
-	end
-	local frame = AcquireLevel(self, level)
-	if level == 1 then
-		frame.lastDirection = "RIGHT"
-		frame.lastVDirection = "DOWN"
-	else
-		frame.lastDirection = levels[level - 1].lastDirection
-		frame.lastVDirection = levels[level - 1].lastVDirection
-	end
-	frame:SetFrameStrata("FULLSCREEN_DIALOG")
-	frame:ClearAllPoints()
-	frame.parent = parent
-	frame:SetPoint("LEFT", UIParent, "RIGHT", 10000, 0)
-	frame:Show()
-	if level == 1 then
-		baseFunc = func
-	end
-	levels[level].value = value
---	levels[level].parentText = parent.text and parent.text:GetText() or nil
---	levels[level].parentTooltipTitle = parent.tooltipTitle
---	levels[level].parentTooltipText = parent.tooltipText
---	levels[level].parentTooltipFunc = parent.tooltipFunc
-	if type(parent) == "table" and parent.arrow then
---		parent.arrow:SetVertexColor(0.2, 0.6, 0)
---		parent.arrow:SetHeight(24)
---		parent.arrow:SetWidth(24)
-		parent.selected = true
-		parent.highlight:Show()
-	end
-	relativePoint = relativePoint or point
-	Refresh(self, levels[level])
-	if point or (cursorX and cursorY) then
-		frame:ClearAllPoints()
-		if cursorX and cursorY then
-			local curX, curY = GetScaledCursorPosition()
-			if curY < GetScreenHeight() / 2 then
-				point, relativePoint = "BOTTOM", "BOTTOM"
-			else
-				point, relativePoint = "TOP", "TOP"
-			end
-			if curX < GetScreenWidth() / 2 then
-				point, relativePoint = point .. "LEFT", relativePoint .. "RIGHT"
-			else
-				point, relativePoint = point .. "RIGHT", relativePoint .. "LEFT"
-			end
-		end
-		frame:SetPoint(point, type(parent) == "table" and parent or UIParent, relativePoint)
-		if cursorX and cursorY then
-			local left = frame:GetLeft()
-			local width = frame:GetWidth()
-			local bottom = frame:GetBottom()
-			local height = frame:GetHeight()
-			local curX, curY = GetScaledCursorPosition()
-			frame:ClearAllPoints()
-			relativePoint = relativePoint or point
-			if point == "BOTTOM" or point == "TOP" then
-				if curX < GetScreenWidth() / 2 then
-					point = point .. "LEFT"
-				else
-					point = point .. "RIGHT"
-				end
-			elseif point == "CENTER" then
-				if curX < GetScreenWidth() / 2 then
-					point = "LEFT"
-				else
-					point = "RIGHT"
-				end
-			end
-			local xOffset, yOffset = 0, 0
-			if curY > GetScreenHeight() / 2 then
-				yOffset = -height
-			end
-			if curX > GetScreenWidth() / 2 then
-				xOffset = -width
-			end
-			frame:SetPoint(point, type(parent) == "table" and parent or UIParent, relativePoint, curX - left + xOffset, curY - bottom + yOffset)
-			if level == 1 then
-				frame.lastDirection = "RIGHT"
-			end
-		elseif cursorX then
-			local left = frame:GetLeft()
-			local width = frame:GetWidth()
-			local curX, curY = GetScaledCursorPosition()
-			frame:ClearAllPoints()
-			relativePoint = relativePoint or point
-			if point == "BOTTOM" or point == "TOP" then
-				if curX < GetScreenWidth() / 2 then
-					point = point .. "LEFT"
-				else
-					point = point .. "RIGHT"
-				end
-			elseif point == "CENTER" then
-				if curX < GetScreenWidth() / 2 then
-					point = "LEFT"
-				else
-					point = "RIGHT"
-				end
-			end
-			frame:SetPoint(point, type(parent) == "table" and parent or UIParent, relativePoint, curX - left - width / 2, 0)
-			if level == 1 then
-				frame.lastDirection = "RIGHT"
-			end
-		elseif cursorY then
-			local bottom = frame:GetBottom()
-			local height = frame:GetHeight()
-			local curX, curY = GetScaledCursorPosition()
-			frame:ClearAllPoints()
-			relativePoint = relativePoint or point
-			if point == "LEFT" or point == "RIGHT" then
-				if curX < GetScreenHeight() / 2 then
-					point = point .. "BOTTOM"
-				else
-					point = point .. "TOP"
-				end
-			elseif point == "CENTER" then
-				if curX < GetScreenHeight() / 2 then
-					point = "BOTTOM"
-				else
-					point = "TOP"
-				end
-			end
-			frame:SetPoint(point, type(parent) == "table" and parent or UIParent, relativePoint, 0, curY - bottom - height / 2)
-			if level == 1 then
-				frame.lastDirection = "DOWN"
-			end
-		end
-		if (strsub(point, 1, 3) ~= strsub(relativePoint, 1, 3)) then
-			if frame:GetBottom() < 0 then
-				local point, parent, relativePoint, x, y = frame:GetPoint(1)
-				local change = GetScreenHeight() - frame:GetTop()
-				local otherChange = -frame:GetBottom()
-				if otherChange < change then
-					change = otherChange
-				end
-				frame:SetPoint(point, parent, relativePoint, x, y + change)
-			elseif frame:GetTop() > GetScreenHeight() then
-				local point, parent, relativePoint, x, y = frame:GetPoint(1)
-				local change = GetScreenHeight() - frame:GetTop()
-				local otherChange = -frame:GetBottom()
-				if otherChange < change then
-					change = otherChange
-				end
-				frame:SetPoint(point, parent, relativePoint, x, y + change)
-			end
-		end
-	end
-	CheckDualMonitor(self, frame)
-	frame:SetClampedToScreen(true)
-	frame:SetClampedToScreen(false)
-	StartCounting(self, level)
-end
-
-function Dewdrop:IsRegistered(parent)
-	self:argCheck(parent, 2, "table", "string")
-	return not not self.registry[parent]
-end
-
-function Dewdrop:Register(parent, ...)
-	self:argCheck(parent, 2, "table", "string")
-	if self.registry[parent] then
-		self:Unregister(parent)
-	end
-	local info = new(...)
-	if type(info.children) == "table" then
-		local err, position = validateOptions(info.children)
-
-		if err then
-			if position then
-				Dewdrop:error(position .. ": " .. err)
-			else
-				Dewdrop:error(err)
-			end
-		end
-	end
-	self.registry[parent] = info
-	if not info.dontHook and not self.onceRegistered[parent] and type(parent) == "table" then
-		if parent:HasScript("OnMouseUp") then
-			local script = parent:GetScript("OnMouseUp")
-			parent:SetScript("OnMouseUp", function(this, ...)
-				if script then
-					script(this, ...)
-				end
-				if arg1 == "RightButton" and self.registry[parent] then
-					if self:IsOpen(parent) then
-						self:Close()
-					else
-						self:Open(parent)
-					end
-				end
-			end)
-		end
-		if parent:HasScript("OnMouseDown") then
-			local script = parent:GetScript("OnMouseDown")
-			parent:SetScript("OnMouseDown", function(this, ...)
-				if script then
-					script(this, ...)
-				end
-				if self.registry[parent] then
-					self:Close()
-				end
-			end)
-		end
-	end
-	self.onceRegistered[parent] = true
-end
-
-function Dewdrop:Unregister(parent)
-	self:argCheck(parent, 2, "table", "string")
-	self.registry[parent] = nil
-end
-
-function Dewdrop:Open(parent, ...)
-	self:argCheck(parent, 2, "table", "string")
-	local info
-	local k1 = ...
-	if type(k1) == "table" and k1[0] and k1.IsFrameType and self.registry[k1] then
-		info = tmp(select(2, ...))
-		for k,v in pairs(self.registry[k1]) do
-			if info[k] == nil then
-				info[k] = v
-			end
-		end
-	else
-		info = tmp(...)
-		if self.registry[parent] then
-			for k,v in pairs(self.registry[parent]) do
-				if info[k] == nil then
-					info[k] = v
-				end
-			end
-		end
-	end
-	local point = info.point
-	local relativePoint = info.relativePoint
-	local cursorX = info.cursorX
-	local cursorY = info.cursorY
-	if type(point) == "function" then
-		local b
-		point, b = point(parent)
-		if b then
-			relativePoint = b
-		end
-	end
-	if type(relativePoint) == "function" then
-		relativePoint = relativePoint(parent)
-	end
-	Open(self, parent, info.children, 1, nil, point, relativePoint, cursorX, cursorY)
-end
-
-function Clear(self, level)
-	if level then
-		if level.buttons then
-			for i = #level.buttons, 1, -1 do
-				ReleaseButton(self, level, i)
-			end
-		end
-	end
-end
-
-function Dewdrop:Close(level)
-	if DropDownList1:IsShown() then
-		DropDownList1:Hide()
-	end
-	if DewdropLib then
-		local d = DewdropLib:GetInstance('1.0')
-		local ret, val = pcall(d, IsOpen, d)
-		if ret and val then
-			DewdropLib:GetInstance('1.0'):Close()
-		end
-	end
-	self:argCheck(level, 2, "number", "nil")
-	if not level then
-		level = 1
-	end
-	if level == 1 and levels[level] then
-		levels[level].parented = false
-	end
-	if level > 1 and levels[level-1].buttons then
-		local buttons = levels[level-1].buttons
-		for _,button in ipairs(buttons) do
---			button.arrow:SetWidth(16)
---			button.arrow:SetHeight(16)
-			button.selected = nil
-			button.highlight:Hide()
---			button.arrow:SetVertexColor(1, 1, 1)
-		end
-	end
-	if sliderFrame and sliderFrame.level >= level then
-		sliderFrame:Hide()
-	end
-	if editBoxFrame and editBoxFrame.level >= level then
-		editBoxFrame:Hide()
-	end
-	for i = level, #levels do
-		Clear(self, levels[level])
-		levels[i]:Hide()
-		levels[i]:ClearAllPoints()
-		levels[i]:SetPoint("CENTER", UIParent, "CENTER")
-		levels[i].value = nil
-	end
-end
-
-function Dewdrop:AddSeparator(level)
-	level = levels[level or currentLevel]
-	if not level or not level.buttons then return; end
-
-	local prevbutton = level.buttons[#level.buttons]
-	if not prevbutton then return; end
-
-	if prevbutton.disabled and prevbutton.text:GetText() == "" then
-		return
-	end
-	self:AddLine("text", "", "disabled", true)
-end
-
-function Dewdrop:AddLine(...)
-	local info = tmp(...)
-	local level = info.level or currentLevel
-	info.level = nil
-	local button = AcquireButton(self, level)
-	if not next(info) then
-		info.disabled = true
-	end
-	button.disabled = info.isTitle or info.notClickable or info.disabled or (self.combat and info.secure)
-	button.isTitle = info.isTitle
-	button.notClickable = info.notClickable
-	if button.isTitle then
-		button.text:SetFontObject(GameFontNormalSmall)
-	elseif button.notClickable then
-		button.text:SetFontObject(GameFontHighlightSmall)
-	elseif button.disabled then
-		button.text:SetFontObject(GameFontDisableSmall)
-	else
-		button.text:SetFontObject(GameFontHighlightSmall)
-	end
-	if info.disabled then
-		button.arrow:SetDesaturated(true)
-		button.check:SetDesaturated(true)
-	else
-		button.arrow:SetDesaturated(false)
-		button.check:SetDesaturated(false)
-	end
-	if info.textR and info.textG and info.textB then
-		button.textR = info.textR
-		button.textG = info.textG
-		button.textB = info.textB
-		button.text:SetTextColor(button.textR, button.textG, button.textB)
-	else
-		button.text:SetTextColor(button.text:GetFontObject():GetTextColor())
-	end
-	button.notCheckable = info.notCheckable
-	button.text:SetPoint("LEFT", button, "LEFT", button.notCheckable and 0 or 24, 0)
-	button.checked = not info.notCheckable and info.checked
-	button.mouseoverUnderline = info.mouseoverUnderline
-	button.isRadio = not info.notCheckable and info.isRadio
-	if info.isRadio then
-		button.check:Show()
-		button.check:SetTexture(info.checkIcon or "Interface\\Buttons\\UI-RadioButton")
-		if button.checked then
-			button.check:SetTexCoord(0.25, 0.5, 0, 1)
-			button.check:SetVertexColor(1, 1, 1, 1)
-		else
-			button.check:SetTexCoord(0, 0.25, 0, 1)
-			button.check:SetVertexColor(1, 1, 1, 0.5)
-		end
-		button.radioHighlight:SetTexture(info.checkIcon or "Interface\\Buttons\\UI-RadioButton")
-		button.check:SetWidth(16)
-		button.check:SetHeight(16)
-	elseif info.icon then
-		button.check:Show()
-		button.check:SetTexture(info.icon)
-		if info.iconWidth and info.iconHeight then
-			button.check:SetWidth(info.iconWidth)
-			button.check:SetHeight(info.iconHeight)
-		else
-			button.check:SetWidth(16)
-			button.check:SetHeight(16)
-		end
-		if info.iconCoordLeft and info.iconCoordRight and info.iconCoordTop and info.iconCoordBottom then
-			button.check:SetTexCoord(info.iconCoordLeft, info.iconCoordRight, info.iconCoordTop, info.iconCoordBottom)
-		elseif info.icon:find("^Interface\\Icons\\") then
-			button.check:SetTexCoord(0.05, 0.95, 0.05, 0.95)
-		else
-			button.check:SetTexCoord(0, 1, 0, 1)
-		end
-		button.check:SetVertexColor(1, 1, 1, 1)
-	else
-		if button.checked then
-			if info.checkIcon then
-				button.check:SetWidth(16)
-				button.check:SetHeight(16)
-				button.check:SetTexture(info.checkIcon)
-				if info.checkIcon:find("^Interface\\Icons\\") then
-					button.check:SetTexCoord(0.05, 0.95, 0.05, 0.95)
-				else
-					button.check:SetTexCoord(0, 1, 0, 1)
-				end
-			else
-				button.check:SetWidth(24)
-				button.check:SetHeight(24)
-				button.check:SetTexture("Interface\\Buttons\\UI-CheckBox-Check")
-				button.check:SetTexCoord(0, 1, 0, 1)
-			end
-			button.check:SetVertexColor(1, 1, 1, 1)
-		else
-			button.check:SetVertexColor(1, 1, 1, 0)
-		end
-	end
-	if not button.disabled then
-		button.func = info.func
-		button.secure = info.secure
-	end
-	button.hasColorSwatch = info.hasColorSwatch
-	if button.hasColorSwatch then
-		button.colorSwatch:Show()
-		button.colorSwatch.texture:Show()
-		button.r = info.r or 1
-		button.g = info.g or 1
-		button.b = info.b or 1
-		button.colorSwatch.texture:SetVertexColor(button.r, button.g, button.b)
-		button.checked = false
-		button.func = nil
-		button.colorFunc = info.colorFunc
-		local i = 1
-		while true do
-			local k = "colorArg" .. i
-			local x = info[k]
-			if x == nil then
-				break
-			end
-			button[k] = x
-			i = i + 1
-		end
-		button.hasOpacity = info.hasOpacity
-		button.opacity = info.opacity or 1
-	else
-		button.colorSwatch:Hide()
-		button.colorSwatch.texture:Hide()
-	end
-	button.hasArrow = not button.hasColorSwatch and (info.value or info.hasSlider or info.hasEditBox) and info.hasArrow
-	if button.hasArrow then
-		button.arrow:SetAlpha(1)
-		if info.hasSlider then
-			button.hasSlider = true
-			button.sliderMin = info.sliderMin or 0
-			button.sliderMax = info.sliderMax or 1
-			button.sliderStep = info.sliderStep or 0
-			button.sliderBigStep = info.sliderBigStep or button.sliderStep
-			if button.sliderBigStep < button.sliderStep then
-				button.sliderBigStep = button.sliderStep
-			end
-			button.sliderIsPercent = info.sliderIsPercent and true or false
-			button.sliderMinText = info.sliderMinText or button.sliderIsPercent and string.format("%.0f%%", button.sliderMin * 100) or button.sliderMin
-			button.sliderMaxText = info.sliderMaxText or button.sliderIsPercent and string.format("%.0f%%", button.sliderMax * 100) or button.sliderMax
-			button.sliderFunc = info.sliderFunc
-			button.sliderValue = info.sliderValue
-			button.fromAceOptions = info.fromAceOptions
-			local i = 1
-			while true do
-				local k = "sliderArg" .. i
-				local x = info[k]
-				if x == nil then
-					break
-				end
-				button[k] = x
-				i = i + 1
-			end
-		elseif info.hasEditBox then
-			button.hasEditBox = true
-			button.editBoxText = info.editBoxText or ""
-			button.editBoxFunc = info.editBoxFunc
-			local i = 1
-			while true do
-				local k = "editBoxArg" .. i
-				local x = info[k]
-				if x == nil then
-					break
-				end
-				button[k] = x
-				i = i + 1
-			end
-			button.editBoxChangeFunc = info.editBoxChangeFunc
-			local i = 1
-			while true do
-				local k = "editBoxChangeArg" .. i
-				local x = info[k]
-				if x == nil then
-					break
-				end
-				button[k] = x
-				i = i + 1
-			end
-			button.editBoxValidateFunc = info.editBoxValidateFunc
-			local i = 1
-			while true do
-				local k = "editBoxValidateArg" .. i
-				local x = info[k]
-				if x == nil then
-					break
-				end
-				button[k] = x
-				i = i + 1
-			end
-			button.editBoxIsKeybinding = info.editBoxIsKeybinding
-			button.editBoxKeybindingOnly = info.editBoxKeybindingOnly
-			button.editBoxKeybindingExcept = info.editBoxKeybindingExcept
-		else
-			button.value = info.value
-			local l = levels[level+1]
-			if l and info.value == l.value then
---				button.arrow:SetWidth(24)
---				button.arrow:SetHeight(24)
-				button.selected = true
-				button.highlight:Show()
-			end
-		end
-	else
-		button.arrow:SetAlpha(0)
-	end
-	local i = 1
-	while true do
-		local k = "arg" .. i
-		local x = info[k]
-		if x == nil then
-			break
-		end
-		button[k] = x
-		i = i + 1
-	end
-	button.closeWhenClicked = info.closeWhenClicked
-	button.textHeight = info.textHeight or UIDROPDOWNMENU_DEFAULT_TEXT_HEIGHT or 10
-	local font,_ = button.text:GetFont()
-	button.text:SetFont(STANDARD_TEXT_FONT or "Fonts\\FRIZQT__.TTF", button.textHeight)
-	button:SetHeight(button.textHeight + 6)
-	button.text:SetPoint("RIGHT", button.arrow, (button.hasColorSwatch or button.hasArrow) and "LEFT" or "RIGHT")
-	button.text:SetJustifyH(info.justifyH or "LEFT")
-	button.text:SetText(info.text)
-	button.tooltipTitle = info.tooltipTitle
-	button.tooltipText = info.tooltipText
-	button.tooltipFunc = info.tooltipFunc
-	local i = 1
-	while true do
-		local k = "tooltipArg" .. i
-		local x = info[k]
-		if x == nil then
-			break
-		end
-		button[k] = x
-		i = i + 1
-	end
-	if not button.tooltipTitle and not button.tooltipText and not button.tooltipFunc and not info.isTitle then
-		button.tooltipTitle = info.text
-	end
-	if type(button.func) == "string" then
-		if type(button.arg1) ~= "table" then
-			self:error("Cannot call method %q on a non-table", button.func)
-		end
-		if type(button.arg1[button.func]) ~= "function" then
-			self:error("Method %q nonexistant.", button.func)
-		end
-	end
-end
-
-function Dewdrop:InjectAceOptionsTable(handler, options)
-	self:argCheck(handler, 2, "table")
-	self:argCheck(options, 3, "table")
-	if tostring(options.type):lower() ~= "group" then
-		self:error('Cannot inject into options table argument #3 if its type is not "group"')
-	end
-	if options.handler ~= nil and options.handler ~= handler then
-		self:error("Cannot inject into options table argument #3 if it has a different handler than argument #2")
-	end
-	options.handler = handler
-	local class = handler.class
-	if not AceLibrary:HasInstance("AceOO-2.0") or not class then
-		if Rock then
-			-- possible Rock object
-			for mixin in Rock:IterateObjectMixins(handler) do
-				if type(mixin.GetAceOptionsDataTable) == "function" then
-					local t = mixin:GetAceOptionsDataTable(handler)
-					for k,v in pairs(t) do
-						if type(options.args) ~= "table" then
-							options.args = {}
-						end
-						if options.args[k] == nil then
-							options.args[k] = v
-						end
-					end
-				end
-			end
-		end
-	else
-		-- Ace2 object
-		while class and class ~= AceLibrary("AceOO-2.0").Class do
-			if type(class.GetAceOptionsDataTable) == "function" then
-				local t = class:GetAceOptionsDataTable(handler)
-				for k,v in pairs(t) do
-					if type(options.args) ~= "table" then
-						options.args = {}
-					end
-					if options.args[k] == nil then
-						options.args[k] = v
-					end
-				end
-			end
-			local mixins = class.mixins
-			if mixins then
-				for mixin in pairs(mixins) do
-					if type(mixin.GetAceOptionsDataTable) == "function" then
-						local t = mixin:GetAceOptionsDataTable(handler)
-						for k,v in pairs(t) do
-							if type(options.args) ~= "table" then
-								options.args = {}
-							end
-							if options.args[k] == nil then
-								options.args[k] = v
-							end
-						end
-					end
-				end
-			end
-			class = class.super
-		end
-	end
-	return options
-end
-
-function Dewdrop:OnTooltipHide()
-	if lastSetFont then
-		if lastSetFont == normalFont then
-			lastSetFont = nil
-			return
-		end
-		fillRegionTmp(GameTooltip:GetRegions())
-		for i,v in ipairs(regionTmp) do
-			if v.GetFont then
-				local font,size,outline = v:GetFont()
-				if font == lastSetFont then
-					v:SetFont(normalFont, size, outline)
-				end
-			end
-			regionTmp[i] = nil
-		end
-		lastSetFont = nil
-	end
-end
-
-local function activate(self, oldLib, oldDeactivate)
-	Dewdrop = self
-	if oldLib and oldLib.registry then
-		self.registry = oldLib.registry
-		self.onceRegistered = oldLib.onceRegistered
-	else
-		self.registry = {}
-		self.onceRegistered = {}
-
-		local WorldFrame_OnMouseDown = WorldFrame:GetScript("OnMouseDown")
-		local WorldFrame_OnMouseUp = WorldFrame:GetScript("OnMouseUp")
-		local oldX, oldY, clickTime
-		WorldFrame:SetScript("OnMouseDown", function(this, ...)
-			oldX,oldY = GetCursorPosition()
-			clickTime = GetTime()
-			if WorldFrame_OnMouseDown then
-				WorldFrame_OnMouseDown(this, ...)
-			end
-		end)
-
-		WorldFrame:SetScript("OnMouseUp", function(this, ...)
-			local x,y = GetCursorPosition()
-			if not oldX or not oldY or not x or not y or not clickTime then
-				self:Close()
-				if WorldFrame_OnMouseUp then
-					WorldFrame_OnMouseUp(this, ...)
-				end
-				return
-			end
-			local d = math.abs(x - oldX) + math.abs(y - oldY)
-			if d <= 5 and GetTime() - clickTime < 0.5 then
-				self:Close()
-			end
-			if WorldFrame_OnMouseUp then
-				WorldFrame_OnMouseUp(this, ...)
-			end
-		end)
-
-		hooksecurefunc(DropDownList1, "Show", function()
-			if levels[1] and levels[1]:IsVisible() then
-				self:Close()
-			end
-		end)
-
-		hooksecurefunc("HideDropDownMenu", function()
-			if levels[1] and levels[1]:IsVisible() then
-				self:Close()
-			end
-		end)
-
-		hooksecurefunc("CloseDropDownMenus", function()
-			if levels[1] and levels[1]:IsVisible() then
-				local stack = debugstack()
-				if not stack:find("`TargetFrame_OnHide'") then
-					self:Close()
-				end
-			end
-		end)
-	end
-	self.frame = oldLib and oldLib.frame or CreateFrame("Frame")
-	self.frame:UnregisterAllEvents()
-	self.frame:RegisterEvent("PLAYER_REGEN_ENABLED")
-	self.frame:RegisterEvent("PLAYER_REGEN_DISABLED")
-	self.frame:Hide()
-	self.frame:SetScript("OnEvent", function(this, event)
-		this:Show()
-		if event=="PLAYER_REGEN_ENABLED" then			-- track combat state for secure frame operations
-			self.combat = false
-		elseif event=="PLAYER_REGEN_DISABLED" then
-			self.combat = true
-		end
-	end)
-	self.frame:SetScript("OnUpdate", function(this)
-		this:Hide()
-		self:Refresh(1)
-	end)
-	self.hookedTooltip = true
-	if not oldLib or not oldLib.hookedTooltip then
-		local OnTooltipHide = GameTooltip:GetScript("OnHide")
-		GameTooltip:SetScript("OnHide", function(this, ...)
-			if OnTooltipHide then
-				OnTooltipHide(this, ...)
-			end
-			if type(self.OnTooltipHide) == "function" then
-				self:OnTooltipHide()
-			end
-		end)
-	end
-	levels = {}
-	buttons = {}
-
-	if oldDeactivate then
-		oldDeactivate(oldLib)
-	end
-end
-
-local function external(lib, major, instance)
-	if major == "SharedMedia-1.0" then
-		SharedMedia = instance
-	end
-end
-
-AceLibrary:Register(Dewdrop, MAJOR_VERSION, MINOR_VERSION, activate, nil, external)
--- a/modules/FuBar_ReActionFu/lib/LibFuBarPlugin-3.0/Changelog-LibFuBarPlugin-3.0-r63707.txt	Wed Apr 02 23:44:06 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,25 +0,0 @@
-------------------------------------------------------------------------
-r63707 | arrowmaster | 2008-03-05 19:54:23 -0500 (Wed, 05 Mar 2008) | 1 line
-Changed paths:
-   M /trunk/LibFuBarPlugin-3.0/LibFuBarPlugin-3.0.lua
-
-LibFuBarPlugin-3.0: fix MINOR_VERSION to stop going negative
-------------------------------------------------------------------------
-r63318 | ckknight | 2008-03-01 12:59:56 -0500 (Sat, 01 Mar 2008) | 1 line
-Changed paths:
-   M /trunk/LibFuBarPlugin-3.0/LibFuBarPlugin-3.0.lua
-
-LibFuBarPlugin-3.0 - remove a pointless :OnEmbedProfileEnable
-------------------------------------------------------------------------
-r62709 | ckknight | 2008-02-23 21:15:11 -0500 (Sat, 23 Feb 2008) | 1 line
-Changed paths:
-   M /trunk/LibFuBarPlugin-3.0/LibFuBarPlugin-3.0.lua
-
-LibFuBarPlugin-3.0 - move around tricorner minimaps properly.
-------------------------------------------------------------------------
-r61479 | ckknight | 2008-02-15 12:18:37 -0500 (Fri, 15 Feb 2008) | 1 line
-Changed paths:
-   M /trunk/LibFuBarPlugin-3.0/LibFuBarPlugin-3.0.lua
-
-LibFuBarPlugin-3.0 - properly move around SIDE-TOP and SIDE-BOTTOM minimaps
-------------------------------------------------------------------------
--- a/modules/FuBar_ReActionFu/lib/LibFuBarPlugin-3.0/LibFuBarPlugin-3.0.lua	Wed Apr 02 23:44:06 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2145 +0,0 @@
---[[
-Name: LibFuBarPlugin-3.0
-Revision: $Rev: 63707 $
-Developed by: ckknight (ckknight@gmail.com)
-Website: http://www.wowace.com/
-Description: Plugin for FuBar.
-Dependencies: LibRock-1.0
-License: LGPL v2.1
-]]
-
-local MAJOR_VERSION = "LibFuBarPlugin-3.0"
-local MINOR_VERSION = tonumber(("$Revision: 63707 $"):match("(%d+)")) - 60000
-
-if not Rock then error(MAJOR_VERSION .. " requires LibRock-1.0") end
-
-local FuBarPlugin, oldLib = Rock:NewLibrary(MAJOR_VERSION, MINOR_VERSION)
-if not FuBarPlugin then
-	return
-end
-
-local SHOW_FUBAR_ICON = "Show FuBar icon"
-local SHOW_FUBAR_ICON_DESC = "Show the FuBar plugin's icon on the panel."
-local SHOW_FUBAR_TEXT = "Show FuBar text"
-local SHOW_FUBAR_TEXT_DESC = "Show the FuBar plugin's text on the panel."
-local SHOW_COLORED_FUBAR_TEXT = "Show colored FuBar text"
-local SHOW_COLORED_FUBAR_TEXT_DESC = "Allow the FuBar plugin to color its text on the panel."
-local DETACH_FUBAR_TOOLTIP = "Detach FuBar tooltip"
-local DETACH_FUBAR_TOOLTIP_DESC = "Detach the FuBar tooltip from the panel."
-local LOCK_FUBAR_TOOLTIP = "Lock tooltip"
-local LOCK_FUBAR_TOOLTIP_DESC = "Lock the tooltips position. When the tooltip is locked, you must use Alt to access it with your mouse."
-local POSITION_ON_FUBAR = "Position on FuBar"
-local POSITION_ON_FUBAR_DESC = "Position the FuBar plugin on the panel."
-local POSITION_LEFT = "Left"
-local POSITION_RIGHT = "Right"
-local POSITION_CENTER = "Center"
-local ATTACH_PLUGIN_TO_MINIMAP = "Attach FuBar plugin to minimap"
-local ATTACH_PLUGIN_TO_MINIMAP_DESC = "Attach the FuBar plugin to the minimap instead of the panel."
-local HIDE_FUBAR_PLUGIN = "Hide FuBar plugin"
-local HIDE_MINIMAP_BUTTON = "Hide minimap button"
-local HIDE_FUBAR_PLUGIN_DESC = "Hide the FuBar plugin from the panel or minimap, leaving the addon running."
-local OTHER = "Other"
-local CLOSE = "Close"
-local CLOSE_DESC = "Close the menu."
-
-if GetLocale() == "zhCN" then
-	SHOW_FUBAR_ICON = "显示FuBar图标"
-	SHOW_FUBAR_ICON_DESC = "在面板上显示FuBar插件的图标."
-	SHOW_FUBAR_TEXT = "显示FuBar文字"
-	SHOW_FUBAR_TEXT_DESC = "在面板上显示Fubar插件文字标题"
-	SHOW_COLORED_FUBAR_TEXT = "显示彩色文字"
-	SHOW_COLORED_FUBAR_TEXT_DESC = "允许插件显示彩色文字."
-	DETACH_FUBAR_TOOLTIP = "独立提示信息"
-	DETACH_FUBAR_TOOLTIP_DESC = "从面板上独立显示信息"
-	LOCK_FUBAR_TOOLTIP = "锁定提示信息"
-	LOCK_FUBAR_TOOLTIP_DESC = "锁定提示信息位置.当提示信息被锁定时,你必须要按Alt-鼠标方可查看."
-	POSITION_ON_FUBAR = "位置"
-	POSITION_ON_FUBAR_DESC = "FuBar插件在面板上的位置."
-	POSITION_LEFT = "居左"
-	POSITION_RIGHT = "居右"
-	POSITION_CENTER = "居中"
-	ATTACH_PLUGIN_TO_MINIMAP = "依附在小地图"
-	ATTACH_PLUGIN_TO_MINIMAP_DESC = "插件图标依附在小地图而不显示在面板上."
-	HIDE_FUBAR_PLUGIN = "隐藏FuBar插件"
-	HIDE_MINIMAP_BUTTON = "隐藏小地图按钮"
-	HIDE_FUBAR_PLUGIN_DESC = "隐藏在面板或小地图上的FuBar插件,暂定插件工作."
-	OTHER = "其他"
-	CLOSE = "关闭"
-	LOSE_DESC = "关闭目录."
-elseif GetLocale() == "zhTW" then
-	SHOW_FUBAR_ICON = "顯示圖示"
-	SHOW_FUBAR_ICON_DESC = "在面板上顯示插件圖示。"
-	SHOW_FUBAR_TEXT = "顯示文字"
-	SHOW_FUBAR_TEXT_DESC = "在面板上顯示插件文字。"
-	SHOW_COLORED_FUBAR_TEXT = "允許彩色文字"
-	SHOW_COLORED_FUBAR_TEXT_DESC = "允許插件在面板上使用彩色文字。"
-	DETACH_FUBAR_TOOLTIP = "獨立提示訊息"
-	DETACH_FUBAR_TOOLTIP_DESC = "從面板上獨立提示訊息。"
-	LOCK_FUBAR_TOOLTIP = "鎖定提示訊息"
-	LOCK_FUBAR_TOOLTIP_DESC = "鎖定提示訊息位置。當提示訊息鎖定時,需要用Alt鍵使用提示訊息的功能。"
-	POSITION_ON_FUBAR = "位置"
-	POSITION_ON_FUBAR_DESC = "插件在面板上的位置。"
-	POSITION_LEFT = "靠左"
-	POSITION_RIGHT = "靠右"
-	POSITION_CENTER = "置中"
-	ATTACH_PLUGIN_TO_MINIMAP = "依附在小地圖"
-	ATTACH_PLUGIN_TO_MINIMAP_DESC = "插件圖標依附在小地圖而不顯示在面板上。"
-	HIDE_FUBAR_PLUGIN = "隱藏插件"
-	HIDE_MINIMAP_BUTTON = "隱藏小地圖按鈕"
-	HIDE_FUBAR_PLUGIN_DESC = "在面板或小地圖上隱藏該插件,但保持執行狀態。"
-	OTHER = "其他"
-	CLOSE = "關閉"
-	CLOSE_DESC = "關閉選單。"
-elseif GetLocale() == "koKR" then
-	SHOW_FUBAR_ICON = "FuBar 아이콘 표시"
-	SHOW_FUBAR_ICON_DESC = "FuBar 패널에 플러그인 아이콘을 표시합니다."
-	SHOW_FUBAR_TEXT = "FuBar 텍스트 표시"
-	SHOW_FUBAR_TEXT_DESC = "FuBar 페널에 플러그인 텍스트를 표시합니다."
-	SHOW_COLORED_FUBAR_TEXT = "색상화된 FuBar 텍스트 표시"
-	SHOW_COLORED_FUBAR_TEXT_DESC = "패널의 FuBar 플러그인의 텍스트 색상을 허용합니다."
-	DETACH_FUBAR_TOOLTIP = "FuBar 툴팁 분리"
-	DETACH_FUBAR_TOOLTIP_DESC = "패널에서 FuBar 툴팁을 분리합니다."
-	LOCK_FUBAR_TOOLTIP = "툴팁 고정"
-	LOCK_FUBAR_TOOLTIP_DESC = "툴팁 위치를 고정시킵니다. 툴팁이 고정되어 있을때, 마우스로 접근하기 위해 Alt키를 사용하여야 합니다."
-	POSITION_ON_FUBAR = "FuBar 위치"
-	POSITION_ON_FUBAR_DESC = "패널 위의 FuBar 플러그인의 위치를 설정합니다."
-	POSITION_LEFT = "좌측"
-	POSITION_RIGHT = "우측"
-	POSITION_CENTER = "중앙"
-	ATTACH_PLUGIN_TO_MINIMAP = "FuBar 플러그인 미니맵 표시"
-	ATTACH_PLUGIN_TO_MINIMAP_DESC = "FuBar 플러그인을 패널 대신 미니맵에 표시합니다."
-	HIDE_FUBAR_PLUGIN = "FuBar 플러그인 숨김"
-	HIDE_MINIMAP_BUTTON = "미니맵 버튼 숨김"
-	HIDE_FUBAR_PLUGIN_DESC = "FuBar 플러그인을 패널이나 미니맵으로 부터 숨김니다."
-	OTHER = "기타"
-	CLOSE = "닫기"
-	CLOSE_DESC = "메뉴를 닫습니다."
-elseif GetLocale() == "frFR" then
-	SHOW_FUBAR_ICON = "Afficher l'icône FuBar"
-	SHOW_FUBAR_ICON_DESC = "Affiche l'icône du plugin FuBar sur le panneau."
-	SHOW_FUBAR_TEXT = "Afficher le texte FuBar"
-	SHOW_FUBAR_TEXT_DESC = "Affiche le texte du plugin FuBar sur le panneau."
-	SHOW_COLORED_FUBAR_TEXT = "Afficher le texte FuBar coloré"
-	SHOW_COLORED_FUBAR_TEXT_DESC = "Autorise le plugin FuBar à colorer son texte sur le panneau."
-	DETACH_FUBAR_TOOLTIP = "Détacher l'infobulle FuBar"
-	DETACH_FUBAR_TOOLTIP_DESC = "Détache l'infobulle FuBar du panneau."
-	LOCK_FUBAR_TOOLTIP = "Verrouiller l'infobulle"
-	LOCK_FUBAR_TOOLTIP_DESC = "Verrouille l'infobulle dans sa position actuelle. Quand l'infobulle est verrouillée, vous devez utiliser la touche Alt pour y interagir avec la souris."
-	POSITION_ON_FUBAR = "Position sur FuBar"
-	POSITION_ON_FUBAR_DESC = "Position du plugin FuBar sur le panneau."
-	POSITION_LEFT = "Gauche"
-	POSITION_RIGHT = "Droite"
-	POSITION_CENTER = "Centre"
-	ATTACH_PLUGIN_TO_MINIMAP = "Attacher le plugin FuBar sur la minicarte"
-	ATTACH_PLUGIN_TO_MINIMAP_DESC = "Attache le plugin FuBar sur la minicarte au lieu du panneau."
-	HIDE_FUBAR_PLUGIN = "Masquer le plugin FuBar"
-	HIDE_MINIMAP_BUTTON = "Masquer le bouton de la minicarte"
-	HIDE_FUBAR_PLUGIN_DESC = "Masque le plugin FuBar du panneau ou de la minicarte, laissant l'addon fonctionner."
-	OTHER = "Autre"
-	CLOSE = "Fermer"
-	CLOSE_DESC = "Ferme le menu."
-end
-
--- #AUTODOC_NAMESPACE FuBarPlugin
-
-local precondition, argCheck = Rock:GetContractFunctions(MAJOR_VERSION, "precondition", "argCheck")
-local newList, del = Rock:GetRecyclingFunctions(MAJOR_VERSION, "newList", "del")
-
-FuBarPlugin.pluginToFrame = oldLib and oldLib.pluginToFrame or {}
-local pluginToFrame = FuBarPlugin.pluginToFrame
-FuBarPlugin.pluginToMinimapFrame = oldLib and oldLib.pluginToMinimapFrame or {}
-local pluginToMinimapFrame = FuBarPlugin.pluginToMinimapFrame
-FuBarPlugin.pluginToPanel = oldLib and oldLib.pluginToPanel or {}
-local pluginToPanel = FuBarPlugin.pluginToPanel
-FuBarPlugin.pluginToOptions = oldLib and oldLib.pluginToOptions or {}
-local pluginToOptions = FuBarPlugin.pluginToOptions
-FuBarPlugin.folderNames = oldLib and oldLib.folderNames or {}
-local folderNames = FuBarPlugin.folderNames
-
-local Tablet20
-local Dewdrop20
-
-FuBarPlugin.MinimapContainer = oldLib and oldLib.MinimapContainer or {}
-local MinimapContainer = FuBarPlugin.MinimapContainer
-
-local epsilon = 1e-5
-
--- #AUTODOC_NAMESPACE FuBarPlugin
-
---[[---------------------------------------------------------------------------
-Notes:
-	*Set metadata about a certain plugin.
-	; tooltipType : string -
-	: "GameTooltip"
-	:: Use Blizzard's GameTooltip. (default if not given)
-	: "Tablet-2.0"
-	:: Use Tablet-2.0.
-	: "Custom"
-	:: LibFuBarPlugin-3.0 will not provide any extra mechanisms, all done manually.
-	; configType : string -
-	: "LibRockConfig-1.0"
-	:: Use LibRockConfig-1.0 to show configuration. (default if not given)
-	: "Dewdrop-2.0"
-	:: Use Dewdrop-2.0.
-	; hasNoText : boolean - If set to true, then it will be a text-less frame.
-	; iconPath : string - the path of the icon to show.
-	; hasNoColor : boolean - If set to true, then it is assumed that no color will be in the text (and thus not show the menu item)
-	; cannotHideText : boolean - If set to true, then the menu item to hide text will not be shown.
-	; overrideMenu : boolean - If set to true, then the menu will not show any of the standard menu items
-	; hideMenuTitle : boolean - If set to true, the plugins name will not be added to the top of the menu as a header.
-	; defaultPosition : string -
-	: "LEFT"
-	::show on the left. (default if not given)
-	: "CENTER"
-	::show in the center.
-	: "RIGHT"
-	::show on the right.
-	: "MINIMAP"
-	::show on the minimap.
-	; defaultMinimapPosition : number - Angle on the minimap, in degrees. [0, 360)
-	; clickableTooltip : boolean - Whether you can drag your mouse onto the tooltip and click a line
-	; tooltipHiddenWhenEmpty : boolean - Whether the detached tooltip is hidden when it is empty.
-	; cannotDetachTooltip : boolean - Whether the tooltip cannot be detached from the plugin text.
-	::Normally, a tooltip can detach (if using Tablet-2.0). This should be set if there is no relevant data in the tooltip.
-	; independentProfile : boolean - If set to true, then the profile setting will not be stripped from .OnMenuRequest, and FuBar will not set the plugin's profile when it changes.
-	::non-FuBar-centric plugins should set this to true.
-Arguments:
-	string - the key to set
-	value - the value to set said key to.
-Example:
-	self:SetFuBarOption('tooltipType', "Tablet-2.0")
------------------------------------------------------------------------------]]
-function FuBarPlugin:SetFuBarOption(key, value)
-	local pluginToOptions_self = pluginToOptions[self]
-	if not pluginToOptions_self then
-		pluginToOptions_self = {}
-		pluginToOptions[self] = pluginToOptions_self
-	end
-
-	pluginToOptions_self[key] = value
-
-	if key == 'tooltipType' then
-		if value == "Tablet-2.0" then
-			Tablet20 = Rock("Tablet-2.0", false, true)
-			if not Tablet20 then
-				error(("Cannot specify %q = %q if %q is not loaded."):format(key, value, value), 2)
-			end
-		end
-	end
-	if key == 'configType' then
-		if value == "Dewdrop-2.0" then
-			Dewdrop20 = Rock("Dewdrop-2.0", false, true)
-			if not Dewdrop20 then
-				error(("Cannot specify %q = %q if %q is not loaded."):format(key, value, value), 2)
-			end
-		end
-	end
-end
-precondition(FuBarPlugin, 'SetFuBarOption', function(self, key, value)
-	argCheck(self, 1, "table")
-	argCheck(key, 2, "string")
-	argCheck(value, 3, "string", "number", "boolean")
-
-	if pluginToOptions[self] and pluginToOptions[self][key] ~= nil then
-		error(("Bad argument #2 to `SetFuBarOption'. Cannot specify %q more than once."):format(key), 3)
-	end
-end)
-
-local function getPluginOption(object, key, default)
-	local pluginToOptions_object = pluginToOptions[object]
-	if pluginToOptions_object == nil then
-		return default
-	end
-	local value = pluginToOptions_object[key]
-	if value == nil then
-		return default
-	end
-	return value
-end
-
-local good = nil
-local function CheckFuBar()
-	if not good then
-		if FuBar then
-			local version = FuBar.version
-			if type(version) == "string" then
-			 	local num = version:match("^(%d+%.?%d*)")
-				if num then
-					num = tonumber(num)
-					good = num >= 3
-				end
-			end
-		end
-	end
-	return good
-end
-
---[[---------------------------------------------------------------------------
-Returns:
-	string - the localized name of the plugin, not including the "FuBar - " part.
-Example
-	local title = self:GetTitle()
------------------------------------------------------------------------------]]
-function FuBarPlugin:GetTitle()
-	local name = self.title or self.name
-	if type(name) ~= "string" then
-		error("You must provide self.title or self.name", 2)
-	end
-	local title = name:match("[Ff][Uu][Bb][Aa][Rr]%s*%-%s*(.-)%s*$") or name
-	return title:gsub("|c%x%x%x%x%x%x%x%x", ""):gsub("|r", "")
-end
-
---[[---------------------------------------------------------------------------
-Returns:
-	string - name of the plugin.
-Notes:
-	This is here for FuBar core to communicate properly.
-Example:
-	local name = self:GetName()
------------------------------------------------------------------------------]]
-function FuBarPlugin:GetName()
-	return self.name
-end
-
---[[---------------------------------------------------------------------------
-Returns:
-	string - category of the plugin.
-Notes:
-	This is here for FuBar core to communicate properly.
-Example:
-	local category = self:GetCategory()
------------------------------------------------------------------------------]]
-function FuBarPlugin:GetCategory()
-	return self.category or OTHER
-end
-
---[[---------------------------------------------------------------------------
-Returns:
-	frame - frame for the plugin.
-Notes:
-	This is here for FuBar core to communicate properly.
-Example:
-	local frame = self:GetFrame()
------------------------------------------------------------------------------]]
-function FuBarPlugin:GetFrame()
-	return pluginToFrame[self]
-end
-
---[[---------------------------------------------------------------------------
-Returns:
-	object - panel for the plugin.
-Notes:
-	This is here for FuBar core to communicate properly.
-Example:
-	local panel = self:GetPanel()
------------------------------------------------------------------------------]]
-function FuBarPlugin:GetPanel()
-	return pluginToPanel[self]
-end
-
-local function getLazyDatabaseValueDefault(object, value, ...)
-	local object_db = object.db
-	if type(object_db) ~= "table" then
-		return value
-	end
-	local current = object_db.profile
-	for i = 1, select('#', ...) do
-		-- traverse through, make sure tables exist.
-		if type(current) ~= "table" then
-			return value
-		end
-		current = current[(select(i, ...))]
-	end
-	if current == nil then
-		return value
-	else
-		return current
-	end
-end
-
-local function getLazyDatabaseValue(object, ...)
-	return getLazyDatabaseValueDefault(object, nil, ...)
-end
-
-local function setLazyDatabaseValue(object, value, ...)
-	local object_db = object.db
-	if type(object_db) ~= "table" then
-		return nil
-	end
-	local current = object_db.profile
-	if type(current) ~= "table" then
-		return nil
-	end
-	local n = select('#', ...)
-	for i = 1, n-1 do
-		-- traverse through, create tables if necessary.
-		local nextOne = current[(select(i, ...))]
-		if type(nextOne) ~= "table" then
-			if nextOne ~= nil then
-				return nil
-			end
-			nextOne = {}
-			current[(select(i, ...))] = nextOne
-		end
-		current = nextOne
-	end
-	current[select(n, ...)] = value
-	return true
-end
-
---[[---------------------------------------------------------------------------
-Returns:
-	boolean - whether the text has color applied.
-Example:
-	local colored = self:IsFuBarTextColored()
------------------------------------------------------------------------------]]
-function FuBarPlugin:IsFuBarTextColored()
-	return not getLazyDatabaseValue(self, 'uncolored')
-end
-
---[[---------------------------------------------------------------------------
-Notes:
-	Toggles whether the text has color applied
-Example:
-	self:ToggleTextColored()
------------------------------------------------------------------------------]]
-function FuBarPlugin:ToggleFuBarTextColored()
-	if not setLazyDatabaseValue(self, not getLazyDatabaseValue(self, 'uncolored') or nil, 'uncolored') then
-		error(("%s: Cannot change text color if self.db is not available."):format(self:GetTitle()), 2)
-	end
-	self:UpdateFuBarText()
-end
-
---[[---------------------------------------------------------------------------
-Returns:
-	boolean - whether the plugin is attached to the minimap.
-Example:
-	local attached = self:IsMinimapAttached()
------------------------------------------------------------------------------]]
-function FuBarPlugin:IsFuBarMinimapAttached()
-	if not CheckFuBar() then
-		return true
-	end
-	return pluginToPanel[self] == MinimapContainer
-end
-
---[[---------------------------------------------------------------------------
-Notes:
-	Toggles whether the plugin is attached to the minimap.
-Example:
-	self:ToggleMinimapAttached()
------------------------------------------------------------------------------]]
-function FuBarPlugin:ToggleFuBarMinimapAttached()
-	if CheckFuBar() and not getPluginOption(self, 'cannotAttachToMinimap', false) then
-		local panel = pluginToPanel[self]
-		local value = panel == MinimapContainer
-		if value then
-			panel:RemovePlugin(self)
-			local defaultPosition = getPluginOption(self, 'defaultPosition', "LEFT")
-			FuBar:GetPanel(1):AddPlugin(self, nil, defaultPosition == "MINIMAP" and "LEFT" or defaultPosition)
-		else
-			if panel then
-				panel:RemovePlugin(self)
-			end
-			MinimapContainer:AddPlugin(self)
-		end
-	end
-end
-
---[[---------------------------------------------------------------------------
-Notes:
-	Calls :UpdateFuBarText() and :UpdateFuBarTooltip(), in that order.
-Example:
-	self:UpdateFuBarPlugin()
------------------------------------------------------------------------------]]
-function FuBarPlugin:UpdateFuBarPlugin()
-	self:UpdateFuBarText()
-	self:UpdateFuBarTooltip()
-end
-
---[[---------------------------------------------------------------------------
-Notes:
-	* Calls :OnUpdateFuBarText() if it is available and the plugin is not disabled.
-	* It is expected to update the icon in :OnUpdateFuBarText as well as text.
-Example:
-	self:UpdateFuBarText()
------------------------------------------------------------------------------]]
-function FuBarPlugin:UpdateFuBarText()
-	if type(self.OnUpdateFuBarText) == "function" then
-		if not self:IsDisabled() then
-			self:OnUpdateFuBarText()
-		end
-	elseif self:IsFuBarTextShown() then
-		self:SetFuBarText(self:GetTitle())
-	end
-end
-
-local function Tablet20_point(frame)
-	if frame:GetTop() > GetScreenHeight() / 2 then
-		local x = frame:GetCenter()
-		if x < GetScreenWidth() / 3 then
-			return "TOPLEFT", "BOTTOMLEFT"
-		elseif x < GetScreenWidth() * 2 / 3 then
-			return "TOP", "BOTTOM"
-		else
-			return "TOPRIGHT", "BOTTOMRIGHT"
-		end
-	else
-		local x = frame:GetCenter()
-		if x < GetScreenWidth() / 3 then
-			return "BOTTOMLEFT", "TOPLEFT"
-		elseif x < GetScreenWidth() * 2 / 3 then
-			return "BOTTOM", "TOP"
-		else
-			return "BOTTOMRIGHT", "TOPRIGHT"
-		end
-	end
-end
-
-local function RegisterTablet20(self)
-	local frame = pluginToFrame[self]
-	if not Tablet20:IsRegistered(frame) then
-		local db = getLazyDatabaseValue(self)
-		if db and not db.detachedTooltip then
-			db.detachedTooltip = {}
-		end
-		Tablet20:Register(frame,
-			'children', function()
-				Tablet20:SetTitle(self:GetTitle())
-				if type(self.OnUpdateFuBarTooltip) == "function" then
-					if not self:IsDisabled() then
-						self:OnUpdateFuBarTooltip()
-					end
-				end
-			end,
-			'clickable', getPluginOption(self, 'clickableTooltip', false),
-			'data', CheckFuBar() and FuBar.db.profile.tooltip or db and db.detachedTooltip or {},
-			'detachedData', db and db.detachedTooltip or {},
-			'point', Tablet20_point,
-			'menu', self.OnMenuRequest and function(level, value, valueN_1, valueN_2, valueN_3, valueN_4)
-				if level == 1 then
-					local name = tostring(self)
-					if not name:find('^table:') then
-						name = name:gsub("|c%x%x%x%x%x%x%x%x(.-)|r", "%1")
-						Rock("Dewdrop-2.0"):AddLine(
-							'text', name,
-							'isTitle', true
-						)
-					end
-				end
-				if type(self.OnMenuRequest) == "function" then
-					self:OnMenuRequest(level, value, true, valueN_1, valueN_2, valueN_3, valueN_4)
-				elseif type(self.OnMenuRequest) == "table" then
-					Rock("Dewdrop-2.0"):FeedAceOptionsTable(self.OnMenuRequest)
-				end
-			end,
-			'hideWhenEmpty', getPluginOption(self, 'tooltipHiddenWhenEmpty', false)
-		)
-		local func = pluginToFrame[self]:GetScript("OnEnter")
-		frame:SetScript("OnEnter", function(this, ...)
-			-- HACK
-			func(this, ...)
-
-			if FuBar and FuBar.IsHidingTooltipsInCombat and FuBar:IsHidingTooltipsInCombat() and InCombatLockdown() then
-				if Tablet20:IsAttached(this) then
-					Tablet20:Close(this)
-				end
-			end
-		end)
-	end
-end
-
---[[---------------------------------------------------------------------------
-Notes:
-	Calls :OnUpdateFuBarTooltip() if it is available, the plugin is not disabled, and the tooltip is shown.
-Example:
-	self:UpdateFuBarTooltip()
------------------------------------------------------------------------------]]
-function FuBarPlugin:UpdateFuBarTooltip()
-	local tooltipType = getPluginOption(self, 'tooltipType', "GameTooltip")
-
-	if tooltipType == "GameTooltip" then
-		local frame = self:IsFuBarMinimapAttached() and pluginToMinimapFrame[self] or pluginToFrame[self]
-		if not GameTooltip:IsOwned(frame) then
-			return
-		end
-		GameTooltip:Hide()
-
-		local anchor
-		if frame:GetTop() > GetScreenHeight() / 2 then
-			local x = frame:GetCenter()
-			if x < GetScreenWidth() / 2 then
-				anchor = "ANCHOR_BOTTOMRIGHT"
-			else
-				anchor = "ANCHOR_BOTTOMLEFT"
-			end
-		else
-			local x = frame:GetCenter()
-			if x < GetScreenWidth() / 2 then
-				anchor = "ANCHOR_TOPLEFT"
-			else
-				anchor = "ANCHOR_TOPRIGHT"
-			end
-		end
-		GameTooltip:SetOwner(frame, anchor)
-		if type(self.OnUpdateFuBarTooltip) == "function" and not self:IsDisabled() then
-			self:OnUpdateFuBarTooltip()
-		end
-		GameTooltip:Show()
-		return
-	elseif tooltipType == "Custom" then
-		if type(self.OnUpdateFuBarTooltip) == "function" and not self:IsDisabled() then
-			self:OnUpdateFuBarTooltip()
-		end
-		return
-	elseif tooltipType == "Tablet-2.0" then
-		RegisterTablet20(self)
-		if self:IsFuBarMinimapAttached() and not self:IsFuBarTooltipDetached() and pluginToMinimapFrame[self] then
-			Tablet20:Refresh(pluginToMinimapFrame[self])
-		else
-			Tablet20:Refresh(pluginToFrame[self])
-		end
-	elseif tooltipType == "None" then
-		return
-	else
-		error(("Unknown %s option for %q: %q"):format(MAJOR_VERSION, 'tooltipType', tostring(tooltipType)), 2)
-	end
-end
-
---[[---------------------------------------------------------------------------
-Notes:
-	Shows the plugin, enables the plugin if previously disabled, and calls :UpdateFuBarPlugin().
-Example:
-	self:Show()
------------------------------------------------------------------------------]]
-function FuBarPlugin:Show(panelId)
-	if pluginToFrame[self]:IsShown() or (pluginToMinimapFrame[self] and pluginToMinimapFrame[self]:IsShown()) then
-		return
-	end
-	if panelId ~= false then
-		setLazyDatabaseValue(self, nil, 'hidden')
-	end
-	if self.IsActive and not self:IsActive() then
-		self.panelIdTmp = panelId
-		self:ToggleActive()
-		self.panelIdTmp = nil
-		setLazyDatabaseValue(self, nil, 'disabled')
-	elseif not getLazyDatabaseValue(self, 'hidden') then
-		if panelId == 0 or not CheckFuBar() then
-			MinimapContainer:AddPlugin(self)
-		else
-			FuBar:ShowPlugin(self, panelId or self.panelIdTmp)
-		end
-		if not getPluginOption(self, 'userDefinedFrame', false) then
-			if not self:IsFuBarTextShown() then
-				local text = pluginToFrame[self].text
-				text:SetText("")
-				text:SetWidth(epsilon)
-				text:Hide()
-			end
-			if not self:IsFuBarIconShown() then
-				local icon = pluginToFrame[self].icon
-				icon:SetWidth(epsilon)
-				icon:Hide()
-			end
-		end
-		self:UpdateFuBarPlugin()
-	end
-end
-
---[[---------------------------------------------------------------------------
-Notes:
-	Hides the plugin, disables the plugin if cannot hide without standby.
-Arguments:
-	[optional] boolean - internal variable. Do not set this.
-Example:
-	self:Hide()
------------------------------------------------------------------------------]]
-function FuBarPlugin:Hide(check)
-	if not pluginToFrame[self]:IsShown() and (not pluginToMinimapFrame[self] or not pluginToMinimapFrame[self]:IsShown()) then
-		return
-	end
-	local hideWithoutStandby = getPluginOption(self, 'hideWithoutStandby', false)
-	if hideWithoutStandby and check ~= false then
-		setLazyDatabaseValue(self, true, 'hidden')
-	end
-	if not hideWithoutStandby then
-		if getPluginOption(self, 'tooltipType', "GameTooltip") == "Tablet-2.0" and not getPluginOption(self, 'cannotDetachTooltip', false) and self:IsFuBarTooltipDetached() and getLazyDatabaseValue(self, 'detachedTooltip', 'detached') then
-			self:ReattachTooltip()
-			setLazyDatabaseValue(self, true, 'detachedTooltip', 'detached')
-		end
-		if self.IsActive and self:IsActive() and self.ToggleActive and (not CheckFuBar() or not FuBar:IsChangingProfile()) then
-			self:ToggleActive()
-		end
-	end
-	if pluginToPanel[self] then
-		pluginToPanel[self]:RemovePlugin(self)
-	end
-	pluginToFrame[self]:Hide()
-	if pluginToMinimapFrame[self] then
-		pluginToMinimapFrame[self]:Hide()
-	end
-end
-
---[[---------------------------------------------------------------------------
-Notes:
-	Sets the path to the icon for the plugin.
-Arguments:
-	string or nil - The path to the icon. If nil, then no icon.
-Example:
-	self:SetFuBarIcon("Interface\\AddOns\\MyAddon\\otherIcon")
------------------------------------------------------------------------------]]
-function FuBarPlugin:SetFuBarIcon(path)
-	if not path then
-		return
-	end
-	if not pluginToFrame[self] or not pluginToFrame[self].icon then
-		return
-	end
-	if path:match([[^Interface\Icons\]]) then
-		pluginToFrame[self].icon:SetTexCoord(0.05, 0.95, 0.05, 0.95)
-	else
-		pluginToFrame[self].icon:SetTexCoord(0, 1, 0, 1)
-	end
-	pluginToFrame[self].icon:SetTexture(path)
-	if pluginToMinimapFrame[self] and pluginToMinimapFrame[self].icon then
-		if path:match([[^Interface\Icons\]]) then
-			pluginToMinimapFrame[self].icon:SetTexCoord(0.05, 0.95, 0.05, 0.95)
-		else
-			pluginToMinimapFrame[self].icon:SetTexCoord(0, 1, 0, 1)
-		end
-		pluginToMinimapFrame[self].icon:SetTexture(path)
-	end
-end
-precondition(FuBarPlugin, 'SetFuBarIcon', function(self, path)
-	if not path then
-		return
-	end
-	argCheck(path, 2, "string", "nil")
-	if not getPluginOption(self, 'iconPath', false) then
-		error(("%s: Cannot set icon unless 'iconPath' is set."):format(self:GetTitle()), 3)
-	end
-end)
-
---[[---------------------------------------------------------------------------
-Returns:
-	string or nil - The path to the icon for the plugin. If nil, then no icon.
-Example:
-	local path = self:GetFuBarIcon()
------------------------------------------------------------------------------]]
-function FuBarPlugin:GetFuBarIcon()
-	if getPluginOption(self, 'iconPath', false) then
-		return pluginToFrame[self] and pluginToFrame[self].icon and pluginToFrame[self].icon:GetTexture()
-	end
-end
-
---[[---------------------------------------------------------------------------
-Notes:
-	Checks the current width of the icon and text, then updates frame to expand/shrink to it if necessary.
-Arguments:
-	[optional] boolean - if true, Shrink/expand no matter what, otherwise if the width is less than 8 pixels smaller, don't shrink.
-Example:
-	self:CheckWidth(true)
------------------------------------------------------------------------------]]
-function FuBarPlugin:CheckWidth(force)
-	local frame = pluginToFrame[self]
-	if not frame then
-		return
-	end
-	local icon = frame.icon
-	local text = frame.text
-	if (not icon or not icon:IsShown()) and (not text or not text:IsShown()) then
-		return
-	end
-
-	local db = getLazyDatabaseValue(self)
-
-	if (db and not self:IsFuBarIconShown()) or not getPluginOption(self, 'iconPath', false) then
-		icon:SetWidth(epsilon)
-	end
-	local width
-	if not getPluginOption(self, 'hasNoText', false) then
-		text:SetHeight(0)
-		text:SetWidth(500)
-		width = text:GetStringWidth() + 1
-		text:SetWidth(width)
-		text:SetHeight(text:GetHeight())
-	end
-	local panel = pluginToPanel[self]
-	if getPluginOption(self, 'hasNoText', false) or not text:IsShown() then
-		frame:SetWidth(icon:GetWidth())
-		if panel and panel:GetPluginSide(self) == "CENTER" then
-			panel:UpdateCenteredPosition()
-		end
-	elseif force or not frame.textWidth or frame.textWidth < width or frame.textWidth - 8 > width then
-		frame.textWidth = width
-		text:SetWidth(width)
-		if icon and icon:IsShown() then
-			frame:SetWidth(width + icon:GetWidth())
-		else
-			frame:SetWidth(width)
-		end
-		if panel and panel:GetPluginSide(self) == "CENTER" then
-			panel:UpdateCenteredPosition()
-		end
-	end
-end
-precondition(FuBarPlugin, 'CheckWidth', function(self, force)
-	argCheck(force, 2, "boolean", "nil")
-end)
-
---[[---------------------------------------------------------------------------
-Notes:
-	Sets the text of the plugin. Should only be called from within :OnFuBarUpdateText()
-Arguments:
-	string - text to set the plugin to. If not given, set to title.
-Example:
-	myAddon.OnFuBarUpdateText = function(self)
-		self:SetFuBarText("Hello")
-	fend
------------------------------------------------------------------------------]]
-function FuBarPlugin:SetFuBarText(text)
-	local frame = pluginToFrame[self]
-	if not frame or not frame.text then
-		return
-	end
-	if text == "" then
-		if getPluginOption(self, 'iconPath', false) then
-			self:ShowFuBarIcon()
-		else
-			text = self:GetTitle()
-		end
-	end
-	if not self:IsFuBarTextColored() then
-		text = text:gsub("|c%x%x%x%x%x%x%x%x", ""):gsub("|r", "")
-	end
-	frame.text:SetText(text)
-	self:CheckWidth()
-end
-precondition(FuBarPlugin, 'SetFuBarText', function(self, text)
-	local frame = pluginToFrame[self]
-	if not frame or not frame.text then
-		return
-	end
-	if getPluginOption(self, 'hasNoText', false) then
-		error(("%s: Cannot set text if 'hasNoText' has been set."):format(self:GetTitle()), 3)
-	end
-	argCheck(text, 2, "string", "number")
-end)
-
---[[---------------------------------------------------------------------------
-Returns:
-	string - The current text of the plugin.
-Example:
-	local text = self:GetFuBarText()
------------------------------------------------------------------------------]]
-function FuBarPlugin:GetFuBarText()
-	local frame = pluginToFrame[self]
-	if not frame or not frame.text then
-		error(("%s: Cannot get text without a text frame."):format(self:GetTitle()), 2)
-	end
-	if not getPluginOption(self, 'hasNoText', false) then
-		return frame.text:GetText() or ""
-	end
-end
-
---[[---------------------------------------------------------------------------
-Returns:
-	boolean - whether the icon for the plugin is showing.
-Example:
-	local isIconShowing = self:IsFuBarIconShown()
------------------------------------------------------------------------------]]
-function FuBarPlugin:IsFuBarIconShown()
-	if not getPluginOption(self, 'iconPath', false) then
-		return false
-	elseif getPluginOption(self, 'hasNoText', false) then
-		return true
-	end
-	return not not getLazyDatabaseValueDefault(self, true, 'showIcon')
-end
-
---[[---------------------------------------------------------------------------
-Notes:
-	Toggles whether the icon for the plugin is showing.
-Example:
-	self:ToggleFuBarIconShown()
------------------------------------------------------------------------------]]
-function FuBarPlugin:ToggleFuBarIconShown()
-	local frame = pluginToFrame[self]
-	local icon = frame and frame.icon
-	local text = frame and frame.text
-	if not icon then
-		error(("%s: Cannot toggle icon without an icon frame."):format(self:GetTitle()), 2)
-	elseif not text then
-		error(("%s: Cannot toggle icon without a text frame."):format(self:GetTitle()), 2)
-	elseif not getPluginOption(self, 'iconPath', false) then
-		error(("%s: Cannot show icon unless 'iconPath' is set."):format(self:GetTitle()), 2)
-	elseif getPluginOption(self, 'hasNoText', false) then
-		error(("%s: Cannot show icon if 'hasNoText' is set."):format(self:GetTitle()), 2)
-	elseif not getLazyDatabaseValue(self) then
-		error(("%s: Cannot hide icon if self.db is not available."):format(self:GetTitle()), 2)
-	end
-	local value = not self:IsFuBarIconShown()
-	setLazyDatabaseValue(self, value, 'showIcon')
-	if value then
-		if not self:IsFuBarTextShown() and text:IsShown() and text:GetText() == self:GetTitle() then
-			text:Hide()
-			text:SetText("")
-		end
-		icon:Show()
-		icon:SetWidth(pluginToFrame[self].icon:GetHeight())
-		self:UpdateFuBarText()
-	else
-		if not text:IsShown() or not text:GetText() or text:GetText() == "" then
-			text:Show()
-			text:SetText(self:GetTitle())
-		end
-		icon:Hide()
-		icon:SetWidth(epsilon)
-	end
-	self:CheckWidth(true)
-	return value
-end
-
---[[---------------------------------------------------------------------------
-Notes:
-	Shows the icon of the plugin if hidden.
-Example:
-	self:ShowFuBarIcon()
------------------------------------------------------------------------------]]
-function FuBarPlugin:ShowFuBarIcon()
-	if not self:IsFuBarIconShown() then
-		self:ToggleFuBarIconShown()
-	end
-end
-
---[[---------------------------------------------------------------------------
-Notes:
-	Hides the icon of the plugin if shown.
-Example:
-	self:HideFuBarIcon()
------------------------------------------------------------------------------]]
-function FuBarPlugin:HideFuBarIcon()
-	if self:IsFuBarIconShown() then
-		self:ToggleFuBarIconShown()
-	end
-end
-
---[[---------------------------------------------------------------------------
-Returns:
-	boolean - whether the text for the plugin is showing.
-Example:
-	local isTextShowing = self:IsFuBarTextShown()
------------------------------------------------------------------------------]]
-function FuBarPlugin:IsFuBarTextShown()
-	if getPluginOption(self, 'hasNoText', false) then
-		return false
-	elseif not getPluginOption(self, 'iconPath', false) then
-		return true
-	end
-	return not not getLazyDatabaseValueDefault(self, true, 'showText')
-end
-
---[[---------------------------------------------------------------------------
-Notes:
-	Toggles whether the text for the plugin is showing.
-Example:
-	self:ToggleFuBarTextShown()
------------------------------------------------------------------------------]]
-function FuBarPlugin:ToggleFuBarTextShown()
-	local frame = pluginToFrame[self]
-	local icon = frame and frame.icon
-	local text = frame and frame.text
-	if not icon then
-		error(("%s: Cannot toggle text without an icon frame."):format(self:GetTitle()), 2)
-	elseif not text then
-		error(("%s: Cannot toggle text without a text frame."):format(self:GetTitle()), 2)
-	elseif getPluginOption(self, 'cannotHideText', false) then
-		error(("%s: Cannot toggle text if 'cannotHideText' is set."):format(self:GetTitle()), 2)
-	elseif not getPluginOption(self, 'iconPath', false) then
-		error(("%s: Cannot toggle text unless 'iconPath' is set."):format(self:GetTitle()), 2)
-	elseif getPluginOption(self, 'hasNoText', false) then
-		error(("%s: Cannot toggle text if 'hasNoText' is set."):format(self:GetTitle()), 2)
-	elseif not getLazyDatabaseValue(self) then
-		error(("%s: Cannot toggle text if self.db is not available."):format(self:GetTitle()), 2)
-	end
-	local value = not self:IsFuBarTextShown()
-	setLazyDatabaseValue(self, value, 'showText')
-	if value then
-		text:Show()
-		self:UpdateFuBarText()
-	else
-		text:SetText("")
-		text:SetWidth(epsilon)
-		text:Hide()
-		self:ShowFuBarIcon()
-	end
-	self:CheckWidth(true)
-	return value
-end
-
---[[---------------------------------------------------------------------------
-Notes:
-	Shows the text of the plugin if hidden.
-Example:
-	self:ShowFuBarText()
------------------------------------------------------------------------------]]
-function FuBarPlugin:ShowFuBarText()
-	if not self:IsFuBarTextShown() then
-		self:ToggleFuBarTextShown()
-	end
-end
-
---[[---------------------------------------------------------------------------
-Notes:
-	Hides the text of the plugin if shown.
-Example:
-	self:HideFuBarText()
------------------------------------------------------------------------------]]
-function FuBarPlugin:HideFuBarText()
-	if self:IsFuBarTextShown() then
-		self:ToggleFuBarTextShown()
-	end
-end
-
---[[---------------------------------------------------------------------------
-Returns:
-	string - default position of the plugin.
-Notes:
-	This is here for FuBar core to communicate properly.
-Example:
-	local pos = self:GetDefaultPosition()
------------------------------------------------------------------------------]]
-function FuBarPlugin:GetDefaultPosition()
-	return getPluginOption(self, 'defaultPosition', "LEFT")
-end
-
---[[---------------------------------------------------------------------------
-Returns:
-	boolean - Whether the tooltip is detached.
-Example:
-	local detached = self:IsFuBarTooltipDetached()
------------------------------------------------------------------------------]]
-function FuBarPlugin:IsFuBarTooltipDetached()
-	local tooltipType = getPluginOption(self, 'tooltipType', "GameTooltip")
-	if tooltipType ~= "Tablet-2.0" then
-		return
-	end
-
-	RegisterTablet20(self)
-	return not Tablet20:IsAttached(pluginToFrame[self])
-end
-
---[[---------------------------------------------------------------------------
-Notes:
-	Toggles whether the tooltip is detached.
-Example:
-	self:ToggleFuBarTooltipDetached()
------------------------------------------------------------------------------]]
-function FuBarPlugin:ToggleFuBarTooltipDetached()
-	local tooltipType = getPluginOption(self, 'tooltipType', "GameTooltip")
-	if tooltipType ~= "Tablet-2.0" then
-		return
-	end
-
-	RegisterTablet20(self)
-	if Tablet20:IsAttached(pluginToFrame[self]) then
-		Tablet20:Detach(pluginToFrame[self])
-	else
-		Tablet20:Attach(pluginToFrame[self])
-	end
-end
-
---[[---------------------------------------------------------------------------
-Notes:
-	* Detaches the tooltip from the plugin.
-	* This does nothing if already detached.
-Example:
-	self:DetachFuBarTooltip()
------------------------------------------------------------------------------]]
-function FuBarPlugin:DetachFuBarTooltip()
-	if not self:IsFuBarTooltipDetached() then
-		self:ToggleFuBarTooltipDetached()
-	end
-end
-
---[[---------------------------------------------------------------------------
-Notes:
-	Reattaches the tooltip to the plugin.
-	This does nothing if already attached.
-Example:
-	self:ReattachFuBarTooltip()
------------------------------------------------------------------------------]]
-function FuBarPlugin:ReattachFuBarTooltip()
-	if self:IsFuBarTooltipDetached() then
-		self:ToggleFuBarTooltipDetached()
-	end
-end
-
-local function IsCorrectPanel(panel)
-	if type(panel) ~= "table" then
-		return false
-	elseif type(panel.AddPlugin) ~= "function" then
-		return false
-	elseif type(panel.RemovePlugin) ~= "function" then
-		return false
-	elseif type(panel.GetNumPlugins) ~= "function" then
-		return false
-	elseif type(panel:GetNumPlugins()) ~= "number" then
-		return false
-	elseif type(panel.GetPlugin) ~= "function" then
-		return false
-	elseif type(panel.HasPlugin) ~= "function" then
-		return false
-	elseif type(panel.GetPluginSide) ~= "function" then
-		return false
-	end
-	return true
-end
-
--- #NODOC
--- this is used internally by FuBar
-function FuBarPlugin:SetPanel(panel)
-	pluginToPanel[self] = panel
-end
-precondition(FuBarPlugin, 'SetPanel', function(self, panel)
-	argCheck(panel, 2, "table", "nil")
-	if panel and not IsCorrectPanel(panel) then
-		error("Bad argument #2 to `SetPanel'. Panel does not have the correct API.", 3)
-	end
-end)
-
--- #NODOC
--- this is used internally by FuBar
-function FuBarPlugin:SetFontSize(size)
-	if getPluginOption(self, 'userDefinedFrame', false) then
-		error(("%sYou must provide a :SetFontSize(size) method if you have 'userDefinedFrame' set."):format(self.name and self.name .. ": " or ""), 2)
-	end
-	if getPluginOption(self, 'iconPath', false) then
-		local frame = pluginToFrame[self]
-		local icon = frame and frame.icon
-		if not icon then
-			error(("%sno icon frame found."):format(self.name and self.name .. ": " or ""), 2)
-		end
-		icon:SetWidth(size + 3)
-		icon:SetHeight(size + 3)
-	end
-	if not getPluginOption(self, 'hasNoText', false) then
-		local frame = pluginToFrame[self]
-		local text = frame and frame.text
-		if not text then
-			error(("%sno text frame found."):format(self.name and self.name .. ": " or ""), 2)
-		end
-		local font, _, flags = text:GetFont()
-		text:SetFont(font, size, flags)
-	end
-	self:CheckWidth()
-end
-
-local function IsLoadOnDemand(plugin)
-	return IsAddOnLoadOnDemand(folderNames[plugin] or "")
-end
-
--- #NODOC
--- this is used internally by FuBar.
-function FuBarPlugin:IsDisabled()
-	return type(self.IsActive) == "function" and not self:IsActive() or false
-end
-
-function FuBarPlugin:OnEmbed(target)
-	local folder = Rock.addonToFolder[target]
-	if not folder then
-		for i = 6, 3, -1 do
-			folder = debugstack(i, 1, 0):match([[\AddOns\(.*)\]])
-			if folder then
-				break
-			end
-		end
-	end
-	folderNames[target] = folder
-end
-
-local frame_OnClick, frame_OnDoubleClick, frame_OnMouseDown, frame_OnMouseUp, frame_OnReceiveDrag, frame_OnEnter, frame_OnLeave
---[[---------------------------------------------------------------------------
-Arguments:
-	[optional] string - name of the frame
-Returns:
-	frame - a frame with the basic scripts to be considered a plugin frame.
-Example:
-	MyPlugin.frame = MyPlugin:CreateBasicPluginFrame("FuBar_MyPluginFrame")
------------------------------------------------------------------------------]]
-function FuBarPlugin:CreateBasicPluginFrame(name)
-	local frame = CreateFrame("Button", name, UIParent)
-	frame:SetFrameStrata("HIGH")
-	frame:SetFrameLevel(7)
-	frame:EnableMouse(true)
-	frame:EnableMouseWheel(true)
-	frame:SetMovable(true)
-	frame:SetWidth(150)
-	frame:SetHeight(24)
-	frame:SetPoint("CENTER", UIParent, "CENTER")
-	frame.self = self
-	if not frame_OnEnter then
-		function frame_OnEnter(this)
-			local self = this.self
-			local tooltipType = getPluginOption(self, 'tooltipType', "GameTooltip")
-			if tooltipType == "GameTooltip" then
-				GameTooltip:SetOwner(self:IsFuBarMinimapAttached() and pluginToMinimapFrame[self] or pluginToFrame[self], "ANCHOR_CURSOR")
-				self:UpdateFuBarTooltip()
-			end
-			if type(self.OnFuBarEnter) == "function" then
-				self:OnFuBarEnter()
-			end
-		end
-	end
-	frame:SetScript("OnEnter", frame_OnEnter)
-	if not frame_OnLeave then
-		function frame_OnLeave(this)
-			local self = this.self
-			if type(self.OnFuBarLeave) == "function" then
-				self:OnFuBarLeave()
-			end
-			local tooltipType = getPluginOption(self, 'tooltipType', "GameTooltip")
-			if tooltipType == "GameTooltip" and GameTooltip:IsOwned(self:IsFuBarMinimapAttached() and pluginToMinimapFrame[self] or pluginToFrame[self]) then
-				GameTooltip:Hide()
-			end
-		end
-	end
-	frame:SetScript("OnLeave", frame_OnLeave)
-	if not frame_OnClick then
-		function frame_OnClick(this, button)
-			local self = this.self
-			if self:IsFuBarMinimapAttached() and this.dragged then return end
-			if type(self.OnFuBarClick) == "function" then
-				self:OnFuBarClick(button)
-			end
-		end
-	end
-	frame:SetScript("OnClick", frame_OnClick)
-	if not frame_OnDoubleClick then
-		function frame_OnDoubleClick(this, button)
-			local self = this.self
-			if type(self.OnFuBarDoubleClick) == "function" then
-				self:OnFuBarDoubleClick(button)
-			end
-		end
-	end
-	frame:SetScript("OnDoubleClick", frame_OnDoubleClick)
-	if not frame_OnMouseDown then
-		function frame_OnMouseDown(this, button)
-			local self = this.self
-			if button == "RightButton" and not IsShiftKeyDown() and not IsControlKeyDown() and not IsAltKeyDown() then
-				self:OpenMenu()
-				return
-			else
-				if type(self.OnFuBarMouseDown) == "function" then
-					self:OnFuBarMouseDown(button)
-				end
-			end
-		end
-	end
-	frame:SetScript("OnMouseDown", frame_OnMouseDown)
-	if not frame_OnMouseUp then
-		function frame_OnMouseUp(this, button)
-			local self = this.self
-			if type(self.OnFuBarMouseUp) == "function" then
-				self:OnFuBarMouseUp(button)
-			end
-		end
-	end
-	frame:SetScript("OnMouseUp", frame_OnMouseUp)
-	if not frame_OnReceiveDrag then
-		function frame_OnReceiveDrag(this)
-			local self = this.self
-			if (self:IsFuBarMinimapAttached() and not this.dragged) and type(self.OnReceiveDrag) == "function" then
-				self:OnFuBarReceiveDrag()
-			end
-		end
-	end
-	frame:SetScript("OnReceiveDrag", frame_OnReceiveDrag)
-	return frame
-end
-
-local child_OnEnter, child_OnLeave, child_OnClick, child_OnDoubleClick, child_OnMouseDown, child_OnMouseUp, child_OnReceiveDrag
---[[---------------------------------------------------------------------------
-Arguments:
-	string - type of the frame, e.g. "Frame", "Button", etc.
-	[optional] string - name of the frame
-	[optional] frame - parent frame
-Returns:
-	frame - a child frame that can be manipulated and used
-Example:
-	local child = self:CreatePluginChildFrame("Frame", nil, self.frame)
------------------------------------------------------------------------------]]
-function FuBarPlugin:CreatePluginChildFrame(frameType, name, parent)
-	local child = CreateFrame(frameType, name, parent)
-	if parent then
-		child:SetFrameLevel(parent:GetFrameLevel() + 2)
-	end
-	child.self = self
-	if not child_OnEnter then
-		function child_OnEnter(this, ...)
-			local self = this.self
-			local frame = pluginToFrame[self]
-			if frame:GetScript("OnEnter") then
-				frame:GetScript("OnEnter")(frame, ...)
-			end
-		end
-	end
-	child:SetScript("OnEnter", child_OnEnter)
-	if not child_OnLeave then
-		function child_OnLeave(this, ...)
-			local self = this.self
-			local frame = pluginToFrame[self]
-			if frame:GetScript("OnLeave") then
-				frame:GetScript("OnLeave")(frame, ...)
-			end
-		end
-	end
-	child:SetScript("OnLeave", child_OnLeave)
-	if child:HasScript("OnClick") then
-		if not child_OnClick then
-			function child_OnClick(this, ...)
-				local self = this.self
-				local frame = pluginToFrame[self]
-				if frame:HasScript("OnClick") and frame:GetScript("OnClick") then
-					frame:GetScript("OnClick")(frame, ...)
-				end
-			end
-		end
-		child:SetScript("OnClick", child_OnClick)
-	end
-	if child:HasScript("OnDoubleClick") then
-		if not child_OnDoubleClick then
-			function child_OnDoubleClick(this, ...)
-				local self = this.self
-				local frame = pluginToFrame[self]
-				if frame:HasScript("OnDoubleClick") and frame:GetScript("OnDoubleClick") then
-					frame:GetScript("OnDoubleClick")(frame, ...)
-				end
-			end
-		end
-		child:SetScript("OnDoubleClick", child_OnDoubleClick)
-	end
-	if not child_OnMouseDown then
-		function child_OnMouseDown(this, ...)
-			local self = this.self
-			local frame = pluginToFrame[self]
-			if frame:HasScript("OnMouseDown") and frame:GetScript("OnMouseDown") then
-				frame:GetScript("OnMouseDown")(frame, ...)
-			end
-		end
-	end
-	child:SetScript("OnMouseDown", child_OnMouseDown)
-	if not child_OnMouseUp then
-		function child_OnMouseUp(this, ...)
-			local self = this.self
-			local frame = pluginToFrame[self]
-			if frame:HasScript("OnMouseUp") and frame:GetScript("OnMouseUp") then
-				frame:GetScript("OnMouseUp")(frame, ...)
-			end
-		end
-	end
-	child:SetScript("OnMouseUp", child_OnMouseUp)
-	if not child_OnReceiveDrag then
-		function child_OnReceiveDrag(this, ...)
-			local self = this.self
-			local frame = pluginToFrame[self]
-			if frame:HasScript("OnReceiveDrag") and frame:GetScript("OnReceiveDrag") then
-				frame:GetScript("OnReceiveDrag")(frame, ...)
-			end
-		end
-	end
-	child:SetScript("OnReceiveDrag", child_OnReceiveDrag)
-	return child
-end
-precondition(FuBarPlugin, 'CreatePluginChildFrame', function(self, frameType, name, parent)
-	if not pluginToFrame[self] then
-		error(("%sYou must have self.frame declared in order to add child frames."):format(self.name and self.name .. ": " or ""), 3)
-	end
-	argCheck(frameType, 2, "string")
-end)
-
---[[---------------------------------------------------------------------------
-Notes:
-	Opens the configuration menu associated with this plugin.
-Example:
-	self:OpenMenu()
------------------------------------------------------------------------------]]
-function FuBarPlugin:OpenMenu(frame)
-	if not frame then
-		frame = self:IsFuBarMinimapAttached() and pluginToMinimapFrame[self] or pluginToFrame[self]
-	end
-	if not frame:IsVisible() then
-		frame = UIParent
-	end
-	local configType = getPluginOption(self, 'configType', "LibRockConfig-1.0")
-	if configType == "Dewdrop-2.0" then
-		if not frame or not self:GetFrame() or Dewdrop20:IsOpen(frame) then
-			Dewdrop20:Close()
-			return
-		end
-		local tooltipType = getPluginOption(self, 'tooltipType', "GameTooltip")
-		if tooltipType == "GameTooltip" then
-			if GameTooltip:IsOwned(frame) then
-				GameTooltip:Hide()
-			end
-		elseif tooltipType == "Custom" and type(self.CloseTooltip) == "function" then
-			self:CloseTooltip()
-		elseif tooltipType == "Tablet-2.0" and Tablet20 then
-			Tablet20:Close()
-		end
-
-		if not Dewdrop20:IsRegistered(self:GetFrame()) then
-			if type(self.OnMenuRequest) == "table" and (not self.OnMenuRequest.handler or self.OnMenuRequest.handler == self) and self.OnMenuRequest.type == "group" then
-				Dewdrop20:InjectAceOptionsTable(self, self.OnMenuRequest)
-				if self.OnMenuRequest.args and CheckFuBar() and not getPluginOption(self, 'independentProfile', false) then
-					self.OnMenuRequest.args.profile = nil
-					if self.OnMenuRequest.extraArgs then
-						self.OnMenuRequest.extraArgs.profile = nil
-					end
-				end
-			end
-			Dewdrop20:Register(self:GetFrame(),
-				'children', type(self.OnMenuRequest) == "table" and self.OnMenuRequest or function(level, value, valueN_1, valueN_2, valueN_3, valueN_4)
-					if level == 1 then
-						if not getPluginOption(self, 'hideMenuTitle', false) then
-							Dewdrop20:AddLine(
-								'text', self:GetTitle(),
-								'isTitle', true
-							)
-						end
-
-						if self.OnMenuRequest then
-							self:OnMenuRequest(level, value, false, valueN_1, valueN_2, valueN_3, valueN_4)
-						end
-
-						if not getPluginOption(self, 'overrideMenu', false) then
-							if self.MenuSettings and not getPluginOption(self, 'hideMenuTitle', false) then
-								Dewdrop20:AddLine()
-							end
-							self:AddImpliedMenuOptions()
-						end
-					else
-						if not getPluginOption(self, 'overrideMenu', false) and self:AddImpliedMenuOptions() then
-						else
-							if self.OnMenuRequest then
-								self:OnMenuRequest(level, value, false, valueN_1, valueN_2, valueN_3, valueN_4)
-							end
-						end
-					end
-					if level == 1 then
-						Dewdrop20:AddLine(
-							'text', CLOSE,
-							'tooltipTitle', CLOSE,
-							'tooltipText', CLOSE_DESC,
-							'func', Dewdrop.Close,
-							'arg1', Dewdrop
-						)
-					end
-				end,
-				'point', function(frame)
-					local x, y = frame:GetCenter()
-					local leftRight
-					if x < GetScreenWidth() / 2 then
-						leftRight = "LEFT"
-					else
-						leftRight = "RIGHT"
-					end
-					if y < GetScreenHeight() / 2 then
-						return "BOTTOM" .. leftRight, "TOP" .. leftRight
-					else
-						return "TOP" .. leftRight, "BOTTOM" .. leftRight
-					end
-				end,
-				'dontHook', true
-			)
-		end
-		if frame == self:GetFrame() then
-			Dewdrop20:Open(self:GetFrame())
-		elseif frame ~= UIParent then
-			Dewdrop20:Open(frame, self:GetFrame())
-		else
-			Dewdrop20:Open(frame, self:GetFrame(), 'cursorX', true, 'cursorY', true)
-		end
-	elseif configType == "LibRockConfig-1.0" then
-		local RockConfig = Rock("LibRockConfig-1.0", false, true)
-		if RockConfig then
-			RockConfig.OpenConfigMenu(self)
-		end
-	else
-		-- TODO: add more possibilities
-	end
-end
-
-function FuBarPlugin.OnEmbedInitialize(FuBarPlugin, self)
-	if not self.frame then
-		local name = MAJOR_VERSION .. "_" .. self:GetTitle() .. "_" .. "Frame"
-		local frame = _G[name]
-		if not frame or not _G[name .. "Text"] or not _G[name .. "Icon"] then
-			frame = FuBarPlugin.CreateBasicPluginFrame(self, name)
-
-			local icon = frame:CreateTexture(name .. "Icon", "ARTWORK")
-			frame.icon = icon
-			icon:SetWidth(16)
-			icon:SetHeight(16)
-			icon:SetPoint("LEFT", frame, "LEFT")
-
-			local text = frame:CreateFontString(name .. "Text", "ARTWORK")
-			frame.text = text
-			text:SetWidth(134)
-			text:SetHeight(24)
-			text:SetPoint("LEFT", icon, "RIGHT", 0, 1)
-			text:SetFontObject(GameFontNormal)
-		end
-		pluginToFrame[self] = frame
-	else
-		pluginToFrame[self] = self.frame
-		if not pluginToOptions[self] then
-			pluginToOptions[self] = {}
-		end
-		pluginToOptions[self].userDefinedFrame = true
-	end
-
-	local frame = pluginToFrame[self]
-	frame.plugin = self
-	frame:SetParent(UIParent)
-	frame:SetPoint("RIGHT", UIParent, "LEFT", -5, 0)
-	frame:Hide()
-
-	local iconPath = getPluginOption(self, 'iconPath', false)
-	if iconPath then
-		self:SetFuBarIcon(iconPath)
-	end
-
-	if CheckFuBar() then
-		FuBar:RegisterPlugin(self)
-	end
-end
-
-
-local CheckShow = function(self, panelId)
-	if not pluginToFrame[self]:IsShown() and (not pluginToMinimapFrame[self] or not pluginToMinimapFrame[self]:IsShown()) then
-		self:Show(panelId)
-	end
-end
-
-local schedules = {}
-local f = CreateFrame("Frame")
-f:SetScript("OnUpdate", function(this)
-	for i,v in ipairs(schedules) do
-		local success, ret = pcall(unpack(v))
-		if not success then
-			geterrorhandler()(ret)
-		end
-		schedules[i] = del(v)
-	end
-	f:Hide()
-end)
-
-local recheckPlugins
-local AceConsole
-function FuBarPlugin.OnEmbedEnable(FuBarPlugin, self, first)
-	if not getPluginOption(self, 'userDefinedFrame', false) then
-		local icon = pluginToFrame[self].icon
-		if self:IsFuBarIconShown() then
-			icon:Show()
-		else
-			icon:Hide()
-		end
-	end
-	self:CheckWidth(true)
-
-	if not getPluginOption(self, 'hideWithoutStandby', false) or (getLazyDatabaseValue(self) and not getLazyDatabaseValue(self, 'hidden')) then
-		if not first then
-			CheckShow(self, self.panelIdTmp)
-		else
-			schedules[#schedules+1] = newList(CheckShow, self, self.panelIdTmp)
-			f:Show()
-		end
-	end
-
-	local tooltipType = getPluginOption(self, 'tooltipType', "GameTooltip")
-	if tooltipType == "Tablet-2.0" and not getPluginOption(self, 'cannotDetachTooltip', false) and getLazyDatabaseValue(self, 'detachedTooltip', 'detached') then
-		schedules[#schedules+1] = newList(self.DetachFuBarTooltip, self)
-		f:Show()
-	end
-
-	if IsLoadOnDemand(self) and CheckFuBar() then
-		if not FuBar.db.profile.loadOnDemand then
-			FuBar.db.profile.loadOnDemand = {}
-		end
-		if not FuBar.db.profile.loadOnDemand[folderNames[self]] then
-			FuBar.db.profile.loadOnDemand[folderNames[self]] = {}
-		end
-		FuBar.db.profile.loadOnDemand[folderNames[self]].disabled = nil
-	end
-	--[[
-	if CheckFuBar() and AceLibrary:HasInstance("AceConsole-2.0") then
-		if not recheckPlugins then
-			if not AceConsole then
-				AceConsole = AceLibrary("AceConsole-2.0")
-			end
-			recheckPlugins = function()
-				for k,v in pairs(AceConsole.registry) do
-					if type(v) == "table" and v.args and AceOO.inherits(v.handler, FuBarPlugin) and not v.handler.independentProfile then
-						v.args.profile = nil
-					end
-				end
-			end
-		end
-		FuBarPlugin:ScheduleEvent("FuBarPlugin-recheckPlugins", recheckPlugins, 0)
-	end
-	]]
-end
-
-function FuBarPlugin.OnEmbedDisable(FuBarPlugin, self)
-	self:Hide(false)
-
-	if IsLoadOnDemand(self) and CheckFuBar() then
-		if not FuBar.db.profile.loadOnDemand then
-			FuBar.db.profile.loadOnDemand = {}
-		end
-		if not FuBar.db.profile.loadOnDemand[folderNames[self]] then
-			FuBar.db.profile.loadOnDemand[folderNames[self]] = {}
-		end
-		FuBar.db.profile.loadOnDemand[folderNames[self]].disabled = true
-	end
-end
-
-function FuBarPlugin.OnEmbedProfileEnable(FuBarPlugin, self)
-	self:UpdateFuBarPlugin()
-	if getLazyDatabaseValue(self) then
-		if not getLazyDatabaseValue(self, 'detachedTooltip') then
-			setLazyDatabaseValue(self, {}, 'detachedTooltip')
-		end
-		local tooltipType = getPluginOption(self, 'tooltipType', "GameTooltip")
-		if tooltipType == "Tablet-2.0" and Tablet20 then
-			if Tablet20.registry[pluginToFrame[self]] then
-				Tablet20:UpdateDetachedData(pluginToFrame[self], getLazyDatabaseValue(self, 'detachedTooltip'))
-			else
-				RegisterTablet20(self)
-			end
-		end
-		if MinimapContainer:HasPlugin(self) then
-			MinimapContainer:ReadjustLocation(self)
-		end
-	end
-end
-
--- #NODOC
-function FuBarPlugin.GetEmbedRockConfigOptions(FuBarPlugin, self)
-	return 'icon', {
-		type = 'boolean',
-		name = SHOW_FUBAR_ICON,
-		desc = SHOW_FUBAR_ICON_DESC,
-		set = "ToggleFuBarIconShown",
-		get = "IsFuBarIconShown",
-		hidden = function()
-			return not getPluginOption(self, 'iconPath', false) or getPluginOption(self, 'hasNoText', false) or self:IsDisabled() or self:IsFuBarMinimapAttached() or not getLazyDatabaseValue(self)
-		end,
-		order = -13.7,
-		handler = self,
-	}, 'text', {
-		type = 'boolean',
-		name = SHOW_FUBAR_TEXT,
-		desc = SHOW_FUBAR_TEXT_DESC,
-		set = "ToggleFuBarTextShown",
-		get = "IsFuBarTextShown",
-		hidden = function()
-			return getPluginOption(self, 'cannotHideText', false) or not getPluginOption(self, 'iconPath', false) or getPluginOption(self, 'hasNoText') or self:IsDisabled() or self:IsFuBarMinimapAttached() or not getLazyDatabaseValue(self)
-		end,
-		order = -13.6,
-		handler = self,
-	}, 'colorText', {
-		type = 'boolean',
-		name = SHOW_COLORED_FUBAR_TEXT,
-		desc = SHOW_COLORED_FUBAR_TEXT_DESC,
-		set = "ToggleFuBarTextColored",
-		get = "IsFuBarTextColored",
-		hidden = function()
-			return getPluginOption(self, 'userDefinedFrame', false) or getPluginOption(self, 'hasNoText', false) or getPluginOption(self, 'hasNoColor', false) or self:IsDisabled() or self:IsFuBarMinimapAttached() or not getLazyDatabaseValue(self)
-		end,
-		order = -13.5,
-		handler = self,
-	}, 'detachTooltip', {
-		type = 'boolean',
-		name = DETACH_FUBAR_TOOLTIP,
-		desc = DETACH_FUBAR_TOOLTIP_DESC,
-		get = "IsFuBarTooltipDetached",
-		set = "ToggleFuBarTooltipDetached",
-		hidden = function()
-			return not Tablet20 or getPluginOption(self, 'tooltipType', "GameTooltip") ~= "Tablet-2.0" or self:IsDisabled()
-		end,
-		order = -13.4,
-		handler = self,
-	}, 'lockTooltip', {
-		type = 'boolean',
-		name = LOCK_FUBAR_TOOLTIP,
-		desc = LOCK_FUBAR_TOOLTIP_DESC,
-		get = function()
-			return Tablet20:IsLocked(pluginToFrame[self])
-		end,
-		set = function()
-			return Tablet20:ToggleLocked(pluginToFrame[self])
-		end,
-		disabled = function()
-			return not self:IsFuBarTooltipDetached()
-		end,
-		hidden = function()
-			return not Tablet20 or getPluginOption(self, 'tooltipType', "GameTooltip") ~= "Tablet-2.0" or getPluginOption(self, 'cannotDetachTooltip', false) or self:IsDisabled()
-		end,
-		order = -13.3,
-		handler = self,
-	}, 'position', {
-		type = 'choice',
-		name = POSITION_ON_FUBAR,
-		desc = POSITION_ON_FUBAR_DESC,
-		choices = {
-			LEFT = POSITION_LEFT,
-			CENTER = POSITION_CENTER,
-			RIGHT = POSITION_RIGHT
-		},
-		choiceSort = {
-			"LEFT",
-			"CENTER",
-			"RIGHT",
-		},
-		get = function()
-			return self:GetPanel() and self:GetPanel():GetPluginSide(self)
-		end,
-		set = function(value)
-			if self:GetPanel() then
-				self:GetPanel():SetPluginSide(self, value)
-			end
-		end,
-		hidden = function()
-			return self:IsFuBarMinimapAttached() or self:IsDisabled() or not pluginToPanel[self]
-		end,
-		order = -13.2,
-		handler = self,
-	}, 'minimapAttach', {
-		type = 'boolean',
-		name = ATTACH_PLUGIN_TO_MINIMAP,
-		desc = ATTACH_PLUGIN_TO_MINIMAP_DESC,
-		get = "IsFuBarMinimapAttached",
-		set = "ToggleFuBarMinimapAttached",
-		hidden = function()
-			return (getPluginOption(self, 'cannotAttachToMinimap', false) and not self:IsFuBarMinimapAttached()) or not CheckFuBar() or self:IsDisabled()
-		end,
-		order = -13.1,
-		handler = self,
-	}, 'hide', {
-		type = 'boolean',
-		name = function()
-			if self:IsFuBarMinimapAttached() then
-				return HIDE_MINIMAP_BUTTON
-			else
-				return HIDE_FUBAR_PLUGIN
-			end
-		end,
-		desc = HIDE_FUBAR_PLUGIN_DESC,
-		get = function()
-			return not pluginToFrame[self]:IsShown() and (not pluginToMinimapFrame[self] or not pluginToMinimapFrame[self]:IsShown())
-		end,
-		set = function(value)
-			if not value then
-				self:Show()
-			else
-				self:Hide()
-			end
-		end,
-		hidden = function()
-			return not getPluginOption(self, 'hideWithoutStandby', false) or self:IsDisabled()
-		end,
-		order = -13,
-		handler = self,
-	}
-end
-
-local plugins = MinimapContainer.plugins or {}
-for k in pairs(MinimapContainer) do
-	MinimapContainer[k] = nil
-end
-MinimapContainer.plugins = plugins
-
-local minimap_OnMouseDown, minimap_OnMouseUp
-function MinimapContainer:AddPlugin(plugin)
-	if CheckFuBar() and FuBar:IsChangingProfile() then
-		return
-	end
-	if pluginToPanel[plugin] then
-		pluginToPanel[plugin]:RemovePlugin(plugin)
-	end
-	pluginToPanel[plugin] = self
-	if not pluginToMinimapFrame[plugin] then
-		local frame = CreateFrame("Button", pluginToFrame[plugin]:GetName() .. "MinimapButton", Minimap)
-		pluginToMinimapFrame[plugin] = frame
-		plugin.minimapFrame = frame
-		frame.plugin = plugin
-		frame:SetWidth(31)
-		frame:SetHeight(31)
-		frame:SetFrameStrata("BACKGROUND")
-		frame:SetFrameLevel(4)
-		frame:SetHighlightTexture("Interface\\Minimap\\UI-Minimap-ZoomButton-Highlight")
-		local icon = frame:CreateTexture(frame:GetName() .. "Icon", "BACKGROUND")
-		plugin.minimapIcon = icon
-		local path = plugin:GetFuBarIcon() or (pluginToFrame[plugin].icon and pluginToFrame[plugin].icon:GetTexture()) or "Interface\\Icons\\INV_Misc_QuestionMark"
-		icon:SetTexture(path)
-		if path:sub(1, 16) == "Interface\\Icons\\" then
-			icon:SetTexCoord(0.07, 0.93, 0.07, 0.93)
-		else
-			icon:SetTexCoord(0, 1, 0, 1)
-		end
-		icon:SetWidth(20)
-		icon:SetHeight(20)
-		icon:SetPoint("TOPLEFT", frame, "TOPLEFT", 7, -5)
-		local overlay = frame:CreateTexture(frame:GetName() .. "Overlay","OVERLAY")
-		overlay:SetTexture("Interface\\Minimap\\MiniMap-TrackingBorder")
-		overlay:SetWidth(53)
-		overlay:SetHeight(53)
-		overlay:SetPoint("TOPLEFT",frame,"TOPLEFT")
-		frame:EnableMouse(true)
-		frame:RegisterForClicks("LeftButtonUp")
-
-		frame.self = plugin
-		if not frame_OnEnter then
-			function frame_OnEnter(this)
-				if type(this.self.OnFuBarEnter) == "function" then
-					this.self:OnFuBarEnter()
-				end
-			end
-		end
-		frame:SetScript("OnEnter", frame_OnEnter)
-		if not frame_OnLeave then
-			function frame_OnLeave(this)
-				if type(this.self.OnFuBarLeave) == "function" then
-					this.self:OnFuBarLeave()
-				end
-			end
-		end
-		frame:SetScript("OnLeave", frame_OnLeave)
-		if not frame_OnClick then
-			function frame_OnClick(this, arg1)
-				if this.self:IsMinimapAttached() and this.dragged then return end
-				if type(this.self.OnFuBarClick) == "function" then
-					this.self:OnFuBarClick(arg1)
-				end
-			end
-		end
-		frame:SetScript("OnClick", frame_OnClick)
-		if not frame_OnDoubleClick then
-			function frame_OnDoubleClick(this, arg1)
-				if type(this.self.OnFuBarDoubleClick) == "function" then
-					this.self:OnFuBarDoubleClick(arg1)
-				end
-			end
-		end
-		frame:SetScript("OnDoubleClick", frame_OnDoubleClick)
-		if not frame_OnReceiveDrag then
-			function frame_OnReceiveDrag(this)
-				if this.self:IsMinimapAttached() and this.dragged then return end
-				if type(this.self.OnFuBarReceiveDrag) == "function" then
-					this.self:OnFuBarReceiveDrag()
-				end
-			end
-		end
-		frame:SetScript("OnReceiveDrag", frame_OnReceiveDrag)
-		if not minimap_OnMouseDown then
-			function minimap_OnMouseDown(this, arg1)
-				this.dragged = false
-				if arg1 == "LeftButton" and not IsShiftKeyDown() and not IsControlKeyDown() and not IsAltKeyDown() then
-					HideDropDownMenu(1)
-					if type(this.self.OnFuBarMouseDown) == "function" then
-						this.self:OnFuBarMouseDown(arg1)
-					end
-				elseif arg1 == "RightButton" and not IsShiftKeyDown() and not IsControlKeyDown() and not IsAltKeyDown() then
-					this.self:OpenMenu(this)
-				else
-					HideDropDownMenu(1)
-					if type(this.self.OnFuBarMouseDown) == "function" then
-						this.self:OnFuBarMouseDown(arg1)
-					end
-				end
-				if this.self.OnFuBarClick or this.self.OnFuBarMouseDown or this.self.OnFuBarMouseUp or this.self.OnFuBarDoubleClick then
-					if this.self.minimapIcon:GetTexture():sub(1, 16) == "Interface\\Icons\\" then
-						this.self.minimapIcon:SetTexCoord(0.14, 0.86, 0.14, 0.86)
-					else
-						this.self.minimapIcon:SetTexCoord(0.1, 0.9, 0.1, 0.9)
-					end
-				end
-			end
-		end
-		frame:SetScript("OnMouseDown", minimap_OnMouseDown)
-		if not minimap_OnMouseUp then
-			function minimap_OnMouseUp(this, arg1)
-				if not this.dragged and type(this.self.OnFuBarMouseUp) == "function" then
-					this.self:OnFuBarMouseUp(arg1)
-				end
-				if this.self.minimapIcon:GetTexture():sub(1, 16) == "Interface\\Icons\\" then
-					this.self.minimapIcon:SetTexCoord(0.05, 0.95, 0.05, 0.95)
-				else
-					this.self.minimapIcon:SetTexCoord(0, 1, 0, 1)
-				end
-			end
-		end
-		frame:SetScript("OnMouseUp", minimap_OnMouseUp)
-		frame:RegisterForDrag("LeftButton")
-		frame:SetScript("OnDragStart", self.OnDragStart)
-		frame:SetScript("OnDragStop", self.OnDragStop)
-
-		if getPluginOption(plugin, 'tooltipType', "GameTooltip") == "Tablet-2.0" then
-			-- Note that we have to do this after :SetScript("OnEnter"), etc,
-			-- so that Tablet-2.0 can override it properly.
-			RegisterTablet20(plugin)
-			Tablet20:Register(frame, pluginToFrame[plugin])
-		end
-	end
-	pluginToFrame[plugin]:Hide()
-	pluginToMinimapFrame[plugin]:Show()
-	self:ReadjustLocation(plugin)
-	table.insert(self.plugins, plugin)
-	local exists = false
-	return true
-end
-
-function MinimapContainer:RemovePlugin(index)
-	if CheckFuBar() and FuBar:IsChangingProfile() then
-		return
-	end
-	if type(index) == "table" then
-		index = self:IndexOfPlugin(index)
-		if not index then
-			return
-		end
-	end
-	local t = self.plugins
-	local plugin = t[index]
-	assert(pluginToPanel[plugin] == self, "Plugin has improper panel field")
-	plugin:SetPanel(nil)
-	table.remove(t, index)
-	return true
-end
-
-function MinimapContainer:ReadjustLocation(plugin)
-	local frame = pluginToMinimapFrame[plugin]
-	if plugin.db and plugin.db.profile.minimapPositionWild then
-		frame:SetPoint("CENTER", UIParent, "BOTTOMLEFT", plugin.db.profile.minimapPositionX, plugin.db.profile.minimapPositionY)
-	elseif not plugin.db and plugin.minimapPositionWild then
-		frame:SetPoint("CENTER", UIParent, "BOTTOMLEFT", plugin.minimapPositionX, plugin.minimapPositionY)
-	else
-		local position
-		if plugin.db then
-			position = plugin.db.profile.minimapPosition or getPluginOption(plugin, 'defaultMinimapPosition', nil) or math.random(1, 360)
-		else
-			position = plugin.minimapPosition or getPluginOption(plugin, 'defaultMinimapPosition', nil) or math.random(1, 360)
-		end
-		local angle = math.rad(position or 0)
-		local x,y
-		local minimapShape = GetMinimapShape and GetMinimapShape() or "ROUND"
-		local cos = math.cos(angle)
-		local sin = math.sin(angle)
-
-		local round = true
-		if minimapShape == "ROUND" then
-			-- do nothing
-		elseif minimapShape == "SQUARE" then
-			round = false
-		elseif minimapShape == "CORNER-TOPRIGHT" then
-			if cos < 0 or sin < 0 then
-				round = false
-			end
-		elseif minimapShape == "CORNER-TOPLEFT" then
-			if cos > 0 or sin < 0 then
-				round = false
-			end
-		elseif minimapShape == "CORNER-BOTTOMRIGHT" then
-			if cos < 0 or sin > 0 then
-				round = false
-			end
-		elseif minimapShape == "CORNER-BOTTOMLEFT" then
-			if cos > 0 or sin > 0 then
-				round = false
-			end
-		elseif minimapShape == "SIDE-LEFT" then
-			if cos > 0 then
-				round = false
-			end
-		elseif minimapShape == "SIDE-RIGHT" then
-			if cos < 0 then
-				round = false
-			end
-		elseif minimapShape == "SIDE-TOP" then
-			if sin < 0 then
-				round = false
-			end
-		elseif minimapShape == "SIDE-BOTTOM" then
-			if sin > 0 then
-				round = false
-			end
-		elseif minimapShape == "TRICORNER-TOPRIGHT" then
-			if cos < 0 and sin < 0 then
-				round = false
-			end
-		elseif minimapShape == "TRICORNER-TOPLEFT" then
-			if cos > 0 and sin < 0 then
-				round = false
-			end
-		elseif minimapShape == "TRICORNER-BOTTOMRIGHT" then
-			if cos < 0 and sin > 0 then
-				round = false
-			end
-		elseif minimapShape == "TRICORNER-BOTTOMLEFT" then
-			if cos > 0 and sin > 0 then
-				round = false
-			end
-		end
-
-		if round then
-			x = cos * 80
-			y = sin * 80
-		else
-			x = 80 * 2^0.5 * cos
-			y = 80 * 2^0.5 * sin
-			if x < -80 then
-				x = -80
-			elseif x > 80 then
-				x = 80
-			end
-			if y < -80 then
-				y = -80
-			elseif y > 80 then
-				y = 80
-			end
-		end
-		frame:SetPoint("CENTER", Minimap, "CENTER", x, y)
-	end
-end
-
-function MinimapContainer:GetPlugin(index)
-	return self.plugins[index]
-end
-
-function MinimapContainer:GetNumPlugins()
-	return #self.plugins
-end
-
-function MinimapContainer:IndexOfPlugin(plugin)
-	for i,p in ipairs(self.plugins) do
-		if p == plugin then
-			return i, "MINIMAP"
-		end
-	end
-end
-
-function MinimapContainer:HasPlugin(plugin)
-	return self:IndexOfPlugin(plugin) ~= nil
-end
-
-function MinimapContainer:GetPluginSide(plugin)
-	local index = self:IndexOfPlugin(plugin)
-	assert(index, "Plugin not in panel")
-	return "MINIMAP"
-end
-
-function MinimapContainer.OnDragStart(this)
-	this.dragged = true
-	this:LockHighlight()
-	this:SetScript("OnUpdate", MinimapContainer.OnUpdate)
-	if this.self.minimapIcon:GetTexture():sub(1, 16) == "Interface\\Icons\\" then
-		this.self.minimapIcon:SetTexCoord(0.05, 0.95, 0.05, 0.95)
-	else
-		this.self.minimapIcon:SetTexCoord(0, 1, 0, 1)
-	end
-end
-
-function MinimapContainer.OnDragStop(this)
-	this:SetScript("OnUpdate", nil)
-	this:UnlockHighlight()
-end
-
-function MinimapContainer.OnUpdate(this, elapsed)
-	if not IsAltKeyDown() then
-		local mx, my = Minimap:GetCenter()
-		local px, py = GetCursorPosition()
-		local scale = UIParent:GetEffectiveScale()
-		px, py = px / scale, py / scale
-		local position = math.deg(math.atan2(py - my, px - mx))
-		if position <= 0 then
-			position = position + 360
-		elseif position > 360 then
-			position = position - 360
-		end
-		if this.self.db then
-			this.self.db.profile.minimapPosition = position
-			this.self.db.profile.minimapPositionX = nil
-			this.self.db.profile.minimapPositionY = nil
-			this.self.db.profile.minimapPositionWild = nil
-		else
-			this.self.minimapPosition = position
-			this.self.minimapPositionX = nil
-			this.self.minimapPositionY = nil
-			this.self.minimapPositionWild = nil
-		end
-	else
-		local px, py = GetCursorPosition()
-		local scale = UIParent:GetEffectiveScale()
-		px, py = px / scale, py / scale
-		if this.self.db then
-			this.self.db.profile.minimapPositionX = px
-			this.self.db.profile.minimapPositionY = py
-			this.self.db.profile.minimapPosition = nil
-			this.self.db.profile.minimapPositionWild = true
-		else
-			this.self.minimapPositionX = px
-			this.self.minimapPositionY = py
-			this.self.minimapPosition = nil
-			this.self.minimapPositionWild = true
-		end
-	end
-	MinimapContainer:ReadjustLocation(this.self)
-end
-
-FuBarPlugin:SetExportedMethods(
-	"SetFuBarOption",
-	"GetTitle",
-	"GetName",
-	"GetCategory",
-	"SetFontSize",
-	"GetFrame",
-	"Show",
-	"Hide",
-	"GetPanel",
-	"IsFuBarTextColored",
-	"ToggleFuBarTextColored",
-	"IsFuBarMinimapAttached",
-	"ToggleFuBarMinimapAttached",
-	"UpdateFuBarPlugin",
-	"UpdateFuBarText",
-	"UpdateFuBarTooltip",
-	"SetFuBarIcon",
-	"GetFuBarIcon",
-	"CheckWidth",
-	"SetFuBarText",
-	"GetFuBarText",
-	"IsFuBarIconShown",
-	"ToggleFuBarIconShown",
-	"ShowFuBarIcon",
-	"HideFuBarIcon",
-	"IsFuBarTextShown",
-	"ToggleFuBarTextShown",
-	"ShowFuBarText",
-	"HideFuBarText",
-	"IsFuBarTooltipDetached",
-	"ToggleFuBarTooltipDetached",
-	"DetachFuBarTooltip",
-	"ReattachFuBarTooltip",
-	"GetDefaultPosition",
-	"SetPanel",
-	"IsDisabled",
-	"CreateBasicPluginFrame",
-	"CreatePluginChildFrame",
-	"OpenMenu"
-)
-
-Rock:FinalizeLibrary(MAJOR_VERSION)
--- a/modules/FuBar_ReActionFu/lib/LibFuBarPlugin-3.0/LibFuBarPlugin-3.0.toc	Wed Apr 02 23:44:06 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,15 +0,0 @@
-## Interface: 20300
-## LoadOnDemand: 1
-## Title: LibFuBarPlugin-3.0
-## Notes: A library to provide a means create a FuBar-compatible plugin.
-## Notes-zhTW: 一個提供支援FuBar所需功能的插件。
-## Notes-esES: Una biblioteca para crear plugins compatibles con Fubar.
-## Author: ckknight
-## eMail: ckknight@gmail.com
-## Version: 2.0 $Revision: 44269 $
-## X-Category: Library
-## Dependencies: LibRock-1.0
-## OptionalDeps: FuBar
-## X-License: LGPL v2.1
-
-lib.xml
\ No newline at end of file
--- a/modules/FuBar_ReActionFu/lib/LibFuBarPlugin-3.0/lib.xml	Wed Apr 02 23:44:06 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
-..\FrameXML\UI.xsd">
-	<Script file="LibFuBarPlugin-3.0.lua" />
-</Ui>
\ No newline at end of file
--- a/modules/FuBar_ReActionFu/lib/LibRock-1.0/Changelog-LibRock-1.0-r63317.txt	Wed Apr 02 23:44:06 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-------------------------------------------------------------------------
-r63317 | ckknight | 2008-03-01 12:57:51 -0500 (Sat, 01 Mar 2008) | 2 lines
-Changed paths:
-   M /trunk/LibRock-1.0/LibRock-1.0.lua
-
-LibRock-1.0 - support LibStub-based mixins that have rawget(library, "Embed") which is a function on em.
-ROCK-136
-------------------------------------------------------------------------
-r61418 | pb_ee1 | 2008-02-15 05:25:45 -0500 (Fri, 15 Feb 2008) | 2 lines
-Changed paths:
-   M /trunk/LibRock-1.0
-
-LibRock-1.0:
-- Adding tsvn:logtemplate, i said -_-'
-------------------------------------------------------------------------
-r61417 | pb_ee1 | 2008-02-15 05:24:03 -0500 (Fri, 15 Feb 2008) | 3 lines
-Changed paths:
-   M /trunk/LibRock-1.0/LibRock-1.0.lua
-
-LibRock-1.0:
-- coller -> collez
-- Adding tsvn:logtemplate
-------------------------------------------------------------------------
-r61415 | pettigrow | 2008-02-15 05:13:24 -0500 (Fri, 15 Feb 2008) | 1 line
-Changed paths:
-   M /trunk/LibRock-1.0/LibRock-1.0.lua
-
-LibRock-1.0: frFR Update
-------------------------------------------------------------------------
-r61118 | ckknight | 2008-02-13 01:32:54 -0500 (Wed, 13 Feb 2008) | 1 line
-Changed paths:
-   M /trunk/LibRock-1.0/LibRock-1.0.lua
-   M /trunk/LibRockComm-1.0/LibRockComm-1.0.lua
-   M /trunk/LibRockConfig-1.0/LibRockConfig-1.0.lua
-   M /trunk/LibRockConsole-1.0/LibRockConsole-1.0.lua
-   M /trunk/LibRockDB-1.0/LibRockDB-1.0.lua
-   M /trunk/LibRockEvent-1.0/LibRockEvent-1.0.lua
-   M /trunk/LibRockHook-1.0/LibRockHook-1.0.lua
-   M /trunk/LibRockLocale-1.0/LibRockLocale-1.0.lua
-   M /trunk/LibRockModuleCore-1.0/LibRockModuleCore-1.0.lua
-   M /trunk/LibRockTimer-1.0/LibRockTimer-1.0.lua
-
-.LibRock-1.0 - don't use negative reversion numbers because the LibStub patch for supporting that was never accepted.
-------------------------------------------------------------------------
--- a/modules/FuBar_ReActionFu/lib/LibRock-1.0/LibRock-1.0.lua	Wed Apr 02 23:44:06 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2968 +0,0 @@
---[[
-Name: LibRock-1.0
-Revision: $Rev: 63317 $
-Developed by: ckknight (ckknight@gmail.com)
-Website: http://www.wowace.com/
-Description: Library to allow for library and addon creation and easy table recycling functions.
-License: LGPL v2.1
-]]
-
-local MAJOR_VERSION = "LibRock-1.0"
-local MINOR_VERSION = tonumber(("$Revision: 63317 $"):match("(%d+)")) - 60000
-
-local _G = _G
-local GetLocale = _G.GetLocale
-local CATEGORIES
-if GetLocale() == "deDE" then
-	CATEGORIES = {
-		["Action Bars"] = "Aktionsleisten",
-		["Auction"] = "Auktion",
-		["Audio"] = "Audio",
-		["Battlegrounds/PvP"] = "Schlachtfeld/PvP",
-		["Buffs"] = "Stärkungszauber",
-		["Chat/Communication"] = "Chat/Kommunikation",
-		["Druid"] = "Druide",
-		["Hunter"] = "Jäger",
-		["Mage"] = "Magier",
-		["Paladin"] = "Paladin",
-		["Priest"] = "Priester",
-		["Rogue"] = "Schurke",
-		["Shaman"] = "Schamane",
-		["Warlock"] = "Hexenmeister",
-		["Warrior"] = "Krieger",
-		["Healer"] = "Heiler",
-		["Tank"] = "Tank",
-		["Caster"] = "Zauberer",
-		["Combat"] = "Kampf",
-		["Compilations"] = "Zusammenstellungen",
-		["Data Export"] = "Datenexport",
-		["Development Tools"] = "Entwicklungstools",
-		["Guild"] = "Gilde",
-		["Frame Modification"] = "Frameveränderungen",
-		["Interface Enhancements"] = "Interfaceverbesserungen",
-		["Inventory"] = "Inventar",
-		["Library"] = "Bibliotheken",
-		["Map"] = "Karte",
-		["Mail"] = "Post",
-		["Miscellaneous"] = "Diverses",
-		["Quest"] = "Quest",
-		["Raid"] = "Schlachtzug",
-		["Tradeskill"] = "Beruf",
-		["UnitFrame"] = "Einheiten-Fenster",
-	}
-elseif GetLocale() == "frFR" then
-	CATEGORIES = {
-		["Action Bars"] = "Barres d'action",
-		["Auction"] = "Hôtel des ventes",
-		["Audio"] = "Audio",
-		["Battlegrounds/PvP"] = "Champs de bataille/JcJ",
-		["Buffs"] = "Buffs",
-		["Chat/Communication"] = "Chat/Communication",
-		["Druid"] = "Druide",
-		["Hunter"] = "Chasseur",
-		["Mage"] = "Mage",
-		["Paladin"] = "Paladin",
-		["Priest"] = "Prêtre",
-		["Rogue"] = "Voleur",
-		["Shaman"] = "Chaman",
-		["Warlock"] = "Démoniste",
-		["Warrior"] = "Guerrier",
-		["Healer"] = "Soigneur",
-		["Tank"] = "Tank",
-		["Caster"] = "Casteur",
-		["Combat"] = "Combat",
-		["Compilations"] = "Compilations",
-		["Data Export"] = "Exportation de données",
-		["Development Tools"] = "Outils de développement",
-		["Guild"] = "Guilde",
-		["Frame Modification"] = "Modification des fenêtres",
-		["Interface Enhancements"] = "Améliorations de l'interface",
-		["Inventory"] = "Inventaire",
-		["Library"] = "Bibliothèques",
-		["Map"] = "Carte",
-		["Mail"] = "Courrier",
-		["Miscellaneous"] = "Divers",
-		["Quest"] = "Quêtes",
-		["Raid"] = "Raid",
-		["Tradeskill"] = "Métiers",
-		["UnitFrame"] = "Fenêtres d'unité",
-	}
-elseif GetLocale() == "koKR" then
-	CATEGORIES = {
-		["Action Bars"] = "액션바",
-		["Auction"] = "경매",
-		["Audio"] = "음향",
-		["Battlegrounds/PvP"] = "전장/PvP",
-		["Buffs"] = "버프",
-		["Chat/Communication"] = "대화/의사소통",
-		["Druid"] = "드루이드",
-		["Hunter"] = "사냥꾼",
-		["Mage"] = "마법사",
-		["Paladin"] = "성기사",
-		["Priest"] = "사제",
-		["Rogue"] = "도적",
-		["Shaman"] = "주술사",
-		["Warlock"] = "흑마법사",
-		["Warrior"] = "전사",
-		["Healer"] = "힐러",
-		["Tank"] = "탱커",
-		["Caster"] = "캐스터",
-		["Combat"] = "전투",
-		["Compilations"] = "복합",
-		["Data Export"] = "자료 출력",
-		["Development Tools"] = "개발 도구",
-		["Guild"] = "길드",
-		["Frame Modification"] = "구조 변경",
-		["Interface Enhancements"] = "인터페이스 강화",
-		["Inventory"] = "인벤토리",
-		["Library"] = "라이브러리",
-		["Map"] = "지도",
-		["Mail"] = "우편",
-		["Miscellaneous"] = "기타",
-		["Quest"] = "퀘스트",
-		["Raid"] = "공격대",
-		["Tradeskill"] = "전문기술",
-		["UnitFrame"] = "유닛 프레임",
-	}
-elseif GetLocale() == "zhTW" then
-	CATEGORIES = {
-		["Action Bars"] = "動作列",
-		["Auction"] = "拍賣",
-		["Audio"] = "音效",
-		["Battlegrounds/PvP"] = "戰場/PvP",
-		["Buffs"] = "增益",
-		["Chat/Communication"] = "聊天/通訊",
-		["Druid"] = "德魯伊",
-		["Hunter"] = "獵人",
-		["Mage"] = "法師",
-		["Paladin"] = "聖騎士",
-		["Priest"] = "牧師",
-		["Rogue"] = "盜賊",
-		["Shaman"] = "薩滿",
-		["Warlock"] = "術士",
-		["Warrior"] = "戰士",
-		["Healer"] = "治療者",
-		["Tank"] = "坦克",
-		["Caster"] = "施法者",
-		["Combat"] = "戰鬥",
-		["Compilations"] = "整合",
-		["Data Export"] = "資料匯出",
-		["Development Tools"] = "開發工具",
-		["Guild"] = "公會",
-		["Frame Modification"] = "框架修改",
-		["Interface Enhancements"] = "介面增強",
-		["Inventory"] = "庫存",
-		["Library"] = "程式庫",
-		["Map"] = "地圖",
-		["Mail"] = "郵件",
-		["Miscellaneous"] = "雜項",
-		["Quest"] = "任務",
-		["Raid"] = "團隊",
-		["Tradeskill"] = "交易技能",
-		["UnitFrame"] = "頭像框架",
-	}
-elseif GetLocale() == "zhCN" then
-	CATEGORIES = {
-		["Action Bars"] = "动作条",
-		["Auction"] = "拍卖",
-		["Audio"] = "音频",
-		["Battlegrounds/PvP"] = "战场/PvP",
-		["Buffs"] = "增益魔法",
-		["Chat/Communication"] = "聊天/交流",
-		["Druid"] = "德鲁伊",
-		["Hunter"] = "猎人",
-		["Mage"] = "法师",
-		["Paladin"] = "圣骑士",
-		["Priest"] = "牧师",
-		["Rogue"] = "潜行者",
-		["Shaman"] = "萨满祭司",
-		["Warlock"] = "术士",
-		["Warrior"] = "战士",
-		["Healer"] = "治疗",
-		["Tank"] = "坦克",
-		["Caster"] = "远程输出",
-		["Combat"] = "战斗",
-		["Compilations"] = "编译",
-		["Data Export"] = "数据导出",
-		["Development Tools"] = "开发工具",
-		["Guild"] = "公会",
-		["Frame Modification"] = "框架修改",
-		["Interface Enhancements"] = "界面增强",
-		["Inventory"] = "背包",
-		["Library"] = "库",
-		["Map"] = "地图",
-		["Mail"] = "邮件",
-		["Miscellaneous"] = "杂项",
-		["Quest"] = "任务",
-		["Raid"] = "团队",
-		["Tradeskill"] = "商业技能",
-		["UnitFrame"] = "头像框架",
-	}
-elseif GetLocale() == "esES" then
-	CATEGORIES = {
-		["Action Bars"] = "Barras de Acción",
-		["Auction"] = "Subasta",
-		["Audio"] = "Audio",
-		["Battlegrounds/PvP"] = "Campos de Batalla/JcJ",
-		["Buffs"] = "Buffs",
-		["Chat/Communication"] = "Chat/Comunicación",
-		["Druid"] = "Druida",
-		["Hunter"] = "Cazador",
-		["Mage"] = "Mago",
-		["Paladin"] = "Paladín",
-		["Priest"] = "Sacerdote",
-		["Rogue"] = "Pícaro",
-		["Shaman"] = "Chamán",
-		["Warlock"] = "Brujo",
-		["Warrior"] = "Guerrero",
-		["Healer"] = "Sanador",
-		["Tank"] = "Tanque",
-		["Caster"] = "Conjurador",
-		["Combat"] = "Combate",
-		["Compilations"] = "Compilaciones",
-		["Data Export"] = "Exportar Datos",
-		["Development Tools"] = "Herramientas de Desarrollo",
-		["Guild"] = "Hermandad",
-		["Frame Modification"] = "Modificación de Marcos",
-		["Interface Enhancements"] = "Mejoras de la Interfaz",
-		["Inventory"] = "Inventario",
-		["Library"] = "Biblioteca",
-		["Map"] = "Mapa",
-		["Mail"] = "Correo",
-		["Miscellaneous"] = "Misceláneo",
-		["Quest"] = "Misión",
-		["Raid"] = "Banda",
-		["Tradeskill"] = "Habilidad de Comercio",
-		["UnitFrame"] = "Marco de Unidades",
-	}
-else -- enUS
-	CATEGORIES = {
-		["Action Bars"] = "Action Bars",
-		["Auction"] = "Auction",
-		["Audio"] = "Audio",
-		["Battlegrounds/PvP"] = "Battlegrounds/PvP",
-		["Buffs"] = "Buffs",
-		["Chat/Communication"] = "Chat/Communication",
-		["Druid"] = "Druid",
-		["Hunter"] = "Hunter",
-		["Mage"] = "Mage",
-		["Paladin"] = "Paladin",
-		["Priest"] = "Priest",
-		["Rogue"] = "Rogue",
-		["Shaman"] = "Shaman",
-		["Warlock"] = "Warlock",
-		["Warrior"] = "Warrior",
-		["Healer"] = "Healer",
-		["Tank"] = "Tank",
-		["Caster"] = "Caster",
-		["Combat"] = "Combat",
-		["Compilations"] = "Compilations",
-		["Data Export"] = "Data Export",
-		["Development Tools"] = "Development Tools",
-		["Guild"] = "Guild",
-		["Frame Modification"] = "Frame Modification",
-		["Interface Enhancements"] = "Interface Enhancements",
-		["Inventory"] = "Inventory",
-		["Library"] = "Library",
-		["Map"] = "Map",
-		["Mail"] = "Mail",
-		["Miscellaneous"] = "Miscellaneous",
-		["Quest"] = "Quest",
-		["Raid"] = "Raid",
-		["Tradeskill"] = "Tradeskill",
-		["UnitFrame"] = "UnitFrame",
-	}
-end
-
-local select = _G.select
-local tostring = _G.tostring
-local pairs = _G.pairs
-local ipairs = _G.ipairs
-local error = _G.error
-local setmetatable = _G.setmetatable
-local getmetatable = _G.getmetatable
-local type = _G.type
-local pcall = _G.pcall
-local next = _G.next
-local tonumber = _G.tonumber
-local strmatch = _G.strmatch
-local table_remove = _G.table.remove
-local debugstack = _G.debugstack
-local LoadAddOn = _G.LoadAddOn
-local GetAddOnInfo = _G.GetAddOnInfo
-local GetAddOnMetadata = _G.GetAddOnMetadata
-local GetNumAddOns = _G.GetNumAddOns
-local DisableAddOn = _G.DisableAddOn
-local EnableAddOn = _G.EnableAddOn
-local IsAddOnLoadOnDemand = _G.IsAddOnLoadOnDemand
-local IsLoggedIn = _G.IsLoggedIn
-local geterrorhandler = _G.geterrorhandler
-local assert = _G.assert
-local collectgarbage = _G.collectgarbage
-local table_sort = _G.table.sort
-local table_concat = _G.table.concat
-
--- #AUTODOC_NAMESPACE Rock
-
-
-local LibStub = _G.LibStub
-
-local Rock = LibStub:GetLibrary(MAJOR_VERSION, true) or _G.Rock
-local oldRock
-if not Rock then
-	Rock = LibStub:NewLibrary(MAJOR_VERSION, MINOR_VERSION)
-	if not Rock then
-		return
-	end
-	Rock.name = MAJOR_VERSION
-else
-	Rock, oldRock = Rock:NewLibrary(MAJOR_VERSION, MINOR_VERSION)
-	if not Rock then
-		return
-	end
-end
-_G.Rock = Rock
-
-local L = setmetatable({}, {__index=function(self,key) self[key] = key; return key end})
-if GetLocale() == "zhCN" then
-	L["Advanced options"] = "高级选项"
-	L["Advanced options for developers and power users."] = "开发者与高级用户的高级选项"
-	L["Unit tests"] = "框体测试"
-	L["Enable unit tests to be run. This is for developers only.\n\nYou must ReloadUI for changes to take effect."] = "开启框体测试,仅供开发者使用。\n\n需要重载用户界面。"
-	L["Contracts"] = "侦错协定"
-	L["Enable contracts to be run. This is for developers and anyone wanting to file a bug. Do not file a bug unless contracts are enabled. This will slightly slow down your addons if enabled."] = "启用侦错协定,这是给插件作者用来通报错误所使用。"
-	L["Reload UI"] = "重载UI"
-	L["Reload the User Interface for some changes to take effect."] = "部分功能更改需要重载用户界面才会生效。"
-	L["Reload"] = "重载"
-	L["Give donation"] = "捐赠"
-	L["Donate"] = "捐赠"
-	L["Give a much-needed donation to the author of this addon."] = "给插件作者捐赠支持插件开发。"
-	L["File issue"] = "通报错误"
-	L["Report"] = "报告"
-	L["File a bug or request a new feature or an improvement to this addon."] = "发送错误报告或请求新功能及要改进的部分。"
-	L["Press Ctrl-C to copy, then Alt-Tab out of the game, open your favorite web browser, and paste the link into the address bar."] = "Ctrl-C复制网址,Alt-Tab切换到桌面,打开浏览器,在地址栏贴上网址。"
-	L["Press Cmd-C to copy, then Cmd-Tab out of the game, open your favorite web browser, and paste the link into the address bar."] = "Cmd-C复制网址,Cmd-Tab切换到电脑桌面,打开浏览器,在地址栏贴上网址。"
-	L["Enabled"] = "开启"
-	L["Enable or disable this addon."] = "启用这个插件。"	
-
-elseif GetLocale() == "zhTW" then
-	L["Advanced options"] = "進階選項"
-	L["Advanced options for developers and power users."] = "插件作者、進階用戶選項"
-	L["Unit tests"] = "單元測試"
-	L["Enable unit tests to be run. This is for developers only.\n\nYou must ReloadUI for changes to take effect."] = "啟用單元測試,這是給插件作者使用的功能。\n\n需要重載介面才能使用。"
-	L["Contracts"] = "偵錯協定"
-	L["Enable contracts to be run. This is for developers and anyone wanting to file a bug. Do not file a bug unless contracts are enabled. This will slightly slow down your addons if enabled."] = "啟用偵錯協定,這是給插件作者用來通報錯誤所使用。"
-	L["Reload UI"] = "重載介面"
-	L["Reload the User Interface for some changes to take effect."] = "重新載入使用者介面,部分功能才會生效。"
-	L["Reload"] = "重載"
-	L["Give donation"] = "捐贈"
-	L["Donate"] = "捐贈"
-	L["Give a much-needed donation to the author of this addon."] = "捐贈金錢給插件作者。"
-	L["File issue"] = "通報錯誤"
-	L["Report"] = "報告"
-	L["File a bug or request a new feature or an improvement to this addon."] = "發出錯誤報告或請求新功能及要改進的部分。"
-	L["Press Ctrl-C to copy, then Alt-Tab out of the game, open your favorite web browser, and paste the link into the address bar."] = "Ctrl-C複製網址,Alt-Tab切換到電腦桌面,打開瀏覽器,在網址列貼上網址。"
-	L["Press Cmd-C to copy, then Cmd-Tab out of the game, open your favorite web browser, and paste the link into the address bar."] = "Cmd-C複製網址,Cmd-Tab切換到電腦桌面,打開瀏覽器,在網址列貼上網址。"
-	L["Enabled"] = "啟用"
-	L["Enable or disable this addon."] = "啟用這個插件。"
-elseif GetLocale() == "koKR" then
-	L["Advanced options"] = "상세 옵션"
-	L["Advanced options for developers and power users."] = "개발자와 파워 사용자를 위한 상세 옵션입니다."
-	L["Unit tests"] = "유닛 테스트"
-	L["Enable unit tests to be run. This is for developers only.\n\nYou must ReloadUI for changes to take effect."] = "유닛 테스트를 사용합니다. 이것은 개발자만을 위한 옵션입니다.\n\n변경된 결과를 적용하기 위해 당신의 UI를 재실행 합니다."
-	L["Contracts"] = "계약"
-	L["Enable contracts to be run. This is for developers and anyone wanting to file a bug. Do not file a bug unless contracts are enabled. This will slightly slow down your addons if enabled."] = "계약을 사용합니다. 이것은 개발자와 버그 파일을 알릴 분이면 누구나 사용 가능합니다. 계약이 가능하지 않으면 버그 파일을 보내지 마십시오. 이것은 당신의 애드온 속도를 약간 떨어뜨립니다."
-	L["Reload UI"] = "UI 재실행"
-	L["Reload the User Interface for some changes to take effect."] = "변경된 결과를 적용하기 위해 사용자 인터페이스를 재실행합니다."
-	L["Reload"] = "재실행"
-	L["Give donation"] = "기부"
-	L["Donate"] = "기부"
-	L["Give a much-needed donation to the author of this addon."] = "이 애드온의 제작자에게 필요한 기부를 합니다."
-	L["File issue"] = "파일 이슈"
-	L["Report"] = "보고"
-	L["File a bug or request a new feature or an improvement to this addon."] = "버그 파일을 알리거나 새로운 기능 또는 이 애드온에 대한 개선을 부탁합니다."
-	L["Press Ctrl-C to copy, then Alt-Tab out of the game, open your favorite web browser, and paste the link into the address bar."] = "Ctrl-C로 복사합니다. Alt-Tab 눌려 게임으로 부터 나간후 웹 브라우저를 엽니다. 복사된 링크를 주소 창에 붙여넣기 합니다."
-	L["Press Cmd-C to copy, then Cmd-Tab out of the game, open your favorite web browser, and paste the link into the address bar."] = "Cmd-C로 복사합니다. Cmd-Tab 눌려 게임으로 부터 나간후 웹 브라우저를 엽니다. 복사된 링크를 주소 창에 붙여넣기 합니다."
-	L["Enabled"] = "사용"
-	L["Enable or disable this addon."] = "이 애드온을 사용하거나 사용하지 않습니다."
-elseif GetLocale() == "frFR" then
-	L["Advanced options"] = "Options avancées"
-	L["Advanced options for developers and power users."] = "Options avancées à l'attention des développeurs et des utilisateurs expérimentés."
-	L["Reload UI"] = "Recharger IU"
-	L["Reload the User Interface for some changes to take effect."] = "Recharge l'interface utilisateur afin que certains changements prennent effet."
-	L["Reload"] = "Recharger"
-	L["Give donation"] = "Faire un don"
-	L["Donate"] = "Don"
-	L["Give a much-needed donation to the author of this addon."] = "Permet de faire un don bien mérité à l'auteur de cet addon."
-	L["File issue"] = "Problème"
-	L["Report"] = "Signaler"
-	L["File a bug or request a new feature or an improvement to this addon."] = "Permet de signaler un bogue ou de demander une amélioration à cet addon."
-	L["Press Ctrl-C to copy, then Alt-Tab out of the game, open your favorite web browser, and paste the link into the address bar."] = "Ctrl-C pour copier, puis Alt-Tab pour sortir du jeu. Ouvrez votre navigateur internet et collez le lien dans la barre d'adresse."
-	L["Press Cmd-C to copy, then Cmd-Tab out of the game, open your favorite web browser, and paste the link into the address bar."] = "Cmd-C pour copier, puis Alt-Tab pour sortir du jeu. Ouvrez votre navigateur internet et collez le lien dans la barre d'adresse."
-	L["Enabled"] = "Activé"
-	L["Enable or disable this addon."] = "Active ou désactive cet addon."
-end
-
-local isStandalone = debugstack():match("[Oo%.][Nn%.][Ss%.]\\([^\\]+)\\") == MAJOR_VERSION or nil
-local unitTestDB, enableContracts
-
-local weakKey = { __mode = 'k' }
-
--- frame to manage events from
-Rock.frame = oldRock and oldRock.frame or _G.CreateFrame("Frame")
-local frame = Rock.frame
--- dict of libraries in { ["major"] = object } form
-Rock.libraries = oldRock and oldRock.libraries or { [MAJOR_VERSION] = Rock }
-local libraries = Rock.libraries
--- set of libraries which have gone through the finalization process in { [object] = true } form
-Rock.finalizedLibraries = setmetatable(oldRock and oldRock.finalizedLibraries or { }, weakKey)
-local finalizedLibraries = Rock.finalizedLibraries
--- set of libraries which have been tried to be loaded.
-Rock.scannedLibraries = oldRock and oldRock.scannedLibraries or {}
-local scannedLibraries = Rock.scannedLibraries
--- exportedMethods[library] = { "method1", "method2" }
-Rock.exportedMethods = setmetatable(oldRock and oldRock.exportedMethods or {}, weakKey)
-local exportedMethods = Rock.exportedMethods
--- mixinToObject[mixin][object] = true
-Rock.mixinToObject = setmetatable(oldRock and oldRock.mixinToObject or {}, weakKey)
-local mixinToObject = Rock.mixinToObject
--- dict of addons in { ["name"] = object } form
-Rock.addons = oldRock and oldRock.addons or {}
-local addons = Rock.addons
--- set of libraries that should be finalized before ADDON_LOADED.
-Rock.pendingLibraries = setmetatable(oldRock and oldRock.pendingLibraries or { }, weakKey)
-local pendingLibraries = Rock.pendingLibraries
--- list of addons in order of created that need to be initialized by ADDON_LOADED.
-Rock.pendingAddons = oldRock and oldRock.pendingAddons or {}
-local pendingAddons = Rock.pendingAddons
--- dictionary of addons to their folder names
-Rock.addonToFolder = oldRock and oldRock.addonToFolder or {}
-local addonToFolder = Rock.addonToFolder
--- set of folders which have been loaded
-Rock.foldersLoaded = oldRock and oldRock.foldersLoaded or {}
-local foldersLoaded = Rock.foldersLoaded
--- list of addons in order of created that need to be enabled by PLAYER_LOGIN.
-Rock.pendingAddonsEnable = oldRock and oldRock.pendingAddonsEnable or {}
-local pendingAddonsEnable = Rock.pendingAddonsEnable
--- set of addons which have been enabled at least once.
-Rock.addonsAlreadyEnabled = oldRock and oldRock.addonsAlreadyEnabled or {}
-local addonsAlreadyEnabled = Rock.addonsAlreadyEnabled
--- set of addons which have no database and are set to be inactive.
-Rock.inactiveAddons = oldRock and oldRock.inactiveAddons or {}
-local inactiveAddons = Rock.inactiveAddons
--- set of addons which are currently enabled (not necessarily should be)
-Rock.currentlyEnabledAddons = oldRock and oldRock.currentlyEnabledAddons or {}
-local currentlyEnabledAddons = Rock.currentlyEnabledAddons
--- dictionary of namespace to list of functions which will be run.
-Rock.unitTests = oldRock and oldRock.unitTests or {}
-local unitTests = Rock.unitTests
--- metatable for addons
-Rock.addon_mt = oldRock and oldRock.addon_mt or {}
-local addon_mt = Rock.addon_mt
-for k in pairs(addon_mt) do
-	addon_mt[k] = nil
-end
-function addon_mt:__tostring()
-	return tostring(self.name)
-end
-
-local function better_tostring(self)
-	if type(self) == "table" and self.name then
-		return tostring(self.name)
-	end
-	return tostring(self)
-end
-
-local function figureCurrentAddon(pos)
-	local stack = debugstack(pos+1, 1, 0)
-	local folder = stack:match("[Oo%.][Nn%.][Ss%.]\\([^\\]+)\\")
-	if folder then
-		return folder
-	end
-
-	local partFolder = stack:match("...([^\\]+)\\")
-	if partFolder then
-		local partFolder_len = #partFolder
-		for i = 1, GetNumAddOns() do
-			local name = GetAddOnInfo(i)
-			if #name >= partFolder_len then
-				local partName = name:sub(-partFolder_len)
-				if partName == partFolder then
-					return name
-				end
-			end
-		end
-	end
-	return nil
-end
-
---[[---------------------------------------------------------------------------
-Returns:
-	string - the localized name of the given category.
-Arguments:
-	string - the English name of the category.
-Example:
-	local uf = Rock:GetLocalizedCategory("UnitFrame")
------------------------------------------------------------------------------]]
-function Rock:GetLocalizedCategory(name)
-	if type(name) ~= "string" then
-		error(("Bad argument #2 to `GetLocalizedCategory'. Expected %q, got %q."):format("string", type(name)), 2)
-	end
-	local cat = CATEGORIES[name]
-	if cat then
-		return cat
-	end
-	local name_lower = name:lower()
-	for k in pairs(CATEGORIES) do
-		if k:lower() == name_lower then
-			return k
-		end
-	end
-	return _G.UNKNOWN or "Unknown"
-end
-
-local weak = {__mode = 'kv'}
-
-Rock.recycleData = oldRock and oldRock.recycleData or {}
-local recycleData = Rock.recycleData
-if recycleData.pools then
-	setmetatable(recycleData.pools, weak)
-end
-if recycleData.debugPools then
-	setmetatable(recycleData.debugPools, weak)
-end
-if recycleData.newList then
-	setmetatable(recycleData.newList, weak)
-end
-if recycleData.newDict then
-	setmetatable(recycleData.newDict, weak)
-end
-if recycleData.newSet then
-	setmetatable(recycleData.newSet, weak)
-end
-if recycleData.del then
-	setmetatable(recycleData.del, weak)
-end
-
-local tmp = {}
-local function myUnpack(t, start)
-	if not start then
-		start = 1
-	end
-	local value = t[start]
-	if value == nil then
-		return
-	end
-	t[start] = nil
-	return value, myUnpack(t, start+1)
-end
-
---[[---------------------------------------------------------------------------
-Notes:
-	* Returns functions for the specified namespace based on what is provided.
-	* function types:
-	; "newList" : to create a list
-	; "newDict" : to create a dictionary
-	; "newSet" : to create a set
-	; "del" : to delete a table
-	; "unpackListAndDel" : deletes a table and returns what its contents were as a list, in order.
-	; "unpackSetAndDel" : deletes a table and returns what its contents were as a set, in no particular order.
-	; "unpackDictAndDel" : deletes a table and returns what its contents were as a dictionary, in no particular order.
-	* If you provide "Debug" as the last argument, then the namespace can be debugged with ''':DebugRecycle'''
-	* It is '''not recommended''' to use table recycling with tables that have more than 128 keys, as it is typically faster to let lua's garbage collector handle it.
-Arguments:
-	string - the namespace. ''Note: this doesn't necessarily have to be a string.''
-Example:
-	local newList, newDict, newSet, del, unpackListAndDel, unpackSetAndDel, unpackDictAndDel = Rock:GetRecyclingFunctions("MyNamespace", "newList", "newDict", "newSet", "del", "unpackListAndDel", "unpackSetAndDel", "unpackDictAndDel")
-
-	local t = newList('alpha', 'bravo') -- same as t = {'alpha', 'bravo'}
-	local u = newDict('alpha', 'bravo') -- same as t = {['alpha'] = 'bravo'}
-	local v = newSet('alpha', 'bravo') -- same as t = {['alpha'] = true, ['bravo'] = true}
-	t = del(t) -- you want to clear your reference as well as deleting.
-	u = del(u)
-	v = del(v)
-
-	-- for debugging
-	local newList = Rock:GetRecyclingFunctions("MyNamespace", "newList", "Debug")
-	local t = newList()
-	Rock:DebugRecycle("MyNamespace")
-	t = del(t)
-
-	-- unpacking functions
-	unpackListAndDel(newList(...)) => ...
-	unpackSetAndDel(newSet(...)) => ...
-	unpackDictAndDel(newDict(...)) => ...
-	newList(unpackListAndDel(t)) => t
-	newSet(unpackSetAndDel(t)) => t
-	newDict(unpackDictAndDel(t)) => t
-	-- as you can see, they are inverses of each other.
------------------------------------------------------------------------------]]
-function Rock:GetRecyclingFunctions(namespace, ...)
-	local pools = recycleData.pools
-	if not pools then
-		pools = setmetatable({}, weak)
-		recycleData.pools = pools
-	end
-	if namespace == "newList" or namespace == "newSet" or namespace == "newDict" or namespace == "del" or namespace == "unpackListAndDel" or namespace == "unpackSetAndDel" or namespace == "unpackDictAndDel" then
-		error(("Bad argument #2 to `GetRecyclingFunctions'. Cannot be %q"):format(namespace), 2)
-	end
-	local pool = pools[namespace]
-	if not pool then
-		pool = setmetatable({}, weak)
-		pools[namespace] = pool
-	end
-	local n = select('#', ...)
-	local debug = select(n, ...) == "Debug"
-	if debug then
-		n = n - 1
-		local debugPools = recycleData.debugPools
-		if not debugPools then
-			debugPools = setmetatable({}, weak)
-			recycleData.debugPools = debugPools
-		end
-		debug = debugPools[namespace]
-		if not debug then
-			debug = { num = 0 }
-			debugPools[namespace] = debug
-		end
-	elseif recycleData.debugPools and recycleData.debugPools[namespace] then
-		debug = recycleData.debugPools[namespace]
-	end
-	for i = 1, n do
-		local func = select(i, ...)
-		local recycleData_func = recycleData[func]
-		if not recycleData_func then
-			recycleData_func = setmetatable({}, weak)
-			recycleData[func] = recycleData_func
-		end
-		if func == "newList" then
-			local newList = recycleData_func[namespace]
-			if not newList then
-				function newList(...)
-					local t = next(pool)
-					local n = select('#', ...)
-					if t then
-						pool[t] = nil
-						for i = 1, n do
-							t[i] = select(i, ...)
-						end
-					else
-						t = { ... }
-					end
-
-					if debug then
-						debug[t] = debugstack(2)
-						debug.num = debug.num + 1
-					end
-
-					return t, n
-				end
-				recycleData_func[namespace] = newList
-			end
-			tmp[i] = newList
-		elseif func == "newDict" then
-			local newDict = recycleData_func[namespace]
-			if not newDict then
-				function newDict(...)
-					local t = next(pool)
-					if t then
-						pool[t] = nil
-					else
-						t = {}
-					end
-
-					for i = 1, select('#', ...), 2 do
-						t[select(i, ...)] = select(i+1, ...)
-					end
-
-					if debug then
-						debug[t] = debugstack(2)
-						debug.num = debug.num + 1
-					end
-
-					return t
-				end
-				recycleData_func[namespace] = newDict
-			end
-			tmp[i] = newDict
-		elseif func == "newSet" then
-			local newSet = recycleData_func[namespace]
-			if not newSet then
-				function newSet(...)
-					local t = next(pool)
-					if t then
-						pool[t] = nil
-					else
-						t = {}
-					end
-
-					for i = 1, select('#', ...) do
-						t[select(i, ...)] = true
-					end
-
-					if debug then
-						debug[t] = debugstack(2)
-						debug.num = debug.num + 1
-					end
-
-					return t
-				end
-				recycleData_func[namespace] = newSet
-			end
-			tmp[i] = newSet
-		elseif func == "del" then
-			local del = recycleData_func[namespace]
-			if not del then
-				function del(t)
-					if not t then
-						error(("Bad argument #1 to `del'. Expected %q, got %q."):format("table", type(t)), 2)
-					end
-					if pool[t] then
-						local _, ret = pcall(error, "Error, double-free syndrome.", 3)
-						geterrorhandler()(ret)
-					end
-					setmetatable(t, nil)
-					for k in pairs(t) do
-						t[k] = nil
-					end
-					t[true] = true
-					t[true] = nil
-					pool[t] = true
-
-					if debug then
-						debug[t] = nil
-						debug.num = debug.num - 1
-					end
-					return nil
-				end
-				recycleData_func[namespace] = del
-			end
-			tmp[i] = del
-		elseif func == "unpackListAndDel" then
-			local unpackListAndDel = recycleData_func[namespace]
-			if not unpackListAndDel then
-				local function f(t, start, finish)
-					if start > finish then
-						for k in pairs(t) do
-							t[k] = nil
-						end
-						t[true] = true
-						t[true] = nil
-						pool[t] = true
-						return
-					end
-					return t[start], f(t, start+1, finish)
-				end
-				function unpackListAndDel(t, start, finish)
-					if not t then
-						error(("Bad argument #1 to `unpackListAndDel'. Expected %q, got %q."):format("table", type(t)), 2)
-					end
-					if not start then
-						start = 1
-					end
-					if not finish then
-						finish = #t
-					end
-					setmetatable(t, nil)
-					if debug then
-						debug[t] = nil
-						debug.num = debug.num - 1
-					end
-					return f(t, start, finish)
-				end
-			end
-			tmp[i] = unpackListAndDel
-		elseif func == "unpackSetAndDel" then
-			local unpackSetAndDel = recycleData_func[namespace]
-			if not unpackSetAndDel then
-				local function f(t, current)
-					current = next(t, current)
-					if current == nil then
-						for k in pairs(t) do
-							t[k] = nil
-						end
-						t[true] = true
-						t[true] = nil
-						pool[t] = true
-						return
-					end
-					return current, f(t, current)
-				end
-				function unpackSetAndDel(t)
-					if not t then
-						error(("Bad argument #1 to `unpackListAndDel'. Expected %q, got %q."):format("table", type(t)), 2)
-					end
-					setmetatable(t, nil)
-					if debug then
-						debug[t] = nil
-						debug.num = debug.num - 1
-					end
-					return f(t, nil)
-				end
-			end
-			tmp[i] = unpackSetAndDel
-		elseif func == "unpackDictAndDel" then
-			local unpackDictAndDel = recycleData_func[namespace]
-			if not unpackDictAndDel then
-				local function f(t, current)
-					local value
-					current, value = next(t, current)
-					if current == nil then
-						for k in pairs(t) do
-							t[k] = nil
-						end
-						t[true] = true
-						t[true] = nil
-						pool[t] = true
-						return
-					end
-					return current, value, f(t, current)
-				end
-				function unpackDictAndDel(t)
-					if not t then
-						error(("Bad argument #1 to `unpackListAndDel'. Expected %q, got %q."):format("table", type(t)), 2)
-					end
-					setmetatable(t, nil)
-					if debug then
-						debug[t] = nil
-						debug.num = debug.num - 1
-					end
-					return f(t, nil)
-				end
-			end
-			tmp[i] = unpackDictAndDel
-		else
-			error(("Bad argument #%d to `GetRecyclingFunctions': %q, %q, %q, %q, %q, %q, or %q expected, got %s"):format(i+2, "newList", "newDict", "newSet", "del", "unpackListAndDel", "unpackSetAndDel", "unpackDictAndDel", type(func) == "string" and ("%q"):format(func) or tostring(func)), 2)
-		end
-	end
-	return myUnpack(tmp)
-end
-
---[[---------------------------------------------------------------------------
-Notes:
-	* Prints information about the specified recycling namespace, including what tables are still in play and where they come from and how many there are.
-	* This goes in tandem with ''':GetRecyclingFunctions'''
-Arguments:
-	string - the namespace. ''Note: this doesn't necessarily have to be a string.''
-Example:
-	local newList = Rock:GetRecyclingFunctions("MyNamespace", "newList", "Debug")
-	local t = newList()
-	Rock:DebugRecycle("MyNamespace")
-	t = del(t)
------------------------------------------------------------------------------]]
-function Rock:DebugRecycle(namespace)
-	local debug = recycleData.debugPools and recycleData.debugPools[namespace]
-	if not debug then
-		return
-	end
-	for k, v in pairs(debug) do
-		if k ~= "num" then
-			_G.DEFAULT_CHAT_FRAME:AddMessage(v)
-			_G.DEFAULT_CHAT_FRAME:AddMessage("------")
-		end
-	end
-	_G.DEFAULT_CHAT_FRAME:AddMessage(("%s: %d tables in action."):format(tostring(namespace), debug.num))
-end
-
-local newList, del, unpackListAndDel, unpackDictAndDel = Rock:GetRecyclingFunctions(MAJOR_VERSION, "newList", "del", "unpackListAndDel", "unpackDictAndDel")
-
---[[---------------------------------------------------------------------------
-Notes:
-	* Adds a unit test for the specified namespace
-	* The function provided is called, and it should be where tests are performed, if a problem occurs, an error should fire. If no problems occur, it should return silently.
-	* You can have as many tests per namespace as you want.
-Arguments:
-	string - the namespace.
-	function - the function to call.
-Example:
-	Rock:AddUnitTest("LibMonkey-1.0", function()
-		local LibMonkey = Rock("LibMonkey-1.0")
-		assert(LibMonkey:Fling() == "Poo")
-	end)
------------------------------------------------------------------------------]]
-function Rock:AddUnitTest(namespace, func)
-	if not isStandalone then
-		return
-	end
-	if type(namespace) ~= "string" then
-		error(("Bad argument #2 to `AddUnitTest'. Expected %q, got %q."):format("string", type(namespace)), 2)
-	end
-	if namespace:find("^Lib[A-Z]") then
-		local addon = figureCurrentAddon(2)
-		if addon ~= namespace then
-			return
-		end
-	end
-	if type(func) ~= "function" then
-		error(("Bad argument #3 to `AddUnitTest'. Expected %q, got %q."):format("function", type(func)), 2)
-	end
-	local addon = figureCurrentAddon(2)
-	if libraries[namespace] and addon ~= namespace then
-		-- only work on standalone libraries.
-		return
-	end
-	local unitTests_namespace = unitTests[namespace]
-	if not unitTests_namespace then
-		unitTests_namespace = newList()
-		unitTests[namespace] = unitTests_namespace
-	end
-	if not unitTests_namespace.addon then
-		unitTests_namespace.addon = addon
-	end
-	if unitTestDB and not unitTestDB[namespace] then
-		return
-	end
-	unitTests_namespace[#unitTests_namespace+1] = func
-end
-
-local LibRockEvent
-local LibRockModuleCore
-local OpenDonationFrame, OpenIssueFrame
-function Rock:OnLibraryLoad(major, library)
-	if major == "LibRockEvent-1.0" then
-		LibRockEvent = library
-		LibRockEvent:Embed(Rock)
-	elseif major == "LibRockModuleCore-1.0" then
-		LibRockModuleCore = library
-	elseif major == "LibRockConfig-1.0" then
-		if isStandalone then
-			library.rockOptions.args.advanced = {
-				type = 'group',
-				groupType = 'inline',
-				name = L["Advanced options"],
-				desc = L["Advanced options for developers and power users."],
-				order = -1,
-				args = {
-					unitTests = {
-						type = 'multichoice',
-						name = L["Unit tests"],
-						desc = L["Enable unit tests to be run. This is for developers only.\n\nYou must ReloadUI for changes to take effect."],
-						get = function(key)
-							return unitTestDB[key]
-						end,
-						set = function(key, value)
-							unitTestDB[key] = value or nil
-						end,
-						choices = function()
-							local t = newList()
-							for k in pairs(unitTests) do
-								t[k] = k
-							end
-							return "@dict", unpackDictAndDel(t)
-						end
-					},
-					contracts = {
-						type = 'boolean',
-						name = L["Contracts"],
-						desc = L["Enable contracts to be run. This is for developers and anyone wanting to file a bug. Do not file a bug unless contracts are enabled. This will slightly slow down your addons if enabled."],
-						get = function()
-							return enableContracts
-						end,
-						set = function(value)
-							_G.LibRock_1_0DB.contracts = value or nil
-							enableContracts = value
-						end,
-					}
-				}
-			}
-		end
-		library.rockOptions.args.reloadui = {
-			type = 'execute',
-			name = L["Reload UI"],
-			desc = L["Reload the User Interface for some changes to take effect."],
-			buttonText = L["Reload"],
-			func = function()
-				_G.ReloadUI()
-			end,
-			order = -2,
-		}
-		Rock.donate = "Paypal:ckknight AT gmail DOT com"
-		library.rockOptions.args.donate = {
-			type = 'execute',
-			name = L["Give donation"],
-			buttonText = L["Donate"],
-			desc = L["Give a much-needed donation to the author of this addon."],
-			func = OpenDonationFrame,
-			passValue = Rock,
-			order = -3,
-		}
-		Rock.issueTracker = "Wowace:10027"
-		library.rockOptions.args.issue = {
-			type = 'execute',
-			name = L["File issue"],
-			buttonText = L["Report"],
-			desc = L["File a bug or request a new feature or an improvement to this addon."],
-			func = OpenIssueFrame,
-			passValue = Rock,
-			order = -4,
-		}
-	end
-end
-
-addon_mt.__index = {}
-local addon_mt___index = addon_mt.__index
---[[---------------------------------------------------------------------------
-#FORCE_DOC
-Notes:
-	* This is exported to all addons.
-	* This information is retrieved from LibRockModuleCore-1.0 if it is a module, otherwise from LibRockDB-1.0 if it uses that as a mixin, otherwise it keeps a variable locally.
-Returns:
-	boolean - whether the addon is in an active state or not.
-Example:
-	local active = MyAddon:IsActive()
------------------------------------------------------------------------------]]
-function addon_mt___index:IsActive()
-	if LibRockModuleCore then
-		local core = LibRockModuleCore:HasModule(self)
-		if core then
-			return core:IsModuleActive(self)
-		end
-	end
-
-	local self_db = self.db
-	if self_db then
-		local disabled
-		local self_db_raw = self_db.raw
-		if self_db_raw then
-			local self_db_raw_disabled = self_db_raw.disabled
-			if self_db_raw_disabled then
-				local profile = type(self.GetProfile) == "function" and select(2, self:GetProfile()) or false
-				disabled = self_db_raw_disabled[profile]
-			end
-		else
-			return false
-		end
-		return not disabled
-	end
-
-	return not inactiveAddons[self]
-end
---[[---------------------------------------------------------------------------
-#FORCE_DOC
-Notes:
-	* This is exported to all addons.
-	* If it enables the addon, it will call :OnEnable(first) on the addon and :OnEmbedEnable(addon, first) on all its mixins.
-	* If it disables the addon, it will call :OnDisable(first) on the addon and :OnEmbedDisable(addon, first) on all its mixins.
-	* This information is stored by LibRockModuleCore-1.0 if it is a module, otherwise from LibRockDB-1.0 if it uses that as a mixin, otherwise it keeps a variable locally.
-Arguments:
-	[optional] boolean - whether the addon should be in an active state or not. Default: not :IsActive()
-Returns:
-	boolean - whether the addon is in an active state or not.
-Example:
-	MyAddon:ToggleActive() -- switch
-	MyAddon:ToggleActive(true) -- force on
-	MyAddon:ToggleActive(false) -- force off
------------------------------------------------------------------------------]]
-function addon_mt___index:ToggleActive(state)
-	if state and state ~= true then
-		error(("Bad argument #2 to `ToggleActive'. Expected %q or %q, got %q."):format("boolean", "nil", type(state)), 2)
-	end
-	if LibRockModuleCore then
-		local core = LibRockModuleCore:HasModule(self)
-		if core then
-			return core:ToggleModuleActive(self, state)
-		end
-	end
-
-	local self_db = self.db
-	if self_db then
-		local self_db_raw = self_db.raw
-		if not self_db_raw then
-			error("Error saving to database with `ToggleActive'. db.raw not available.", 2)
-		end
-		local self_db_raw_disabled = self_db_raw.disabled
-		if not self_db_raw_disabled then
-			self_db_raw_disabled = newList()
-			self_db_raw.disabled = self_db_raw_disabled
-		end
-		local profile = type(self.GetProfile) == "function" and select(2, self:GetProfile()) or false
-		if state == nil then
-			state = not not self_db_raw_disabled[profile]
-		elseif (not self_db_raw_disabled[profile]) == state then
-			return
-		end
-		self_db_raw_disabled[profile] = not state or nil
-		if next(self_db_raw_disabled) == nil then
-			self_db_raw.disabled = del(self_db_raw_disabled)
-		end
-	else
-		if state == nil then
-			state = not not inactiveAddons[self]
-		elseif (not inactiveAddons[self]) == state then
-			return
-		end
-		inactiveAddons[self] = not state or nil
-	end
-
-	Rock:RecheckEnabledStates()
-
-	return state
-end
-
-local function noop() end
-
-do
-	local preconditions = setmetatable({}, weakKey)
-	local postconditions = setmetatable({}, weakKey)
-	local postconditionsOld = setmetatable({}, weakKey)
-
-	local currentMethod = nil
-
-	local function hook(object, method)
-		local object_method = object[method]
-		object[method] = function(...)
-			local pre = preconditions[object_method]
-			local post = postconditions[object_method]
-			if pre then
-				local old_currentMethod = currentMethod
-				currentMethod = method
-				pre(...)
-				currentMethod = old_currentMethod
-			end
-			if not post then
-				return object_method(...)
-			end
-			local oldFunc = postconditionsOld[object_method]
-			local old
-			if oldFunc then
-				old = newList()
-				oldFunc(old, ...)
-			end
-
-			local old_currentMethod = currentMethod
-			currentMethod = nil
-			local ret, n = newList(object_method(...))
-
-			currentMethod = method
-			if old then
-				post(old, ret, ...)
-				old = del(old)
-			else
-				post(ret, ...)
-			end
-			currentMethod = old_currentMethod
-			return unpackListAndDel(ret, 1, n)
-		end
-	end
-
-	local function precondition(object, method, func)
-		if type(object) ~= "table" then
-			error(("Bad argument #1 to `precondition'. Expected %q, got %q."):format("table", type(object)), 2)
-		end
-		if type(object[method]) ~= "function" then
-			error(("Method %q not found on object %s. Expected %q, got %q."):format(tostring(method), tostring(object), "function", type(object[method])), 2)
-		end
-		if type(func) ~= "function" then
-			error(("Bad argument #3 to `precondition'. Expected %q, got %q."):format("function", type(func)), 2)
-		end
-
-		local object_method = object[method]
-		if preconditions[object_method] then
-			error("Cannot call `preconditon' on the same method twice.", 2)
-		end
-		preconditions[object_method] = func
-
-		if not postconditions[object_method] then
-			hook(object, method)
-		end
-	end
-
-	local function postcondition(object, method, func, fillOld)
-		if type(object) ~= "table" then
-			error(("Bad argument #1 to `postcondition'. Expected %q, got %q."):format("table", type(object)), 2)
-		end
-		if type(object[method]) ~= "function" then
-			error(("Method %q not found on object %s. Expected %q, got %q."):format(tostring(method), tostring(object), "function", type(object[method])), 2)
-		end
-		if type(func) ~= "function" then
-			error(("Bad argument #3 to `postcondition'. Expected %q, got %q."):format("function", type(func)), 2)
-		end
-		if fillOld and type(fillOld) ~= "function" then
-			error(("Bad argument #4 to `postcondition'. Expected %q or %q, got %q."):format("function", "nil", type(func)), 2)
-		end
-
-		local object_method = object[method]
-		if postconditions[object_method] then
-			error("Cannot call `postcondition' on the same method twice.", 2)
-		end
-		postconditions[object_method] = func
-		postconditionsOld[object_method] = fillOld
-
-		if not preconditions[object_method] then
-			hook(object, method)
-		end
-	end
-
-	local function argCheck(value, position, ...)
-		if not currentMethod then
-			error("Cannot call `argCheck' outside of a pre/post-condition.", 2)
-		end
-		if type(position) ~= "number" then
-			error(("Bad argument #2 to `argCheck'. Expected %q, got %q"):format("number", type(position)), 2)
-		end
-		local type_value = type(value)
-		for i = 1, select('#', ...) do
-			local v = select(i, ...)
-			if type(v) ~= "string" then
-				error(("Bad argument #%d to `argCheck'. Expected %q, got %q"):format(i+1, "string", type(v)), 2)
-			end
-			if v == type_value then
-				return
-			end
-		end
-		local t = newList(...)
-		t[#t] = nil
-		for i,v in ipairs(t) do
-			t[i] = ("%q"):format(v)
-		end
-		local s
-		if #t == 0 then
-			s = ("%q"):format((...))
-		elseif #t == 1 then
-			s = ("%q or %q"):format(...)
-		else
-			s = table_concat(t, ", ") .. ", or " .. ("%q"):format(select(#t+1, ...))
-		end
-		t = del(t)
-
-		error(("Bad argument #%d to `%s'. Expected %s, got %q."):format(position, tostring(currentMethod), s, type_value), 4)
-	end
-
-	--[[---------------------------------------------------------------------------
-	Notes:
-		* Returns functions for the specified namespace based on what is provided.
-		* function types:
-		; "precondition" : to set the pre-condition for a method.
-		; "postcondition" : to set the post-condition for a method.
-		; "argCheck" : to check the type of an argument, to be executed within a pre-condition.
-		* preconditon is in the form of <tt>precondition(object, "methodName", func(self, ...))</tt>
-		* postcondition is in the form of either <tt>postcondition(object, "methodName", func(returnValues, self, ...))</tt> or <tt>postcondition(object, "methodName", func(oldValues, returnValues, self, ...), populateOld(oldValues, self, ...))</tt>
-		** returnValues is the list of return values, empty if no return values were sent.
-		** if the populateOld function is provided, then the empty oldValues table is provided and expected to be filled, and then given to the func.
-		* argCheck is in the form of <tt>argCheck(value, n, "type1" [, "type2", ...])</tt>
-		** value is the value provided to the function you're checking.
-		** n is the argument position. ''Note: 1 is the position of `self'. 2 would be the first "real" position.''
-		** the tuple of types can be any string, but specifically "nil", "boolean", "string", "number", "function", "userdata", "table", etc.
-	Arguments:
-		string - the namespace. ''Note: this doesn't necessarily have to be a string.''
-	Example:
-		local precondition, postcondition, argCheck = Rock:GetRecyclingFunctions("Stack", "precondition", "postcondition", "argCheck")
-
-		local stack = {}
-		stack.IsEmpty = function(self)
-			return self[1] == nil
-		end
-		stack.GetLength = function(self)
-			return #self
-		end
-		stack.Push = function(self, value)
-			self[#self+1] = value
-		end
-		precondition(stack, "Push", function(self, value)
-			argCheck(value, 2, "string") -- only accept strings, no other values
-		end)
-		postcondition(stack, "Push", function(old, ret, self, value)
-			assert(self:GetLength() == old.length+1)
-			assert(not self:IsEmpty())
-		end, function(old, self)
-			old.length = self:GetLength()
-		end)
-		stack.Pop = function(self)
-			local value = self[#self]
-			self[#self] = nil
-			return value
-		end
-		precondition(stack, "Pop", function(self)
-			assert(self:GetLength() >= 1)
-		end)
-		postcondition(stack, "Pop", function(old, ret, self)
-			assert(self:GetLength() == old.length-1)
-		end, function(old, self)
-			old.length = self:GetLength()
-		end)
-		stack.Peek = function(self)
-			return self[#self]
-		end
-		precondition(stack, "Peek", function(self)
-			assert(self:GetLength() >= 1)
-		end)
-		postcondition(stack, "Peek", function(old, ret, self)
-			assert(self:GetLength() == old.length)
-		end, function(old, self)
-			old.length = self:GetLength()
-		end)
-
-		local t = setmetatable({}, {__index=stack})
-		t:Push("Alpha")
-		t:Push("Bravo")
-		t:Push(5) -- error, only strings
-		assert(t:Pop() == "Bravo")
-		assert(t:Pop() == "Alpha")
-		t:Pop() -- error, out of values
-	-----------------------------------------------------------------------------]]
-	function Rock:GetContractFunctions(namespace, ...)
-		if namespace == "precondition" or namespace == "postcondition" or namespace == "argCheck" then
-			error(("Bad argument #2 to `GetContractFunctions'. Cannot be %q."):format(namespace), 2)
-		end
-		local t = newList()
-		if enableContracts then
-			for i = 1, select('#', ...) do
-				local v = select(i, ...)
-				if v == "precondition" then
-					t[i] = precondition
-				elseif v == "postcondition" then
-					t[i] = postcondition
-				elseif v == "argCheck" then
-					t[i] = argCheck
-				else
-					error(("Bad argument #%d to `GetContractFunctions'. Expected %q, %q, or %q, got %q."):format(i+2, "precondition", "postcondition", "argCheck", tostring(v)))
-				end
-			end
-		else
-			for i = 1, select('#', ...) do
-				t[i] = noop
-			end
-		end
-		return unpackListAndDel(t)
-	end
-end
-
---[[---------------------------------------------------------------------------
-Notes:
-	* convert a revision string to a number
-Arguments:
-	string - revision string
-Returns:
-	string or number - the string given or the number retrieved from it.
------------------------------------------------------------------------------]]
-local function coerceRevisionToNumber(version)
-	if type(version) == "string" then
-		return tonumber(version:match("(%-?%d+)")) or version
-	else
-		return version
-	end
-end
-
---[[---------------------------------------------------------------------------
-Notes:
-	* try to enable the standalone library specified
-Arguments:
-	string - name of the library.
-Returns:
-	boolean - whether the library is properly enabled and loadable.
------------------------------------------------------------------------------]]
-local function TryToEnable(addon)
-	local islod = IsAddOnLoadOnDemand(addon)
-	if islod then
-		local _, _, _, enabled = GetAddOnInfo(addon)
-		EnableAddOn(addon)
-		local _, _, _, _, loadable = GetAddOnInfo(addon)
-		if not loadable and not enabled then
-			DisableAddOn(addon)
-		end
-
-		return loadable
-	end
-end
-
---[[---------------------------------------------------------------------------
-Notes:
-	* try to load the standalone library specified
-Arguments:
-	string - name of the library.
-Returns:
-	boolean - whether the library is loaded.
------------------------------------------------------------------------------]]
-local function TryToLoadStandalone(major)
-	major = major:lower()
-	if scannedLibraries[major] then
-		return
-	end
-	scannedLibraries[major] = true
-	local name, _, _, enabled, loadable, state = GetAddOnInfo(major)
-	if state == "MISSING" or not IsAddOnLoadOnDemand(major) then
-		-- backwards compatibility for X-AceLibrary
-		local field = "X-AceLibrary-" .. major
-		local loaded
-		for i = 1, GetNumAddOns() do
-			if GetAddOnMetadata(i, field) then
-				name, _, _, enabled, loadable = GetAddOnInfo(i)
-
-				loadable = (enabled and loadable) or TryToEnable(name)
-				if loadable then
-					loaded = true
-					LoadAddOn(name)
-				end
-			end
-		end
-
-		return loaded
-	elseif (enabled and loadable) or TryToEnable(major) then
-		LoadAddOn(major)
-		return true
-	else
-		return false
-	end
-end
-
---[[---------------------------------------------------------------------------
-Notes:
-	* Return the LibStub library, casing is unimportant.
-Arguments:
-	string - name of the library.
-Returns:
-	table or nil - library
-	number - minor version
------------------------------------------------------------------------------]]
-local function GetLibStubLibrary(major)
-	local lib, minor = LibStub:GetLibrary(major, true)
-	if lib then
-		return lib, minor
-	end
-	major = major:lower()
-	for m, lib in LibStub:IterateLibraries() do
-		if m:lower() == major then
-			return LibStub:GetLibrary(m)
-		end
-	end
-	return nil, nil
-end
-
-local finishLibraryRegistration
---[[---------------------------------------------------------------------------
-Notes:
-	* create a new library if the version provided is not out of date.
-Arguments:
-	string - name of the library.
-	number - version of the library.
-Returns:
-	library, oldLibrary
-	* table or nil - the library with which to manipulate
-	* table or nil - the old version of the library to upgrade from
-Example:
-	local LibMonkey, oldLib = Rock:NewLibrary("LibMonkey-1.0", 50)
-	if not LibMonkey then
-		-- opt out now, out of date
-		return
-	end
------------------------------------------------------------------------------]]
-function Rock:NewLibrary(major, version)
-	if type(major) ~= "string" then
-		error(("Bad argument #2 to `NewLibrary'. Expected %q, got %q."):format("string", type(major)), 2)
-	end
-	if not major:match("^Lib[A-Z][A-Za-z%d%-]*%-%d+%.%d+$") then
-		error(("Bad argument #2 to `NewLibrary'. Must match %q, got %q."):format("^Lib[A-Z][A-Za-z%d%-]*%-%d+%.%d+$", major), 2)
-	end
-	TryToLoadStandalone(major)
-	version = coerceRevisionToNumber(version)
-	if type(version) ~= "number" then
-		error(("Bad argument #3 to `NewLibrary'. Expected %q, got %q."):format("number", type(version)), 2)
-	end
-	local library, oldMinor = LibStub:GetLibrary(major, true)
-	if oldMinor and oldMinor >= version then
-		-- in case LibStub is acting funny
-		return nil, nil
-	end
-	local library, oldMinor = LibStub:NewLibrary(major, version)
-	if not library then
-		return nil, nil
-	end
-	local unitTests_major = unitTests[major]
-	if unitTests_major then
-		for k,v in pairs(unitTests_major) do
-			unitTests_major[k] = nil
-		end
-	end
-	for k, v in pairs(recycleData) do
-		v[major] = nil
-	end
-	local mixinToObject_library = mixinToObject[library]
-
-	local oldLib
-	if oldMinor then
-		-- previous version exists
-		local mixins = newList()
-		for mixin, objectSet in pairs(mixinToObject) do
-			if objectSet[library] then
-				mixins[mixin] = true
-			end
-		end
-		for mixin in pairs(mixins) do
-			mixin:Unembed(library)
-		end
-		mixins = del(mixins)
-		oldLib = newList()
-		for k, v in pairs(library) do
-			oldLib[k] = v
-			library[k] = nil
-		end
-		setmetatable(oldLib, getmetatable(library))
-		setmetatable(library, nil)
-	end
-	finishLibraryRegistration(major, version, library, figureCurrentAddon(2))
-
-	return library, oldLib
-end
-function finishLibraryRegistration(major, version, library, folder)
-	library.name = major
-
-	libraries[major] = library
-	pendingLibraries[library] = folder
-	local exportedMethods_library = exportedMethods[library]
-	if exportedMethods_library then
-		local mixinToObject_library = mixinToObject[library]
-		if mixinToObject_library then
-			for object in pairs(mixinToObject_library) do
-				for _,v in ipairs(exportedMethods_library) do
-					object[v] = nil
-				end
-			end
-		end
-		exportedMethods[library] = del(exportedMethods_library)
-	end
-	if library ~= Rock then
-		Rock:Embed(library)
-	end
-
-	frame:Show()
-end
-if not oldRock then
-	finishLibraryRegistration(MAJOR_VERSION, MINOR_VERSION, Rock, figureCurrentAddon(1))
-end
-
--- #NODOC
-local function __removeLibrary(libName)
-	libraries[libName] = nil
-	if LibStub.libs then
-		LibStub.libs[libName] = nil
-	end
-	if LibStub.minors then
-		LibStub.minors[libName] = nil
-	end
-	local lastCount
-	repeat
-		lastCount = collectgarbage('count')
-		collectgarbage('collect')
-	until lastCount == collectgarbage('count')
-end
-local function run(_,a)
-	if a < 1/30 then
-		collectgarbage('step')
-	end
-end
-
---[[---------------------------------------------------------------------------
-Notes:
-	* properly finalizes the library, essentially stating that it has loaded properly.
-	* This will call :OnLibraryLoad("major", library) on every other library
-	* This will also call :OnLibraryLoad("major", library) on the library provided, using every other library as the arguments.
-	* An error will occur if this is not done before ADDON_LOADED.
-Arguments:
-	string - name of the library.
-Example:
-	local LibMonkey, oldLib = Rock:NewLibrary("LibMonkey-1.0", 50)
-	if not LibMonkey then
-		-- opt out now, out of date
-		return
-	end
-	Rock:FinalizeLibrary("LibMonkey-1.0")
------------------------------------------------------------------------------]]
-function Rock:FinalizeLibrary(major)
-	if type(major) ~= "string" then
-		error(("Bad argument #2 to `FinalizeLibrary'. Expected %q, got %q."):format("string", type(major)), 2)
-	end
-	local library = libraries[major]
-	if not library then
-		error(("Bad argument #2 to `FinalizeLibrary'. %q is not a library."):format("string", major), 2)
-	end
-	pendingLibraries[library] = nil
-	local library_OnLibraryLoad = library.OnLibraryLoad
-	if library_OnLibraryLoad then
-		for maj, lib in LibStub:IterateLibraries() do -- for all libraries
-			if maj ~= major then
-				local success, ret = pcall(library_OnLibraryLoad, library, maj, lib)
-				if not success then
-					geterrorhandler()(ret)
-					break
-				end
-			end
-		end
-	end
-	if finalizedLibraries[library] then
-		return
-	end
-	finalizedLibraries[library] = true
-	for maj, lib in pairs(libraries) do -- just Rock libraries
-		if maj ~= major then
-			local lib_OnLibraryLoad = lib.OnLibraryLoad
-			if lib_OnLibraryLoad then
-				local success, ret = pcall(lib_OnLibraryLoad, lib, major, library)
-				if not success then
-					geterrorhandler()(ret)
-				end
-			end
-		end
-	end
-	if LibRockEvent then
-		self:DispatchEvent("LibraryLoad", major, library)
-	end
-end
-
-local function manualFinalize(major, library)
-	if libraries[major] then -- non-Rock libraries only
-		return
-	end
-	if finalizedLibraries[library] then -- don't do it twice
-		return
-	end
-	finalizedLibraries[library] = true
-	for maj, lib in pairs(libraries) do -- just Rock libraries
-		if maj ~= major then
-			local lib_OnLibraryLoad = lib.OnLibraryLoad
-			if lib_OnLibraryLoad then
-				local success, ret = pcall(lib_OnLibraryLoad, lib, major, library)
-				if not success then
-					geterrorhandler()(ret)
-				end
-			end
-		end
-	end
-	if LibRockEvent then
-		Rock:DispatchEvent("LibraryLoad", major, library)
-	end
-end
-
---[[---------------------------------------------------------------------------
-Arguments:
-	string - name of the library.
-	[optional] boolean - whether to not load a library if it is not found. Default: false
-	[optional] boolean - whether to not error if a library is not found. Default: false
-Returns:
-	library
-	* table or nil - the library requested
-Example:
-	local LibMonkey = Rock:GetLibrary("LibMonkey-1.0")
-	-- or
-	local LibMonkey = Rock("LibMonkey-1.0")
------------------------------------------------------------------------------]]
-function Rock:GetLibrary(major, dontLoad, dontError)
-	if type(major) ~= "string" then
-		error(("Bad argument #2 to `GetLibrary'. Expected %q, got %q."):format("string", type(major)), 2)
-	end
-	if dontLoad and dontLoad ~= true then
-		error(("Bad argument #3 to `GetLibrary'. Expected %q or %q, got %q."):format("boolean", "nil", type(dontLoad)), 2)
-	end
-	if dontError and dontError ~= true then
-		error(("Bad argument #4 to `GetLibrary'. Expected %q or %q, got %q."):format("boolean", "nil", type(dontError)), 2)
-	end
-	if not dontLoad then
-		TryToLoadStandalone(major)
-	end
-
-	local library = GetLibStubLibrary(major)
-	if not library then
-		if dontError then
-			return nil
-		end
-		error(("Library %q not found."):format(major), 2)
-	end
-
-	return library
-end
-
-setmetatable(Rock, { __call = Rock.GetLibrary })
-
---[[---------------------------------------------------------------------------
-Arguments:
-	string - name of the library.
-Returns:
-	boolean - whether the library exists and is a proper mixin which can be embedded.
-Example:
-	local isMixin = Rock:IsLibraryMixin("LibMonkey-1.0")
------------------------------------------------------------------------------]]
-function Rock:IsLibraryMixin(name)
-	local library = self:GetLibrary(name, false, true)
-	if not library then
-		return false
-	end
-	return not not exportedMethods[library]
-end
-
---[[---------------------------------------------------------------------------
-Arguments:
-	string - name of the library.
-	[optional] boolean - whether to not load a library if it is not found. Default: false
-Returns:
-	library
-	* table or nil - the library requested
-Example:
-	local hasLibMonkey = Rock:HasLibrary("LibMonkey-1.0")
------------------------------------------------------------------------------]]
-function Rock:HasLibrary(major, dontLoad)
-	if type(major) ~= "string" then
-		error(("Bad argument #2 to `HasLibrary'. Expected %q, got %q."):format("string", type(major)), 2)
-	end
-	if dontLoad and dontLoad ~= true then
-		error(("Bad argument #3 to `HasLibrary'. Expected %q or %q, got %q."):format("boolean", "nil", type(dontLoad)), 2)
-	end
-	if not dontLoad then
-		TryToLoadStandalone(major)
-	end
-	return not not GetLibStubLibrary(major)
-end
-
---[[---------------------------------------------------------------------------
-Notes:
-	* This is exported to all libraries
-Returns:
-	major, minor
-	* string - name of the library
-	* number - version of the library
-Example:
-	local major, minor = Rock:GetLibraryVersion() -- will be "LibRock-1.0", 12345
-	local major, minor = LibMonkey:GetLibraryVersion() -- will be "LibMonkey-1.0", 50
------------------------------------------------------------------------------]]
-function Rock:GetLibraryVersion()
-	if type(self) ~= "table" then
-		return nil, nil
-	end
-	local major
-	local name = self.name
-	if name and GetLibStubLibrary(name) == self then
-		major = name
-	else
-		for m, instance in LibStub:IterateLibraries() do
-			if instance == self then
-				major = m
-				break
-			end
-		end
-		if not major then
-			return nil, nil
-		end
-	end
-	local _, minor = GetLibStubLibrary(major)
-	return major, minor
-end
-
---[[---------------------------------------------------------------------------
-Returns:
-	an iterator to traverse all registered libraries.
-Example:
-	for major, library in Rock:IterateLibraries() do
-		-- do something with major and library
-	end
------------------------------------------------------------------------------]]
-function Rock:IterateLibraries()
-	return LibStub:IterateLibraries()
-end
-
---[[---------------------------------------------------------------------------
-Notes:
-	* This is exported to all libraries
-	* Allows you to set precisely what methods for the library to export.
-	* This automatically turns a library into a mixin.
-Arguments:
-	tuple - the list of method names to export.
-Example:
-	local LibMonkey = Rock:NewLibrary("LibMonkey-1.0", 50)
-	LibMonkey.FlingPoo = function(self)
-		return "Splat!"
-	end
-	LibMonkey:SetExportedMethods("FlingPoo")
-	-- later
-	local Darwin = Rock:NewAddon("Darwin", "LibMonkey-1.0")
-	assert(Darwin:FlingPoo() == "Splat!")
------------------------------------------------------------------------------]]
-function Rock:SetExportedMethods(...)
-	if exportedMethods[self] then
-		error("Cannot call `SetExportedMethods' more than once.", 2)
-	end
-	local t = newList(...)
-	if #t == 0 then
-		error("Must supply at least 1 method to `SetExportedMethods'.", 2)
-	end
-	for i,v in ipairs(t) do
-		if type(self[v]) ~= "function" then
-			error(("Bad argument #%d to `SetExportedMethods'. Method %q does not exist."):format(i+1, tostring(v)), 2)
-		end
-	end
-	exportedMethods[self] = t
-
-	local mixinToObject_library = mixinToObject[self]
-	if mixinToObject_library then
-		for object in pairs(mixinToObject_library) do
-			for _,method in ipairs(t) do
-				object[method] = self[method]
-			end
-		end
-	end
-end
-
---[[---------------------------------------------------------------------------
-Notes:
-	* This is exported to all libraries
-	* Embeds all the methods previously set to export onto a table.
-	* This will call :OnEmbed(object) on the library if it is available.
-Arguments:
-	table - the table with which to export methods onto.
-Returns:
-	The table provided, after embedding.
-Example:
-	local LibMonkey = Rock:NewLibrary("LibMonkey-1.0", 50)
-	LibMonkey.FlingPoo = function(self)
-		return "Splat!"
-	end
-	LibMonkey:SetExportedMethods("FlingPoo")
-	-- later
-	local Darwin = {}
-	Rock("LibMonkey-1.0"):Embed(Darwin)
-	assert(Darwin:FlingPoo() == "Splat!")
------------------------------------------------------------------------------]]
-function Rock:Embed(object)
-	if not exportedMethods[self]  then
-		error(("Cannot call `Embed' for library %q if `SetExportedMethods' has not been called."):format(tostring(self.name)), 2)
-	end
-	if type(object) ~= "table" then
-		error(("Bad argument #2 to `Embed'. Expected %q, got %q."):format("table", type(object)), 2)
-	end
-
-	for i,v in ipairs(exportedMethods[self]) do
-		if type(self[v]) ~= "function" then
-			error(("Problem embedding method %q from library %q. Expected %q, got %q."):format(tostring(v), better_tostring(self), "function", type(self[v])))
-		end
-		object[v] = self[v]
-	end
-
-	if not mixinToObject[self] then
-		-- weak because objects come and go
-		mixinToObject[self] = setmetatable(newList(), weakKey)
-	end
-	if mixinToObject[self][object] then
-		error(("Cannot embed library %q into the same object %q more than once."):format(better_tostring(self), better_tostring(object)), 2)
-	end
-	mixinToObject[self][object] = true
-	if type(rawget(object, 'mixins')) == "table" then
-		object.mixins[self] = true
-	end
-
-	local self_OnEmbed = self.OnEmbed
-	if self_OnEmbed then
-		local success, ret = pcall(self_OnEmbed, self, object)
-		if not success then
-			geterrorhandler()(ret)
-		end
-	end
-
-	return object
-end
-
---[[---------------------------------------------------------------------------
-Notes:
-	* This is exported to all libraries
-	* Unembeds all the methods previously set to export onto a table.
-	* This will error if the library is not embedded on the object
-	* This will call :OnUnembed(object) on the library if it is available.
-Arguments:
-	table - the table with which to export methods onto.
-Returns:
-	The table provided, after embedding.
-Example:
-	local LibMonkey = Rock:NewLibrary("LibMonkey-1.0", 50)
-	LibMonkey.FlingPoo = function(self)
-		return "Splat!"
-	end
-	LibMonkey:SetExportedMethods("FlingPoo")
-	-- later
-	local Darwin = {}
-	Rock("LibMonkey-1.0"):Embed(Darwin)
-	assert(Darwin:FlingPoo() == "Splat!")
-	Rock("LibMonkey-1.0"):Unembed(Darwin)
-	assert(Darwin.FlingPoo == nil)
------------------------------------------------------------------------------]]
-function Rock:Unembed(object)
-	if not exportedMethods[self]  then
-		error(("Cannot call `Unembed' for library %q if `SetExportedMethods' has not been called."):format(better_tostring(self)), 2)
-	end
-
-	if not mixinToObject[self] or not mixinToObject[self][object] then
-		error(("Cannot unembed library %q from object %q, since it is not embedded originally."):format(better_tostring(self), better_tostring(object)), 2)
-	end
-	local mixinToObject_self = mixinToObject[self]
-	mixinToObject_self[object] = nil
-	if not next(mixinToObject_self) then
-		mixinToObject[self] = del(mixinToObject_self)
-	end
-
-	local mixin_OnUnembed = self.OnUnembed
-	if mixin_OnUnembed then
-		local success, ret = pcall(mixin_OnUnembed, self, object)
-		if not success then
-			geterrorhandler()(ret)
-		end
-	end
-
-	for i,v in ipairs(exportedMethods[self]) do
-		object[v] = nil
-	end
-end
-
-local function embedAce2Mixin(mixin, object)
-	if not mixinToObject[mixin] then
-		mixinToObject[mixin] = setmetatable(newList(), weakKey)
-	end
-	mixinToObject[mixin][object] = true
-	mixin:embed(object)
-end
-
-local function embedLibStubMixin(mixin, object)
-	if not mixinToObject[mixin] then
-		mixinToObject[mixin] = setmetatable(newList(), weakKey)
-	end
-	mixinToObject[mixin][object] = true
-	mixin:Embed(object)
-end
-
---[[---------------------------------------------------------------------------
-Notes:
-	* create a new addon with the specified name.
-Arguments:
-	string - name of the addon.
-	tuple - list of mixins with which to embed into this addon.
-Returns:
-	addon
-	* table - the addon with which to manipulate
-Example:
-	local MyAddon = Rock:NewAddon("MyAddon", "Mixin-1.0", "OtherMixin-2.0")
------------------------------------------------------------------------------]]
-function Rock:NewAddon(name, ...)
-	if type(name) ~= "string" then
-		error(("Bad argument #2 to `NewAddon'. Expected %q, got %q"):format("string", type(name)), 2)
-	end
-	if name:match("^Lib[A-Z]") then
-		error(("Bad argument #2 to `NewAddon'. Cannot start with %q, got %q."):format("Lib", name), 2)
-	end
-	if self == Rock and name:match("_") then
-		error(("Bad argument #2 to `NewAddon'. Cannot contain underscores, got %q."):format(name), 2)
-	end
-
-	if addons[name] then
-		error(("Bad argument #2 to `NewAddon'. Addon %q already created."):format(name), 2)
-	end
-	local addon = setmetatable(newList(), addon_mt)
-	addon.name = name
-
-	local mixinSet = newList()
-
-	for i = 1, select('#', ...) do
-		local libName = select(i, ...)
-		if mixinSet[libName] then
-			error(("Bad argument #%d to `NewAddon'. %q already stated."):format(i+2, tostring(libName)), 2)
-		end
-		mixinSet[libName] = true
-		TryToLoadStandalone(libName)
-		local library = Rock:GetLibrary(libName, false, true)
-		if not library then
-			error(("Bad argument #%d to `NewAddon'. Library %q is not found."):format(i+2, tostring(libName)), 2)
-		end
-		
-		local style = 'rock'
-
-		if not exportedMethods[library] then
-			local good = false
-			if AceLibrary then
-				local AceOO = AceLibrary:HasInstance("AceOO-2.0", false) and AceLibrary("AceOO-2.0")
-				if AceOO.inherits(library, AceOO.Mixin) then
-					good = true
-					style = 'ace2'
-				end
-			end
-			if not good and type(rawget(library, 'Embed')) == "function" then
-				good = true
-				style = 'libstub'
-			end
-			if not good then
-				error(("Bad argument #%d to `NewAddon'. Library %q is not a mixin."):format(i+2, tostring(libName)), 2)
-			end
-		end
-
-		if library == Rock then
-			error(("Bad argument #%d to `NewAddon'. Cannot use %q as a mixin."):format(i+2, tostring(libName)), 2)
-		end
-
-		if style == 'rock' then
-			library:Embed(addon)
-		elseif style == 'ace2' then
-			embedAce2Mixin(library, addon)
-		elseif style == 'libstub' then
-			embedLibStubMixin(library, addon)
-		end
-	end
-
-	mixinSet = del(mixinSet)
-
-	addons[name] = addon
-	pendingAddons[#pendingAddons+1] = addon
-	pendingAddonsEnable[#pendingAddonsEnable+1] = addon
-	addonToFolder[addon] = figureCurrentAddon(self == Rock and 2 or 4)
-
-	frame:Show()
-
-	return addon
-end
-
---[[---------------------------------------------------------------------------
-Arguments:
-	string - name of the addon.
-Returns:
-	addon
-	* table or nil - the addon requested
-Example:
-	local MyAddon = Rock:GetAddon("MyAddon")
------------------------------------------------------------------------------]]
-function Rock:GetAddon(name)
-	if type(name) ~= "string" then
-		return nil
-	end
-	local addon = addons[name]
-	if addon then
-		return addon
-	end
-	name = name:lower()
-	for k, v in pairs(addons) do
-		if k:lower() == name then
-			return v
-		end
-	end
-	return nil
-end
-
---[[---------------------------------------------------------------------------
-Arguments:
-	string or table - name of the addon or the addon itself.
-Returns:
-	boolean - whether the addon requested exists.
-Example:
-	local hasMyAddon = Rock:HasAddon("MyAddon")
-	-- or
-	local hasMyAddon = Rock:HasAddon(MyAddon)
------------------------------------------------------------------------------]]
-function Rock:HasAddon(name)
-	if type(name) == "string" then
-		local addon = addons[name]
-		if addon then
-			return true
-		end
-		name = name:lower()
-		for k, v in pairs(addons) do
-			if k:lower() == name then
-				return true
-			end
-		end
-	elseif type(name) == "table" then
-		for k,v in pairs(addons) do
-			if v == name then
-				return true
-			end
-		end
-	end
-	return false
-end
-
---[[---------------------------------------------------------------------------
-Returns:
-	an iterator to traverse all addons created with Rock.
-Example:
-	for name, addon in Rock:IterateAddons() do
-		-- do something with name and addon
-	end
------------------------------------------------------------------------------]]
-function Rock:IterateAddons()
-	return pairs(addons)
-end
-
---[[---------------------------------------------------------------------------
-Arguments:
-	string - major version of the mixin library
-Returns:
-	an iterator to traverse all objects that the given mixin has embedded into
-Example:
-	local LibMonkey = Rock:NewLibrary("LibMonkey-1.0")
-	local Darwin = Rock:NewAddon("Darwin", "LibMonkey-1.0")
-	for object in LibMonkey:IterateMixinObjects("LibMonkey-1.0") do
-		assert(object == Darwin)
-	end
------------------------------------------------------------------------------]]
-function Rock:IterateMixinObjects(mixinName)
-	local mixin
-	if type(mixinName) == "table" then
-		mixin = mixinName
-	else
-		if type(mixinName) ~= "string" then
-			error(("Bad argument #2 to `IterateMixinObjects'. Expected %q or %q, got %q."):format("table", "string", type(mixinName)), 2)
-		end
-		mixin = libraries[mixinName]
-	end
-	local mixinToObject_mixin = mixinToObject[mixin]
-	if not mixinToObject_mixin then
-		return noop
-	end
-	return pairs(mixinToObject_mixin)
-end
-
-local function iter(object, mixin)
-	mixin = next(mixinToObject, mixin)
-	if not mixin then
-		return nil
-	elseif mixinToObject[mixin][object] then
-		return mixin
-	end
-	return iter(object, mixin) -- try next mixin
-end
---[[---------------------------------------------------------------------------
-Returns:
-	an iterator to traverse all mixins that an object has embedded
-Example:
-	local LibMonkey = Rock:NewLibrary("LibMonkey-1.0")
-	local Darwin = Rock:NewAddon("Darwin", "LibMonkey-1.0")
-	for mixin in Rock:IterateObjectMixins(Darwin) do
-		assert(mixin == LibMonkey)
-	end
------------------------------------------------------------------------------]]
-function Rock:IterateObjectMixins(object)
-	if type(object) ~= "table" then
-		error(("Bad argument #2 to `IterateObjectMixins'. Expected %q, got %q."):format("table", type(object)), 2)
-	end
-	return iter, object, nil
-end
-
---[[---------------------------------------------------------------------------
-Arguments:
-	table - the object to check
-	string - the mixin to check
-Returns:
-	boolean - whether the object has the given mixin embedded into it.
-Example:
-	local LibMonkey = Rock:NewLibrary("LibMonkey-1.0")
-	local Darwin = Rock:NewAddon("Darwin", "LibMonkey-1.0")
-	assert(Rock:DoesObjectUseMixin(Darwin, "LibMonkey-1.0"))
------------------------------------------------------------------------------]]
-function Rock:DoesObjectUseMixin(object, mixinName)
-	if type(object) ~= "table" then
-		error(("Bad argument #2 to `IterateObjectMixins'. Expected %q, got %q."):format("table", type(object)), 2)
-	end
-	local mixin
-	if type(mixinName) == "table" then
-		mixin = mixinName
-	else
-		if type(mixinName) ~= "string" then
-			error(("Bad argument #3 to `IterateMiDoesObjectUseMixininObjects'. Expected %q or %q, got %q."):format("table", "string", type(mixinName)), 2)
-		end
-		mixin = libraries[mixinName]
-	end
-	if not mixin then
-		return false
-	end
-
-	local mixinToObject_mixin = mixinToObject[mixin]
-	if not mixinToObject_mixin then
-		return false
-	end
-	return not not mixinToObject_mixin[object]
-end
-
-Rock.UID_NUM = oldRock and oldRock.UID_NUM or 0
---[[---------------------------------------------------------------------------
-Notes:
-	* This UID is not unique across sessions. If you save a UID in a saved variable, the same UID can be generated in another session.
-Returns:
-	number - a unique number.
-Example:
-	local UID = Rock:GetUID()
------------------------------------------------------------------------------]]
-function Rock:GetUID()
-	local num = Rock.UID_NUM + 1
-	Rock.UID_NUM = num
-	return num
-end
-
-local function unobfuscateEmail(email)
-	return email:gsub(" AT ", "@"):gsub(" DOT ", ".")
-end
-local function fix(char)
-	return ("%%%02x"):format(char:byte())
-end
-local function urlencode(text)
-	return text:gsub("[^0-9A-Za-z]", fix)
-end
-
-local url
-local function makeURLFrame()
-	makeURLFrame = nil
-	local function bumpFrameLevels(frame, amount)
-		frame:SetFrameLevel(frame:GetFrameLevel()+amount)
-		local children = newList(frame:GetChildren())
-		for _,v in ipairs(children) do
-			bumpFrameLevels(v, amount)
-		end
-		children = del(children)
-	end
-	-- some code borrowed from Prat here
-	StaticPopupDialogs["ROCK_SHOW_URL"] = {
-		text = not IsMacClient() and L["Press Ctrl-C to copy, then Alt-Tab out of the game, open your favorite web browser, and paste the link into the address bar."] or L["Press Cmd-C to copy, then Cmd-Tab out of the game, open your favorite web browser, and paste the link into the address bar."],
-		button2 = ACCEPT,
-		hasEditBox = 1,
-		hasWideEditBox = 1,
-		showAlert = 1, -- HACK : it's the only way I found to make de StaticPopup have sufficient width to show WideEditBox :(
-
-		OnShow = function()
-			local editBox = _G[this:GetName() .. "WideEditBox"]
-			editBox:SetText(url)
-			editBox:SetFocus()
-			editBox:HighlightText(0)
-			editBox:SetScript("OnTextChanged", function() StaticPopup_EditBoxOnTextChanged() end)
-
-			local button = _G[this:GetName() .. "Button2"]
-			button:ClearAllPoints()
-			button:SetWidth(200)
-			button:SetPoint("CENTER", editBox, "CENTER", 0, -30)
-
-			_G[this:GetName() .. "AlertIcon"]:Hide()  -- HACK : we hide the false AlertIcon
-			this:SetFrameStrata("FULLSCREEN_DIALOG")
-			bumpFrameLevels(this, 30)
-		end,
-		OnHide = function()
-			local editBox = _G[this:GetName() .. "WideEditBox"]
-			editBox:SetScript("OnTextChanged", nil)
-			this:SetFrameStrata("DIALOG")
-			bumpFrameLevels(this, -30)
-		end,
-		OnAccept = function() end,
-		OnCancel = function() end,
-		EditBoxOnEscapePressed = function() this:GetParent():Hide() end,
-		EditBoxOnTextChanged = function()
-			this:SetText(url)
-			this:SetFocus()
-			this:HighlightText(0)
-		end,
-		timeout = 0,
-		whileDead = 1,
-		hideOnEscape = 1
-	}
-end
-
-function OpenDonationFrame(self)
-	if makeURLFrame then
-		makeURLFrame()
-	end
-
-	local donate = self.donate
-	if type(donate) ~= "string" then
-		donate = "Wowace"
-	end
-	local style, data = (":"):split(donate, 2)
-	style = style:lower()
-	if style ~= "website" and style ~= "paypal" then
-		style = "wowace"
-	end
-	if style == "wowace" then
-		url = "http://www.wowace.com/wiki/Donations"
-	elseif style == "website" then
-		url = data
-	else -- PayPal
-		local text = "https://www.paypal.com/cgi-bin/webscr?cmd=_xclick&business=" .. urlencode(unobfuscateEmail(data))
-		local name
-		if type(self.title) == "string" then
-			name = self.title
-		elseif type(self.name) == "string" then
-			name = self.name
-		end
-		if name == MAJOR_VERSION then
-			name = "Rock"
-		end
-		if name then
-			name = name:gsub("|c%x%x%x%x%x%x%x%x", ""):gsub("|r", "")
-			text = text .. "&item_name=" .. urlencode(name)
-		end
-		url = text
-	end
-
-	StaticPopup_Show("ROCK_SHOW_URL")
-end
-function OpenIssueFrame(self)
-	if makeURLFrame then
-		makeURLFrame()
-	end
-
-	local issueTracker = self.issueTracker
-	if type(issueTracker) ~= "string" then
-		return
-	end
-	local style, data = (":"):split(issueTracker, 2)
-	style = style:lower()
-	if style ~= "website" and style ~= "wowace" then
-		return
-	end
-	if style == "wowace" then
-		url = "http://jira.wowace.com/secure/CreateIssue.jspa?pid=" .. data
-	elseif style == "website" then
-		url = data
-	end
-
-	StaticPopup_Show("ROCK_SHOW_URL")
-end
-local function donate_hidden(addon)
-	return type(addon.donate) ~= "string"
-end
-
-local function issue_hidden(addon)
-	return type(addon.issueTracker) ~= "string"
-end
-
--- #NODOC
-function Rock:GetRockConfigOptions(addon)
-	return 'active', {
-		type = 'boolean',
-		name = L["Enabled"],
-		desc = L["Enable or disable this addon."],
-		get = 'IsActive',
-		set = 'ToggleActive',
-		handler = addon,
-		order = -1,
-	}, 'donate', {
-		type = 'execute',
-		name = L["Give donation"],
-		buttonText = L["Donate"],
-		desc = L["Give a much-needed donation to the author of this addon."],
-		func = OpenDonationFrame,
-		hidden = donate_hidden,
-		passValue = addon,
-		order = -2,
-	}, 'issue', {
-		type = 'execute',
-		name = L["File issue"],
-		buttonText = L["Report"],
-		desc = L["File a bug or request a new feature or an improvement to this addon."],
-		func = OpenIssueFrame,
-		hidden = issue_hidden,
-		passValue = addon,
-		order = -3,
-	}
-end
-
-local function initAddon(addon, name)
-	name = addonToFolder[addon] or name or ""
-	-- TOC checks
-	if addon.title == nil then
-		addon.title = GetAddOnMetadata(name, "Title")
-	end
-	if type(addon.title) == "string" then
-		addon.title = addon.title:gsub("|c%x%x%x%x%x%x%x%x", ""):gsub("|r", ""):gsub("%-Rock%-$", ""):trim()
-	end
-	if addon.notes == nil then
-		addon.notes = GetAddOnMetadata(name, "Notes")
-	end
-	if type(addon.notes) == "string" then
-		addon.notes = addon.notes:trim()
-	end
-	if addon.version == nil then
-		addon.version = GetAddOnMetadata(name, "Version")
-	end
-	if type(addon.version) == "string" then
-		addon.version = addon.version:trim()
-	end
-	if addon.author == nil then
-		addon.author = GetAddOnMetadata(name, "Author")
-	end
-	if type(addon.author) == "string" then
-		addon.author = addon.author:trim()
-	end
-	if addon.credits == nil then
-		addon.credits = GetAddOnMetadata(name, "X-Credits")
-	end
-	if type(addon.credits) == "string" then
-		addon.credits = addon.credits:trim()
-	end
-	if addon.donate == nil then
-		addon.donate = GetAddOnMetadata(name, "X-Donate")
-	end
-	if type(addon.donate) == "string" then
-		addon.donate = addon.donate:trim()
-	end
-	if addon.issueTracker == nil then
-		addon.issueTracker = GetAddOnMetadata(name, "X-IssueTracker")
-	end
-	if type(addon.issueTracker) == "string" then
-		addon.issueTracker = addon.issueTracker:trim()
-	end
-	if addon.category == nil then
-		addon.category = GetAddOnMetadata(name, "X-Category")
-	end
-	if type(addon.category) == "string" then
-		addon.category = addon.category:trim()
-	end
-	if addon.email == nil then
-		addon.email = GetAddOnMetadata(name, "X-eMail") or GetAddOnMetadata(name, "X-Email")
-	end
-	if type(addon.email) == "string" then
-		addon.email = addon.email:trim()
-	end
-	if addon.license == nil then
-		addon.license = GetAddOnMetadata(name, "X-License")
-	end
-	if type(addon.license) == "string" then
-		addon.license = addon.license:trim()
-	end
-	if addon.website == nil then
-		addon.website = GetAddOnMetadata(name, "X-Website")
-	end
-	if type(addon.website) == "string" then
-		addon.website = addon.website:trim()
-	end
-
-	for mixin in Rock:IterateObjectMixins(addon) do
-		local mixin_OnEmbedInitialize = mixin.OnEmbedInitialize
-		if mixin_OnEmbedInitialize then
-			local success, ret = pcall(mixin_OnEmbedInitialize, mixin, addon)
-			if not success then
-				geterrorhandler()(ret)
-			end
-		end
-	end
-
-	local addon_OnInitialize = addon.OnInitialize
-	if addon_OnInitialize then
-		local success, ret = pcall(addon_OnInitialize, addon)
-		if not success then
-			geterrorhandler()(ret)
-		end
-	end
-
-	if LibRockEvent then
-		Rock:DispatchEvent("AddonInitialized", addon)
-	end
-end
-
-
-local function manualEnable(addon)
-	for i,v in ipairs(pendingAddons) do
-		if v == addon then
-			return
-		end
-	end
-	if currentlyEnabledAddons[addon] then
-		return false
-	end
-	currentlyEnabledAddons[addon] = true
-
-	local first = not addonsAlreadyEnabled[addon]
-	addonsAlreadyEnabled[addon] = true
-
-	for mixin in Rock:IterateObjectMixins(addon) do
-		local mixin_OnEmbedEnable = mixin.OnEmbedEnable
-		if mixin_OnEmbedEnable then
-			local success, ret = pcall(mixin_OnEmbedEnable, mixin, addon, first)
-			if not success then
-				geterrorhandler()(ret)
-			end
-		end
-	end
-	local addon_OnEnable = addon.OnEnable
-	if addon_OnEnable then
-		local success, ret = pcall(addon_OnEnable, addon, first)
-		if not success then
-			geterrorhandler()(ret)
-		end
-	end
-
-	if LibRockEvent then
-		Rock:DispatchEvent("AddonEnabled", addon, first)
-	end
-
-	return true, first
-end
-
-local function manualDisable(addon)
-	if not currentlyEnabledAddons[addon] then
-		return false
-	end
-	currentlyEnabledAddons[addon] = nil
-
-	for mixin in Rock:IterateObjectMixins(addon) do
-		local mixin_OnEmbedDisable = mixin.OnEmbedDisable
-		if mixin_OnEmbedDisable then
-			local success, ret = pcall(mixin_OnEmbedDisable, mixin, addon)
-			if not success then
-				geterrorhandler()(ret)
-			end
-		end
-	end
-	local addon_OnDisable = addon.OnDisable
-	if addon_OnDisable then
-		local success, ret = pcall(addon_OnDisable, addon)
-		if not success then
-			geterrorhandler()(ret)
-		end
-	end
-
-	if LibRockEvent then
-		Rock:DispatchEvent("AddonDisabled", addon)
-	end
-	return true
-end
-
-local function enableAddon(addon)
-	for i,v in ipairs(pendingAddons) do
-		if v == addon then
-			return
-		end
-	end
-	if addon_mt___index.IsActive(addon) then
-		manualEnable(addon)
-	end
-end
-
--- #NODOC
--- This is used by internal Rock libraries after updating the active state.
-function Rock:RecheckEnabledStates()
-	local changed = false
-	for _,addon in pairs(addons) do
-		local good = true
-		for _,a in ipairs(pendingAddonsEnable) do
-			if addon == a then
-				good = false
-				break
-			end
-		end
-		if good then
-			if addon_mt___index.IsActive(addon) then
-				if manualEnable(addon) then
-					changed = true
-				end
-			else
-				if manualDisable(addon) then
-					changed = true
-				end
-			end
-		end
-	end
-	if changed then
-		return self:RecheckEnabledStates()
-	end
-end
-
-frame:UnregisterAllEvents()
-frame:RegisterEvent("ADDON_LOADED")
-frame:RegisterEvent("PLAYER_LOGIN")
-local function runMainAddonLoadedChunk(name)
-	local tmp = newList()
-	tmp, pendingAddons = pendingAddons, tmp
-	for i, addon in ipairs(tmp) do
-		local folder = addonToFolder[addon]
-		if name and folder and not foldersLoaded[folder] then
-			for j = i, #tmp do
-				pendingAddons[#pendingAddons+1] = tmp[j]
-				tmp[j] = nil
-			end
-			break
-		end
-		initAddon(addon, name)
-	end
-
-	if IsLoggedIn() then
-		for i, addon in ipairs(tmp) do
-			for j, v in ipairs(pendingAddonsEnable) do
-				if v == addon then
-					table_remove(pendingAddonsEnable, i)
-					break
-				end
-			end
-			enableAddon(addon)
-		end
-		for i, addon in ipairs(pendingAddonsEnable) do
-			local good = true
-			for j, v in ipairs(pendingAddons) do
-				if v == addon then
-					good = false
-					break
-				end
-			end
-			if not good then
-				break
-			end
-			pendingAddonsEnable[i] = nil
-			enableAddon(addon)
-		end
-	end
-	tmp = del(tmp)
-	for library, addonName in pairs(pendingLibraries) do
-		if not name or foldersLoaded[addonName] then
-			local success, ret = pcall(error, ("Library %q not finalized before ADDON_LOADED."):format(better_tostring(library)), 3)
-			geterrorhandler()(ret)
-			Rock:FinalizeLibrary((library:GetLibraryVersion()))
-		end
-	end
-
-	if isStandalone then
-		local LibRock_1_0DB = _G.LibRock_1_0DB
-		if type(LibRock_1_0DB) ~= "table" then
-			LibRock_1_0DB = {}
-			_G.LibRock_1_0DB = LibRock_1_0DB
-		end
-		if type(LibRock_1_0DB.unitTests) ~= "table" then
-			LibRock_1_0DB.unitTests = {}
-		end
-		enableContracts = LibRock_1_0DB.contracts or false
-		unitTestDB = LibRock_1_0DB.unitTests
-		for namespace, data in pairs(unitTests) do
-			if not unitTestDB[namespace] then
-				if data then
-					del(data)
-					unitTests[namespace] = false
-				end
-			elseif data and (not name or data.addon == name) then
-				local stats = newList()
-				for i,v in ipairs(data) do
-					data[i] = nil
-
-					local libs = newList()
-					for k,v in pairs(libraries) do
-						libs[k] = v
-					end
-
-					local success, ret = pcall(v)
-					if not success then
-						geterrorhandler()(ret)
-						stats[i] = ret
-					else
-						stats[i] = false
-					end
-
-					for k in pairs(libraries) do
-						if not libs[k] then
-							__removeLibrary(k)
-						end
-					end
-					libs = del(libs)
-
-					local lastCount
-					repeat
-						lastCount = collectgarbage('count')
-						collectgarbage('collect')
-					until lastCount == collectgarbage('count')
-				end
-				del(data)
-				unitTests[namespace] = false
-				if #stats >= 1 then
-					local pass, fail = 0, 0
-					for i,v in ipairs(stats) do
-						if v then
-							fail = fail + 1
-						else
-							pass = pass + 1
-						end
-					end
-
-					local color
-					if fail == 0 then
-						_G.DEFAULT_CHAT_FRAME:AddMessage(("|cff00ff00%s: %d unit test(s) passed."):format(namespace, pass))
-					elseif pass > 0 then
-						_G.DEFAULT_CHAT_FRAME:AddMessage(("|cffff0000%s: %d unit test(s) passed, %d unit test(s) failed."):format(namespace, pass, fail))
-					else
-						_G.DEFAULT_CHAT_FRAME:AddMessage(("|cffff0000%s: %d unit test(s) failed."):format(namespace, fail))
-					end
-					for i,v in ipairs(stats) do
-						if v then
-							_G.DEFAULT_CHAT_FRAME:AddMessage(("|cffff0000%s|r"):format(tostring(v)))
-						end
-					end
-					if fail > 0 then
-						_G.DEFAULT_CHAT_FRAME:AddMessage("|cffff0000----------|r")
-					end
-				end
-				stats = del(stats)
-			end
-		end
-	end
-	if isStandalone and name == MAJOR_VERSION then
-		Rock("LibRockEvent-1.0", false, true) -- load if possible
-		Rock("LibRockConsole-1.0", false, true) -- load if possible - I like the default chat commands
-		Rock("LibRockComm-1.0", false, true) -- load if possible - has version checking and the like
-		Rock("LibRockConfig-1.0", false, true) -- load if possible - LibRock-1.0 registers with it.
-	end
-
-	for major, library in LibStub:IterateLibraries() do
-		manualFinalize(major, library)
-	end
-
-	if IsLoggedIn() then
-		collectgarbage('collect')
-	end
-end
-
-frame:Show()
-frame:SetScript("OnUpdate", function(this, elapsed)
-	-- capture all un-initialized addons.
-	runMainAddonLoadedChunk()
-	collectgarbage('collect')
-	this:SetScript("OnUpdate", run)
-end)
-frame:SetScript("OnEvent", function(this, event, ...)
-	if event == "ADDON_LOADED" then
-		-- this creates a new table and flushes the old in case someone LoDs an addon inside ADDON_LOADED.
-		local name = ...
-		foldersLoaded[name] = true
-		runMainAddonLoadedChunk(name)
-		frame:Show()
-	elseif event == "PLAYER_LOGIN" then
-		for i, addon in ipairs(pendingAddonsEnable) do
-			local good = true
-			for _, a in ipairs(pendingAddons) do
-				if a == addon then
-					good = false
-					break
-				end
-			end
-			if good then
-				pendingAddonsEnable[i] = nil
-				enableAddon(addon)
-			end
-		end
-		collectgarbage('collect')
-	end
-end)
-
-Rock:SetExportedMethods("SetExportedMethods", "Embed", "Unembed", "GetLibraryVersion")
-
-Rock:FinalizeLibrary(MAJOR_VERSION)
-
-for major, library in LibStub:IterateLibraries() do
-	manualFinalize(major, library)
-end
-
-Rock:AddUnitTest(MAJOR_VERSION, function()
-	-- test recycling
-	local newList, newDict, newSet, del = Rock:GetRecyclingFunctions(MAJOR_VERSION .. "_UnitTest", "newList", "newDict", "newSet", "del", "Debug")
-	local t = newList("Alpha", "Bravo", "Charlie")
-	assert(t[1] == "Alpha")
-	assert(t[2] == "Bravo")
-	assert(t[3] == "Charlie")
-	t = del(t)
-	t = newList("Alpha", "Bravo", "Charlie")
-	-- check recycled table
-	assert(t[1] == "Alpha")
-	assert(t[2] == "Bravo")
-	assert(t[3] == "Charlie")
-	t = del(t)
-	t = newDict("Alpha", "Bravo", "Charlie", "Delta")
-	assert(t.Alpha == "Bravo")
-	assert(t.Charlie == "Delta")
-	t = del(t)
-	t = newSet("Alpha", "Bravo", "Charlie")
-	assert(t.Alpha)
-	assert(t.Bravo)
-	assert(t.Charlie)
-	t = del(t)
-
-	local debug = recycleData.debugPools[MAJOR_VERSION .. "_UnitTest"]
-	assert(debug.num == 0)
-	t = newList()
-	assert(debug.num == 1)
-	t[1] = newList()
-	assert(debug.num == 2)
-	t[2] = newList()
-	assert(debug.num == 3)
-	t[1] = del(t[1])
-	assert(debug.num == 2)
-	t[2] = del(t[2])
-	assert(debug.num == 1)
-	t = del(t)
-	assert(debug.num == 0)
-end)
-
-Rock:AddUnitTest(MAJOR_VERSION, function()
-	-- test :GetUID()
-	local t = {}
-	for i = 1, 10000 do
-		local uid = Rock:GetUID()
-		if t[i] then
-			error(("UID match for iteration %d, UID %s"):format(i, uid))
-		end
-		t[i] = true
-	end
-end)
-
-Rock:AddUnitTest(MAJOR_VERSION, function()
-	-- test basic creation and deletion
-	assert(not LibStub:GetLibrary("LibRockFakeLib-1.0", true))
-	assert(not Rock:HasLibrary("LibRockFakeLib-1.0"))
-	local lib = Rock:NewLibrary("LibRockFakeLib-1.0", 1)
-	Rock:FinalizeLibrary("LibRockFakeLib-1.0")
-	lib = nil
-	assert(LibStub:GetLibrary("LibRockFakeLib-1.0", true))
-	assert(Rock:HasLibrary("LibRockFakeLib-1.0"))
-	local good = false
-	for _, lib in pairs(libraries) do
-		if lib.name == "LibRockFakeLib-1.0" then
-			good = true
-			break
-		end
-	end
-	assert(good)
-	__removeLibrary("LibRockFakeLib-1.0")
-	for _, lib in pairs(libraries) do
-		assert(lib.name ~= "LibRockFakeLib-1.0")
-	end
-	assert(not LibStub:GetLibrary("LibRockFakeLib-1.0", true))
-	assert(not Rock:HasLibrary("LibRockFakeLib-1.0"))
-end)
-
-Rock:AddUnitTest(MAJOR_VERSION, function()
-	-- test library creation and the like
-	assert(not Rock:HasLibrary("LibRockFakeLib-1.0"))
-	for name in Rock:IterateLibraries() do
-		assert(name ~= "LibRockFakeLib-1.0")
-	end
-
-	local myLib, oldLib = Rock:NewLibrary("LibRockFakeLib-1.0", 1)
-	assert(myLib)
-	assert(myLib.name == "LibRockFakeLib-1.0")
-	assert(not oldLib)
-
-	assert(myLib:GetLibraryVersion() == "LibRockFakeLib-1.0")
-	assert(select(2, myLib:GetLibraryVersion()) == 1)
-
-	local good = false
-	for name in Rock:IterateLibraries() do
-		if name == "LibRockFakeLib-1.0" then
-			good = true
-			break
-		end
-	end
-	assert(good)
-	assert(Rock:HasLibrary("LibRockFakeLib-1.0"))
-	assert(Rock:GetLibrary("LibRockFakeLib-1.0") == myLib)
-	assert(Rock("LibRockFakeLib-1.0") == myLib)
-
-	assert(not Rock:IsLibraryMixin("LibRockFakeLib-1.0"))
-	function myLib:DoSomething()
-		return "Something"
-	end
-	myLib:SetExportedMethods("DoSomething")
-	assert(Rock:IsLibraryMixin("LibRockFakeLib-1.0"))
-	local t = {}
-	assert(not Rock:DoesObjectUseMixin(t, "LibRockFakeLib-1.0"))
-	assert(not t.DoSomething)
-	for mixin in Rock:IterateObjectMixins(t) do
-		assert(false)
-	end
-	for object in Rock:IterateMixinObjects("LibRockFakeLib-1.0") do
-		assert(false)
-	end
-	myLib:Embed(t)
-	assert(t:DoSomething() == "Something")
-	assert(Rock:DoesObjectUseMixin(t, "LibRockFakeLib-1.0"))
-	for mixin in Rock:IterateObjectMixins(t) do
-		assert(mixin == myLib)
-	end
-	for object in Rock:IterateMixinObjects("LibRockFakeLib-1.0") do
-		assert(object == t)
-	end
-
-	Rock:FinalizeLibrary("LibRockFakeLib-1.0")
-
-	local myNewLib, oldLib = Rock:NewLibrary("LibRockFakeLib-1.0", 2)
-	assert(myNewLib == myLib)
-	assert(oldLib)
-	assert(Rock:GetLibrary("LibRockFakeLib-1.0") == myLib)
-
-	function myLib:DoSomething()
-		return "Something else"
-	end
-	function myLib:TrySomething()
-		return "Blah"
-	end
-	myLib:SetExportedMethods("DoSomething", "TrySomething")
-	assert(Rock:IsLibraryMixin("LibRockFakeLib-1.0"))
-	assert(t:DoSomething() == "Something else")
-	assert(t:TrySomething() == "Blah")
-	assert(Rock:DoesObjectUseMixin(t, "LibRockFakeLib-1.0"))
-	for mixin in Rock:IterateObjectMixins(t) do
-		assert(mixin == myLib)
-	end
-	for object in Rock:IterateMixinObjects("LibRockFakeLib-1.0") do
-		assert(object == t)
-	end
-
-	Rock:FinalizeLibrary("LibRockFakeLib-1.0")
-
-	local myNewLib, oldLib = Rock:NewLibrary("LibRockFakeLib-1.0", 3)
-	assert(myNewLib == myLib)
-	assert(oldLib)
-	assert(Rock:GetLibrary("LibRockFakeLib-1.0") == myLib)
-
-	function myLib:DoSomething()
-		return "Something"
-	end
-	myLib:SetExportedMethods("DoSomething")
-	assert(Rock:IsLibraryMixin("LibRockFakeLib-1.0"))
-	assert(t:DoSomething() == "Something")
-	assert(t.TrySomething == nil)
-	assert(Rock:DoesObjectUseMixin(t, "LibRockFakeLib-1.0"))
-	for mixin in Rock:IterateObjectMixins(t) do
-		assert(mixin == myLib)
-	end
-	for object in Rock:IterateMixinObjects("LibRockFakeLib-1.0") do
-		assert(object == t)
-	end
-
-	Rock:FinalizeLibrary("LibRockFakeLib-1.0")
-
-	assert(not Rock:NewLibrary("LibRockFakeLib-1.0", 2)) -- out of date
-	assert(not Rock:NewLibrary("LibRockFakeLib-1.0", 3)) -- same revision
-end)
-
-Rock:AddUnitTest(MAJOR_VERSION, function()
-	assert(not Rock:HasAddon("RockFakeAddon"))
-	for name in Rock:IterateAddons() do
-		assert(name ~= "RockFakeAddon")
-	end
-
-	local myAddon = Rock:NewAddon("RockFakeAddon")
-
-	assert(myAddon)
-	assert(myAddon.name == "RockFakeAddon")
-
-	local good = false
-	for name in Rock:IterateAddons() do
-		if name == "RockFakeAddon" then
-			good = true
-			break
-		end
-	end
-	assert(good)
-	assert(Rock:HasAddon("RockFakeAddon"))
-	assert(Rock:GetAddon("RockFakeAddon") == myAddon)
-end)
-
-Rock:AddUnitTest(MAJOR_VERSION, function()
-	-- test :OnLibraryLoad
-	local lib = Rock:NewLibrary("LibRockFakeLib-1.0", 1)
-	local triggered = false
-	function lib:OnLibraryLoad(major, instance)
-		if major == "LibRockFakeLib-2.0" then
-			triggered = true
-		end
-	end
-	Rock:FinalizeLibrary("LibRockFakeLib-1.0")
-
-	local lib = Rock:NewLibrary("LibRockFakeLib-2.0", 1)
-	assert(not triggered)
-	Rock:FinalizeLibrary("LibRockFakeLib-2.0")
-	assert(triggered)
-	triggered = false
-	local lib = Rock:NewLibrary("LibRockFakeLib-2.0", 2)
-	assert(not triggered)
-	Rock:FinalizeLibrary("LibRockFakeLib-2.0")
-	assert(not triggered)
-end)
--- a/modules/FuBar_ReActionFu/lib/LibRock-1.0/LibRock-1.0.toc	Wed Apr 02 23:44:06 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,14 +0,0 @@
-## Interface: 20300
-
-## Title: LibRock-1.0
-## Notes: AddOn development framework
-## Author: ckknight
-## X-Website: http://www.wowace.com
-## X-Category: Library
-## X-Donate: Paypal:ckknight AT gmail DOT com
-## X-eMail: ckknight AT gmail DOT com
-## X-License: LGPL v2.1
-## SavedVariables: LibRock_1_0DB
-## OptionalDeps: !BugGrabber, !Swatter
-
-lib.xml
\ No newline at end of file
--- a/modules/FuBar_ReActionFu/lib/LibRock-1.0/LibStub/LibStub.lua	Wed Apr 02 23:44:06 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +0,0 @@
--- LibStub is a simple versioning stub meant for use in Libraries.  http://www.wowace.com/wiki/LibStub for more info
--- LibStub is hereby placed in the Public Domain Credits: Kaelten, Cladhaire, ckknight, Mikk, Ammo, Nevcairiel, joshborke
-local LIBSTUB_MAJOR, LIBSTUB_MINOR = "LibStub", 2  -- NEVER MAKE THIS AN SVN REVISION! IT NEEDS TO BE USABLE IN ALL REPOS!
-local LibStub = _G[LIBSTUB_MAJOR]
-
-if not LibStub or LibStub.minor < LIBSTUB_MINOR then
-	LibStub = LibStub or {libs = {}, minors = {} }
-	_G[LIBSTUB_MAJOR] = LibStub
-	LibStub.minor = LIBSTUB_MINOR
-	
-	function LibStub:NewLibrary(major, minor)
-		assert(type(major) == "string", "Bad argument #2 to `NewLibrary' (string expected)")
-		minor = assert(tonumber(strmatch(minor, "%d+")), "Minor version must either be a number or contain a number.")
-		
-		local oldminor = self.minors[major]
-		if oldminor and oldminor >= minor then return nil end
-		self.minors[major], self.libs[major] = minor, self.libs[major] or {}
-		return self.libs[major], oldminor
-	end
-	
-	function LibStub:GetLibrary(major, silent)
-		if not self.libs[major] and not silent then
-			error(("Cannot find a library instance of %q."):format(tostring(major)), 2)
-		end
-		return self.libs[major], self.minors[major]
-	end
-	
-	function LibStub:IterateLibraries() return pairs(self.libs) end
-	setmetatable(LibStub, { __call = LibStub.GetLibrary })
-end
--- a/modules/FuBar_ReActionFu/lib/LibRock-1.0/lib.xml	Wed Apr 02 23:44:06 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
-..\FrameXML\UI.xsd">
-	<Script file="LibStub\LibStub.lua" />
-	<Script file="LibRock-1.0.lua" />
-</Ui>
\ No newline at end of file
--- a/modules/FuBar_ReActionFu/lib/embeds.xml	Wed Apr 02 23:44:06 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,12 +0,0 @@
-<Ui xmlns="http://www.blizzard.com/wow/ui/" 
-    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
-    xsi:schemaLocation="http://www.blizzard.com/wow/ui/..\FrameXML\UI.xsd">
-
-  <Include file="LibRock-1.0\lib.xml"/>
-  <Include file="LibFuBarPlugin-3.0\lib.xml"/>
-
-  <Script file="AceLibrary\AceLibrary.lua"/>
-  <Script file="Dewdrop-2.0\Dewdrop-2.0.lua"/>
-  <Script file="Tablet-2.0\Tablet-2.0.lua"/>
-
-</Ui>
--- a/modules/modules.xml	Wed Apr 02 23:44:06 2008 +0000
+++ b/modules/modules.xml	Thu Apr 03 16:59:16 2008 +0000
@@ -9,13 +9,6 @@
 <!-- action button modules -->
 <Include file="ReAction_Action\ReAction_Action.xml"/>
 
-
-
-<!-- deprecated
-<Include file="FuBar_ReActionFu\FuBar_ReActionFu.xml"/>
--->
-
-
 <!-- in progress
 <Include file="ReAction_PetAction\ReAction_PetAction.xml"/>
 -->